package es.ejie.frmk.presentacion.iu.taglib.html.menu.displayer;

import java.io.IOException;
import java.net.MalformedURLException;
import java.text.MessageFormat;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;

import org.apache.commons.lang.StringUtils;
import org.apache.struts.util.RequestUtils;

import es.ejie.frmk.control.excepciones.Q70FrameworkException;
import es.ejie.frmk.infraestructura.traza.Q70TraceLevel;
import es.ejie.frmk.infraestructura.traza.Q70Traza;
import es.ejie.frmk.presentacion.iu.taglib.base.Q70Constants;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.base.Q70MenuComponent;


public class Q70DHTMLSlideMenuDisplayer extends Q70MessageResourcesMenuDisplayer {

	private static Q70Traza tr = Q70Traza.getSingleton();
	
    private static MessageFormat menuMessage =
        new MessageFormat(
            "slideMenu.makeMenu(''{0}'',''{1}'',''{2}'',''{3}'',''{4}'',''{5}'');");
    private static final String TAB = "    "; // four spaces
    private static final String SCRIPT_START =
        "\n<script type=\"text/javascript\">\n<!--";
    private static final String SCRIPT_END = "//-->\n</script>\n";
    private static final String END_STATEMENT = TAB + " slideMenu.init();\n";
    
    private static final String DEFAULT_JAVASCRIPTFILES ="dhtmlslidemenu.js,dhtmlslidemenu-config.js";

    protected String getJavaScriptsFilesDefault() {
    	return DEFAULT_JAVASCRIPTFILES;
    }
    
    /**
     * @param context
     * @param mapping
     * @throws JspException
     */
    public void init(PageContext context, Q70MenuDisplayerMapping mapping) throws JspException
    {
        super.init(context, mapping);
        
        try {
        	out.println(SCRIPT_START);
        } 
        catch (Exception e) 
        {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Q70DHTMLSlideMenuDisplayer: Throwable recogida en metodo init():" + e.getMessage());
			}           	
        }
    }

    /**
     * Prints the appropriate javascript for CoolMenu using \
     * <code>menuMessage</code> as the format.
     */
    public void display(Q70MenuComponent menu,PageContext pageContext) throws JspException, IOException 
    {		    	
    	this.pageContext=pageContext;
		super.setSecureId(menu.getSecureId());
		boolean allowed =(Q70Constants.MODE_NOTDISPLAYED!=super.getDisplayMode()?true:false);
    	
		StringBuffer sb = new StringBuffer();
        buildMenuString(menu, sb, allowed,pageContext,0);
        out.print("\n" + TAB + sb);
    }

    /**
     * This will output the ending javascript statements defined in
     * <code>END_STATEMENT</code> and <code>SCRIPT_END</code>
     */
    public void end(PageContext context) 
    {
        try 
        {
            out.print(END_STATEMENT);
            out.print(SCRIPT_END);
        } 
        catch (Exception e) 
        {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Q70DHTMLSlideMenuDisplayer: Throwable recogida en metodo end():" + e.getMessage());
			}           	
        }
    }
    
    /**
     * Metodo recursivo que displaya el arbol de menus y submenus.
     * @param menu
     * @param sb
     * @param allowed
     * @param pageContext
     * @throws JspException
     */
    protected void buildMenuString(Q70MenuComponent menu, StringBuffer sb, boolean allowed,PageContext pageContext,int level) throws JspException 
    {
        if (allowed) {
        	super.displayComponents(menu,pageContext);
            try{
        		setPageLocation(menu);
        	}catch (MalformedURLException m)
        	 {	                    
    			if (tr.isTraceActive())	{
    				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Action o forward incorrecto: " + m.getMessage());
    				tr.trace(COMPONENTE, Q70TraceLevel.DEBUG, "Estableciendo location a #");
    			} 																			                    
                menu.setLocation("#");
            }	
        	
            sb.append(menuMessage.format(getArgs(menu,level)) + "\n" + TAB + TAB);
            Q70MenuComponent[] subMenus;
			try {
				subMenus = menu.getMenuComponents();
			} catch (Q70FrameworkException e) {
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Error en la obtención de los menus. Q70DHMTLSlideMenuDisplayer");
				}
				RequestUtils.saveException(pageContext, e);
				throw new JspException("Error en la obtención de los menus. Q70DHTMLSlideMenuDisplayer",e);
			}

            if (subMenus.length > 0) 
            {
            	level++;
                for (int i = 0; i < subMenus.length; i++) 
                {
					subMenus[i].setI18nKey(menu.getI18nKey());                	
					super.setSecureId(subMenus[i].getSecureId());
					subMenus[i].setPageContext(pageContext);
					subMenus[i].setListaI18nKey(this.getListaI18nKey());
					
					boolean subMenuAllowed =(Q70Constants.MODE_NOTDISPLAYED!=super.getDisplayMode()?true:false);
 					buildMenuString(subMenus[i], sb, subMenuAllowed,pageContext,level);
                }
            }
        }
    }

    /**
     * @param menu
     * @param allowed
     * @return
     * @throws JspException
     */
    protected String[] getArgs(Q70MenuComponent menu,int level) throws JspException{
    	String[] args = new String[6];
	        
    	//makeMenu('TYPE','TEXT','LINK','TARGET', 'NAME TITLE','END (THE LAST MENU)')
    	//There are 3 different types of menus you can make
    	//top = Main menus
    	//sub = Sub menus
    	//sub2 = SubSub menus
    	
    	args[1]=(menu.getImage() != null) ? (getConfigMessage("cm.image", menu.getImage()) + " " + 
    			getMessage(menu.getListaI18nKey(), menu.getTitle())):getMessage(menu.getListaI18nKey(), menu.getTitle());
    	args[4]=args[1];
    	args[1]=StringUtils.abbreviate(args[1],18);
        args[2]=(menu.getUrl() == null) ? EMPTY : menu.getUrl();
        args[0]=obtenerTipo(level);
        args[2] = StringUtils.replace(args[2], "\"", "\\\"");
        args[3]=EMPTY;
        args[5]=EMPTY;
        
        return args;
    }
    
    private String obtenerTipo(int level){
    	String cadena=null;
    	
    	switch(level){
    		case 0: cadena="top";
    				break;
    		case 1: cadena="sub";
    				break;
    		default: cadena="sub"+level;
    	}
    	return cadena;
    }

    /**
     * @param menu
     * @return String 
     */
    protected String getParentName(Q70MenuComponent menu) {
        String name = null;

        if (menu.getParentMenu() == null) {
            name = "";
        } else {
            name = menu.getParentMenu().getName();
        }

        return name;
    }
    
    /**
     * @param menu
     * @return String 
     */
    protected String getTarget(Q70MenuComponent menu) {
        String theTarget = super.getTarget(menu);

        if (target == null) {
            theTarget = EMPTY;
        }

        return theTarget;
    }
}
