/*
 * Q70SlideMenuDisplayer.java
 *
 * Created on December 7, 2002, 12:22 AM
 * @author  <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 */
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;



/**
 *Variables for each menu item: (** means that they have to be specified!)
 * 0 name: The name of the item. This must be unique for each item. Do not use spaces or strange characters in this one! **
 * 1 parent_name: The name of the menuitem you want this to "connect" to. This will be a submenu of the item that have the name you place in here. ** for all other then the topitems
 * 2 text: The text you want in the item. ** (except if you use images)
 * 3 link: The page you want this item to link to.
 * 4 target: The target window or frame you want the link to go to (Default is same window if you're not using frames, and the mainframe if you're using frames)
 * width: The width of the element. If not specified it will get the default width specified above.
 * height: The height of the element. If not specified it will get the default height specified above.
 * 5 img1: The "off" image for element if you want to use images.
 * 6 img2: The image that appears onmouseover if using images.
 * 7 regClass: The CSS class for a cell when it's not selected.
 * 8 overClass: The CSS class for a cell when it's moused over.
 * align: The alignment for this item.
 * rows: The number of rows for this item to expand.
 * 9 nolink:  If you have items that are meant to be info items only or something like that you can set this value to 1 and the item will not get a hand cursor and/or a link (the events will not work either)
 *10 onclick: If you want something to happen when the element is clicked (different from going to a link) spesifiy it here.
 *11 onmouseover: This will happen when you mouseover the element. Could be status text, another imageswap or whatever.
 *12 onmouseout: This will happen when you mouseout the element.
 * Remember you can have as many levels/sublevels as you want. Just make sure you spesify the correct "parent" for each item.
 * To set styles for each level see above.
 * @version 1.0  Fecha: 7-Dic-2002
 */
public class Q70SlideMenuDisplayer extends Q70MessageResourcesMenuDisplayer 
{
	private static Q70Traza tr = Q70Traza.getSingleton();

	// main message format of the menu.  only 10 args max in jdk1.3 :( */
    // the zero (0) below before the number 5 is for the nolink attribute, since I'm 
    // hiding menus when they're not allowed, this is always 0.
    private static MessageFormat menuMessage =
        new MessageFormat(
            "oCMenu.makeMenu(''{0}'',''{1}'',''{2}'',''{3}'',''{4}'',''{5}'',''''," +
            "'''','''','''','''','''','''',0,''{6}'',''{7}'',''{8}'');");
    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 + "oCMenu.construct();\n";
    
    private static final String DEFAULT_JAVASCRIPTFILES ="slidemenus.js,slidemenu-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.print(SCRIPT_START);
        } 
        catch (Exception e) 
        {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Q70SlideMenuDisplayer: 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);
        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, "Q70SlideMenuDisplayer: 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) 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)) + "\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. Q70SlideMenuDisplayer");
				}
				RequestUtils.saveException(pageContext, e);
				throw new JspException("Error en la obtención de los menus. Q70SlideMenuDisplayer",e);
			}

            if (subMenus.length > 0) 
            {
                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);
                }
            }
        }
    }

    /**
     * @param menu
     * @param allowed
     * @return
     * @throws JspException
     */
    protected String[] getArgs(Q70MenuComponent menu) throws JspException{
        String[] args = new String[9];
        args[0] = menu.getName();
        args[1] = getParentName(menu);

        args[2] =
            (menu.getImage() != null)
            ? (getConfigMessage("cm.image", menu.getImage()) + " " + getMessage(menu.getListaI18nKey(), menu.getTitle())) 
            : getMessage(menu.getListaI18nKey(), menu.getTitle());	
			
        args[3] = (menu.getUrl() == null) ? EMPTY : menu.getUrl();
        args[4] = getTarget(menu);
        args[5] = (menu.getWidth() == null) ? EMPTY : menu.getWidth();
        args[6] = (menu.getOnclick() == null) ? EMPTY : menu.getOnclick();
        args[7] =
            (menu.getOnmouseover() == null) ? EMPTY : menu.getOnmouseover();
        args[8] = (menu.getOnmouseout() == null) ? EMPTY : menu.getOnmouseout();

        // fix image HTML to escape double quotes for JavaScript
        args[2] = StringUtils.replace(args[2], "\"", "\\\"");

        return args;
    }

    /**
     * @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;
    }
}
