/*
 * DisplayDropDownMenuTag.java
 *
 * Created on February 13, 2001, 4:51 PM
 */
package es.ejie.frmk.presentacion.iu.taglib.html.menu;

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

import org.apache.struts.util.RequestUtils;

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.Q70BaseHandlerTag;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.base.Q70MenuRepository;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.displayer.Q70MenuDisplayer;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.displayer.Q70MenuDisplayerMapping;
import es.ejie.frmk.presentacion.iu.taglib.html.menu.displayer.Q70MessageResourcesMenuDisplayer;




/**
 *
 * @author  ssayles, mraible
 * @version
 */
public class Q70UseMenuDisplayerTag extends Q70BaseHandlerTag 
{
    //~ Static fields/initializers =============================================

    public static final String DISPLAYER_KEY =
            "es.ejie.frmk.presentacion.iu.taglib.html.menu.DISPLAYER";

    //used by the menu displayer tag to get the menu repository
    //it is possible that the user may have multiple repositories
    // although it's unlikely
    public static final String MENU_TYPES_REPOSITORY_KEY =
            "es.ejie.frmk.presentacion.iu.taglib.html.menu.MENU_TYPES_REPOSITORY";
    
    protected String name;
	protected Q70MenuDisplayer menuDisplayer = null;


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


	/**
	 * Modo de display del tag
	 */
	private int displayMode = Q70Constants.MODE_READWRITE;

   
    //~ Methods ================================================================

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
 
    public int doStartTag() throws JspException 
    {
    	int result = 1; //(EVAL_BODY_INCLUDE);

		displayMode = super.getDisplayMode();
		if (displayMode != Q70Constants.MODE_NOTDISPLAYED) 
		{	    													
			//Obtener el repositorio de tipos de menu
			Q70MenuRepository menuRep = getMenuRepository();															
	
	        //get the displayer mapping
	        Q70MenuDisplayerMapping displayerMapping = menuRep.getMenuDisplayerMapping(this.name);
	
	        if (displayerMapping == null) {
				JspException e =
					new JspException("Q70UseMenuDisplayerTag: No existe el mapping para el menu especificado en el MenuDisplayer.");
				RequestUtils.saveException(pageContext, e);
				throw e;				
	        }
	
	        //get an instance of the menu displayer
	        try {
	        	menuDisplayer =
	                    (Q70MenuDisplayer) Class.forName(displayerMapping.getType())
	                    .newInstance();

	        } catch (Exception e) {
				if (tr.isTraceActive())
				{
					tr.trace(COMPONENTE, Q70TraceLevel.ERROR, e.getMessage());
				}
				RequestUtils.saveException(pageContext, e);
	            throw new JspException("Q70UseMenuDisplayerTag: No ha sido posible crear una nueva instancia del displayer",e);
	        }
	
			if (menuDisplayer instanceof Q70MessageResourcesMenuDisplayer) 
			{				
				Q70MessageResourcesMenuDisplayer mrDisplayerInstance =
						(Q70MessageResourcesMenuDisplayer) menuDisplayer;

				mrDisplayerInstance.setListaI18nKey(getListaI18nKey());
				
				//	Pasar las propiedades recogidas por el custom tag a la nueva instancia de menu
				String localI18nKey = super.getI18nKey(); 
				if ( localI18nKey != null) {
					mrDisplayerInstance.setI18nKey(localI18nKey);
					pageContext.setAttribute(Q70Constants.USE_MENU_DISPLAYER_I18N_KEY, localI18nKey, PageContext.REQUEST_SCOPE);
				}
						
				String localSecureId = super.getSecureId(); 		
				if ( localSecureId != null){
					mrDisplayerInstance.setSecureId(localSecureId);
				}
				
				mrDisplayerInstance.setJavaScriptFiles(super.getJavaScriptFiles());	
			}

			menuDisplayer.init(pageContext, displayerMapping);
	
	        //Guardar en el contexto de pagina el repositorio de tipos de menu 
	        pageContext.setAttribute(DISPLAYER_KEY, menuDisplayer, PageContext.REQUEST_SCOPE);
	        pageContext.setAttribute(MENU_TYPES_REPOSITORY_KEY, menuRep, PageContext.REQUEST_SCOPE);
		}
		else
		{
			result = 0; //SKIP_BODY
		}

        return result;
    }

    public int doEndTag() throws JspException 
    {
		if (displayMode != Q70Constants.MODE_NOTDISPLAYED) 
		{    	
	        menuDisplayer.end(pageContext);
	        pageContext.removeAttribute(DISPLAYER_KEY, PageContext.REQUEST_SCOPE);
	        pageContext.removeAttribute(Q70Constants.USE_MENU_DISPLAYER_I18N_KEY, PageContext.REQUEST_SCOPE);
	        //pageContext.removeAttribute(MENU_REPOSITORY_KEY);
	       
	        // Might have to apply fix for
	        // http://nagoya.apache.org/bugzilla/show_bug.cgi?id=16001
	        // release(); // don't seem to need it at this point...
		}
		
        return 6; //EVAL_PAGE
    }

    public void release() {

		if (tr.isTraceActive())	
			tr.trace(COMPONENTE, Q70TraceLevel.INFO, "UseMenuDisplayTag: comenzando a ejecutar el metodo release() ");

        super.release();
        this.menuDisplayer = null;
        this.name = null;
        this.menuDisplayer = null;

        //this.repository = Q70MenuRepository.MENU_REPOSITORY_KEY;
    }
    
    
    /**
	 * Metodo para localizar el repositorio de tiops de menu.
	 * Primero lo busca en el contexto de pagina, por si algun menu anteriormente lo ha depositado.
	 * Si no existe, se busca a nivel de aplicacion y de operacion de presentacion. 
	 * Si tampoco existe, se lanza una excepcion.
	 **/    
    private Q70MenuRepository getMenuRepository() 
    	throws JspException
    {
    	
		Q70MenuRepository menuRep = (Q70MenuRepository) pageContext.getAttribute(MENU_TYPES_REPOSITORY_KEY, PageContext.REQUEST_SCOPE);
			
		if (menuRep == null) 
		{			
			//Obtener el nombre de la operacion de presentacion (o modulo).  
			String moduleName = RequestUtils.getModuleName((HttpServletRequest)pageContext.getRequest(),
															pageContext.getSession().getServletContext());
			
			//Buscar el repositorio de menus a nivel de operacion de presentacion
			menuRep = (Q70MenuRepository) pageContext.getServletContext().
											getAttribute(Q70MenuRepository.MENU_REPOSITORY_KEY + moduleName);
			
			if (null==menuRep) {
				JspException e =
					new JspException("Q70UseMenuDisplayerTag: No ha sido posible encontrar el repositorio de menus");
				RequestUtils.saveException(pageContext, e);
				throw e;				
			}
			if (tr.isTraceActive()) {
				tr.trace(COMPONENTE, Q70TraceLevel.INFO, "Obtenido Repositorio de tipos de menu del contexto de servlet.");
			} 	
		}
		else
		{
			if (tr.isTraceActive()) {
				tr.trace(COMPONENTE, Q70TraceLevel.INFO, "Encontrado Repositorio de tipos de menu a nivel de pagina.");
			} 				
		}


		return menuRep;
		    	
    }
    
    
    
}
