/*
 * Q70ListMenuDisplayer.java
 *
 * Created on December 7, 2002, 12:35 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.util.HashMap;
import java.util.Map;

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;




/**
 * Clase que displaya en web todo un arbol de menu (submenus) en modo lista 
 * @version 1.0  Fecha: 7-dic-2002
 */
public class Q70ListMenuDisplayer extends Q70MessageResourcesMenuDisplayer 
{


    // Is this class thread safe?  I'm doubting it - therefore, this
    // probably shouldn't be here
    private Map jsMap;

    //Instancia del log de trazas
	private static Q70Traza tr = Q70Traza.getSingleton();

	 /**
     * @param context
     * @param mapping
     * @throws JspException
     */
    public void init(PageContext pageContext, Q70MenuDisplayerMapping mapping)
    	 throws JspException
   	{
        super.init(pageContext, mapping);
        jsMap = new HashMap();

        try 
        {
            out.println(getConfigMessage("lmd.begin"));
        } 
        catch (Exception e) 
        {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Q70ListMenuDisplayer: Throwable recogida en metodo init():" + e.getMessage());
			}         	
        }
    }

    /**
     * Prints the appropriate javascript for CoolMenu using \
     * <code>menuMessage</code> as the format.
     * @param menu
     * @param pageContext
     */
    public void display(Q70MenuComponent menu,PageContext pageContext) throws JspException, IOException 
    {
    	this.pageContext=pageContext;
		super.setSecureId(menu.getSecureId());
		if (Q70Constants.MODE_NOTDISPLAYED != super.getDisplayMode())
		{
            out.println(getConfigMessage("lmd.menu.top"));
            displayComponents(menu, 0,pageContext);
            out.println(getConfigMessage("lmd.menu.bottom"));
        }
    }

    /**
     * Metodo recursivo que displaya el arbol de menus y submenus.
     * @param menu
     * @param level
     * @param pageContext
     * @throws JspException
     * @throws IOException
     */
    protected void displayComponents(Q70MenuComponent menu, int level,PageContext pageContext)
    	throws JspException, IOException 
    {
		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("#");
        }	
        Q70MenuComponent[] components;
		try {
			components = menu.getMenuComponents();
		} catch (Q70FrameworkException e) {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Error en la obtención de los menus. Q70ListMenuDisplayer");
			}
			RequestUtils.saveException(pageContext, e);
			throw new JspException("Error en la obtención de los menus. Q70ListMenuDisplayer",e);
		}

        if (components.length > 0) {
            // eliminate spaces in string used for Id
            String domId =
                StringUtils.deleteWhitespace(getMessage(menu.getListaI18nKey(),menu.getTitle()));

            // check to see if this name has already been used
            if (jsMap.containsKey(domId + "Menu")) {
                domId = domId + Math.round((Math.random() * 100)); // use a random number for uniqueness
            }

            String menuClass = "menu";

            if (level >= 1) {
                menuClass = "submenu";
            }

            out.println(getConfigMessage("lmd.menu.actuator.top",
                                         domId,
                                         getMessage(menu.getListaI18nKey(), menu.getTitle()),
                                         menuClass) );

            jsMap.put(domId + "Menu", domId + "Actuator");

            for (int i = 0; i < components.length; i++) 
            {				            	
                // check the permissions on this component
				components[i].setI18nKey(menu.getI18nKey());
				super.setSecureId(components[i].getSecureId());
				if (Q70Constants.MODE_NOTDISPLAYED != super.getDisplayMode())
				{ 
                    try {
						if (components[i].getMenuComponents().length > 0) 
						{
						    out.println("<li>");
						    
						    displayComponents(components[i], level + 1,pageContext);
						    
						    out.println(getConfigMessage("lmd.menu.actuator.bottom"));

						    if (i == (components[i].getMenuComponents().length - 1)) 
						    { // last one
						        out.println("</li>");
						    }
						} 
						else 
						{
							printComponent("lmd.menu.item", components[i]);
						}
					} catch (Q70FrameworkException e) {
						if (tr.isTraceActive())
						{
							tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Error en la obtención de los menus. Q70ListMenuDisplayer");
						}
						RequestUtils.saveException(pageContext, e);
						throw new JspException("Error en la obtención de los menus. Q70ListMenuDisplayer",e);
					}
                }
            }
            // close the </ul> for the top menu
            if (menuClass.equals("menu")) 
            {
                out.println("</ul>");
            }
        } 
        else 
        {
            if (menu.getParent() == null) 
            {
				printComponent("lmd.menu.standalone", menu);
            } 
            else 
            {
				printComponent("lmd.menu.item", menu);
            }
        }
    }

    /**
     * This will output the ending HTML code to close tags from the beginning
     * @param context the current pageContext
     */
    public void end(PageContext context) {
        try {
            out.print(getConfigMessage("lmd.end"));
        } 
        catch (Exception e) 
        {
			if (tr.isTraceActive())
			{
				tr.trace(COMPONENTE, Q70TraceLevel.ERROR, "Q70ListMenuDisplayer: Throwable recogida en metodo end():" + e.getMessage());
			}          	
        }
    }
    
	//------------------------------------------------------------------------------------ Private methods
    
	/**
	 * Manda al navegador el codigo para pintar el componente (solo si seguridad lo permite).
	 * @param key: clave del recurso de internacionalizacion
	 * @param menu: objeto menu 
	 * @param level: nivel de profuncidad del menu
	 * @throws JspException
	 */    
	private void printComponent(String key, Q70MenuComponent menu)
		throws JspException, IOException 
	{
		super.setSecureId(menu.getSecureId());
		menu.setPageContext(pageContext);
		menu.setListaI18nKey(getListaI18nKey());
		setPageLocation(menu);
		if (Q70Constants.MODE_NOTDISPLAYED != super.getDisplayMode())
		{ 		        	
			out.println(getConfigMessage(key,
										 menu.getUrl(),
										 super.getMenuToolTip(menu),
										 getMessage(menu.getListaI18nKey(), menu.getTitle())));
		}
	}    
}
