/**
 * Licensed under the MICE s.r.l.
 * End User License Agreement
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.micegroup.it/voila/license.html
 */
package it.mice.voila.runtime.springmvc.taglibs;

import it.mice.voila.runtime.springmvc.bean.PageStatus;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

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

import org.springframework.web.servlet.tags.form.AbstractHtmlElementTag;
import org.springframework.web.servlet.tags.form.TagWriter;

/**
 * @author zzy9v4p
 *         <p/>
 *         To change this generated comment edit the template variable "typecomment":
 *         Window>Preferences>Java>Templates.
 *         To enable and disable the creation of type comments go to
 *         Window>Preferences>Java>Code Generation.
 */
public class PopupTag extends AbstractHtmlElementTag {
	private TagWriter tagWriter;

    private List paramValue = new ArrayList(1);

    private List retValue = new ArrayList(1);

    private String url = null;

    private String title = null;

    //private String src = null;

    private String width = null;

    private String height = null;

    private String popupType = "submit";

    private String preCall = null;
    private String postCall = null;
    private String postFill = null;

    private String value = null;

    private boolean useDomName = false;

	private String renderIfPageStatusIs = null;
	private String renderIfPageStatusIsNot = null;
	private String forceEdit = null;

    /**
     * Generate the required input tag.
     * <p/>
     * Support for indexed property since Struts 1.1
     *
     * @throws JspException if a JSP exception has occurred
     */
	@Override
	protected int writeTagContent(TagWriter tagWriter) throws JspException {
		this.tagWriter = tagWriter;
		
		PageStatus pageStatus = TagUtils.getPageStatus(getNestedPath());
		if (pageStatus != null) {
			if (pageStatus.isReadOnly()) {
				if (!evaluateBoolean("forceEdit", getForceEdit())) {
	                pageContext.getRequest().setAttribute("skipElement", Boolean.TRUE);
                    return (SKIP_BODY);
				}
			}
			String r1 = (String)evaluate("renderIfPageStatusIs", renderIfPageStatusIs);
			String r2 = (String)evaluate("renderIfPageStatusIsNot", renderIfPageStatusIsNot);
            if (r1 != null && !pageStatus.equals(r1)) {
                pageContext.getRequest().setAttribute("skipElement", Boolean.TRUE);
                return (SKIP_BODY);
            } else if (r2 != null && pageStatus.equals(r2)) {
                pageContext.getRequest().setAttribute("skipElement", Boolean.TRUE);
                return (SKIP_BODY);
            }
		}
        paramValue = new ArrayList<PopupParamTag>(1);
        retValue = new ArrayList<PopupReturnTag>(1);
        return (EVAL_BODY_INCLUDE);
	}

    /**
     * Process the end of this tag.
     * [Indexed property since Struts 1.1]
     *
     * @throws JspException if a JSP exception has occurred
     */
    public int doEndTag() throws JspException {
    	//String elementFunction = "document.getElementById";
        if (pageContext.getRequest().getAttribute("skipElement") != null) {
            pageContext.getRequest().removeAttribute("skipElement");
            return (EVAL_PAGE);
        }
        HttpServletResponse response = (HttpServletResponse) pageContext.getResponse();
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();

        StringBuffer internalOnClick = new StringBuffer("var chooseStruct = {caller: this, ");
        StringBuffer internalHref = new StringBuffer("popup.title=");

        setTitle(TagUtils.getMessage(getRequestContext(), evaluate("title", getTitle())));
        internalOnClick.append("title: '").append(getTitle()).append("',");
        internalHref.append(getTitle());
        String append = "?";
        if (getUrl().indexOf("?") > -1) {
        	append = "&amp;";
        }
        internalOnClick.append("url: '").append(request.getContextPath()).append("/").append(getUrl()).append(append).append("popup.jscript=true',");
        internalHref.append("&amp;popup.url=").append("/").append(getUrl());

        internalOnClick.append("parameter: ");

        Iterator<PopupParamTag> i = getParamValue().iterator();
        String separator = "";
        while (i.hasNext()) {
            PopupParamTag param = i.next();
            if (param.getConstant() == null) {
                internalOnClick.append(separator).append("'").append(param.getParamName()).append("='+ getFieldValue('").append(param.getPropertyId()).append("', true) ");
                internalHref.append("&amp;popup.i.parm=").append(param.getParamName()).append("&amp;popup.i.parm.").append(param.getParamName()).append("=").append(param.getProperty());
            } else {
                internalOnClick.append(separator).append("'").append(param.getParamName()).append("=").append(param.getConstant()).append("'");
            }

            separator = "+ '&amp;' +";
        }

        //Aggiunge l'elenco dei returnParameter names allo struct.parameter in modo che vengano trasmessi al server.
        separator = "";
        internalOnClick.append(" + '&amp;popupReturnParameters=");
        Iterator<PopupReturnTag> i2 = getRetValue().iterator();
        while (i2.hasNext()) {
            PopupReturnTag ret = i2.next();
            internalOnClick.append(separator).append(ret.getParamName());
            separator = ",";
        }
        internalOnClick.append("'");
        //////////////////////

        //Aggiunge l'elenco dei paramParameter names dove non occorre attivare il clearFilter.
        separator = "";
        internalOnClick.append(" + '&amp;popupNoClearFilterParameters=");
        internalHref.append("&amp;popupNoClearFilterParameters=");
        i = getParamValue().iterator();
        while (i.hasNext()) {
            PopupParamTag param = i.next();
            if (!param.isClearFilter()) {
                internalOnClick.append(separator).append(param.getParamName());
                internalHref.append(separator).append(param.getParamName());
                separator = ",";
            }
        }
        internalOnClick.append("'");
        //////////////////////
        
        i = getParamValue().iterator();
        while (i.hasNext()) {
            PopupParamTag parm = i.next();
            internalOnClick.append(", ").append(parm.getParamName().replaceAll("\\.", "\\_").replaceAll("\\[", "\\_").replaceAll("\\]", "")).append(": getFieldValue('").append(parm.getPropertyId()).append("', true)");
        }

        i2 = getRetValue().iterator();
        while (i2.hasNext()) {
            PopupReturnTag ret = i2.next();
            internalHref.append("&amp;popup.o.parm=").append(ret.getParamName()).append("&amp;popup.o.parm.").append(ret.getParamName()).append("=").append(ret.getProperty());
        }

        internalOnClick.append("};");

        if (getPreCall() != null) {
            internalOnClick.append("if (").append(getPreCall()).append("(chooseStruct)) {");
        }
        internalOnClick.append("openPopupDialog(chooseStruct, ")
                .append("'").append(getWidth()).append("', '").append(getHeight()).append("'")
                .append(", function (chooseStruct) {");

        if (getPostCall() != null) {
            internalOnClick.append("if (").append(getPostCall()).append("(chooseStruct)) {");
        }

        internalOnClick.append("if (chooseStruct != undefined) {");
        i2 = getRetValue().iterator();
        while (i2.hasNext()) {
            PopupReturnTag ret = i2.next();
            internalOnClick.append("setFieldValue('").append(ret.getPropertyId()).append("', chooseStruct.").append(ret.getParamName()).append(");");
        }
        internalOnClick.append("}");

        if (getPostFill() != null) {
            internalOnClick.append(getPostFill()).append("(chooseStruct);");
        }

        if (getPostCall() != null) {
            internalOnClick.append("}");
        }

        internalOnClick.append("try {currentPopupDialogArg.caller.focus();} catch(err){} });");
        if (getPreCall() != null) {
            internalOnClick.append("}");
        }
        internalOnClick.append(";event.cancelBubble=true;event.returnValue=false;return false;");

        StringBuffer results = new StringBuffer();

        if (getCssClass() == null || getCssClass().equals("popup")) {
            setCssClass("popup");
        } else {
            setCssClass(getCssClass());
        }

        String tmpValue = TagUtils.getMessage(getRequestContext(), evaluate("value", getValue()));
        if (tmpValue == null) {
        	tmpValue = "";
        }
        
        if (getPopupType().equals("a")) {
            results.append("<a ");

            results.append(" href=\"").append(request.getContextPath()).append("?jfmn=popupOn&amp;").append(response.encodeURL(internalHref.toString())).append("\" ");
            //results.append(" href=\"").append(url).append("&amp;").append(response.encodeURL(internalHref.toString())).append("\" ");

//            if (accesskey != null) {
//                results.append(" accesskey=\"");
//                results.append(accesskey);
//                results.append("\"");
//            }
//
//            if (getOnkeypress() == null) {
//                setOnkeypress(";");
//            }
//
//            if (tabindex != null) {
//                results.append(" tabindex=\"");
//                results.append(tabindex);
//                results.append("\"");
//            }
//            if (getDisabled()) {
//                results.append(" disabled=\"");
//                results.append(getDisabled());
//                results.append("\"");
//            }

            results.append(" onclick=\"");
            results.append(getOnclick() + ";" + internalOnClick);
            results.append("\"");

            setOnclick(null);
//            results.append(prepareEventHandlers());
//            results.append(prepareStyles());

            results.append(">").append(tmpValue).append("</a>");
        } else {
        	if (TagUtils.isBootstrapTheme()) {
            	tagWriter.startTag("button");
            	setCssClass("btn btn-primary btn-popup");
        	} else {
            	tagWriter.startTag("input");
        	}
        	tagWriter.writeAttribute("type", getPopupType());
        	tagWriter.writeAttribute("name", "button.submit.popupOn?" + response.encodeURL(internalHref.toString()));
        	tagWriter.writeAttribute("value", tmpValue);
        	setOnclick(TagUtils.safeAppend(getOnclick(), ";" + internalOnClick));

//            if (accesskey != null) {
//                results.append(" accesskey=\"");
//                results.append(accesskey);
//                results.append("\"");
//            }

            if (getOnkeypress() == null) {
                setOnkeypress(";");
            }

//            if (tabindex != null) {
//                results.append(" tabindex=\"");
//                results.append(tabindex);
//                results.append("\"");
//            }
//            if (getDisabled()) {
//                results.append(" disabled=\"");
//                results.append(getDisabled());
//                results.append("\"");
//            }
//
//            results.append(prepareEventHandlers());
//            results.append(prepareStyles());
//            results.append(getElementClose());
            writeDefaultAttributes(tagWriter);

        	if (TagUtils.isBootstrapTheme()) {
        		//<i class="fa fa-ellipsis-h"></i>
        		tagWriter.startTag("i");
        		tagWriter.writeAttribute(CLASS_ATTRIBUTE, "fa fa-ellipsis-h");
        		tagWriter.endTag(true);
        	}

        	tagWriter.endTag();
        }

        // Evaluate the remainder of this page
        return (EVAL_PAGE);

    }


    /**
     * Returns the height.
     *
     * @return String
     */
    public String getHeight() {
        if (height == null)
            return "90%";
        return height;
    }

/**
 * Returns the image.
 * @return String
 */
//public String getSrc() {
//	return src;
//}

    /**
     * Returns the paramValue.
     *
     * @return List
     */
    public List getParamValue() {
        return paramValue;
    }

    /**
     * Returns the retValue.
     *
     * @return List
     */
    public List getRetValue() {
        return retValue;
    }

    /**
     * Returns the title.
     *
     * @return String
     */
    public String getTitle() {
        return title;
    }

    /**
     * Returns the url.
     *
     * @return String
     */
    public String getUrl() {
        return url;
    }

    /**
     * Returns the width.
     *
     * @return String
     */
    public String getWidth() {
        if (width == null)
            return "90%";
        return width;
    }

    /**
     * Sets the height.
     *
     * @param height The height to set
     */
    public void setHeight(String height) {
        this.height = height;
    }

    public String getForceEdit() {
		return forceEdit;
	}

	public void setForceEdit(String forceEdit) {
		this.forceEdit = forceEdit;
	}

	/**
     * Sets the paramValue.
     *
     * @param paramValue The paramValue to set
     */
    public void setParamValue(List paramValue) {
        this.paramValue = paramValue;
    }

    /**
     * Sets the paramValue.
     *
     * @param paramValue The paramValue to set
     */
    public void addParamValue(Object paramValue) {
        this.paramValue.add(paramValue);
    }

    /**
     * Sets the retValue.
     *
     * @param retValue The retValue to set
     */
    public void setRetValue(List retValue) {
        this.retValue = retValue;
    }

    /**
     * Sets the retValue.
     *
     * @param retValue The retValue to set
     */
    public void addRetValue(Object retValue) {
        this.retValue.add(retValue);
    }

    /**
     * Sets the title.
     *
     * @param title The title to set
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * Sets the url.
     *
     * @param url The url to set
     */
    public void setUrl(String url) {
        this.url = url;
    }

    /**
     * Sets the width.
     *
     * @param width The width to set
     */
    public void setWidth(String width) {
        this.width = width;
    }

    /**
     * Returns the chooseType.
     *
     * @return String
     */
    public String getPopupType() {
        return popupType;
    }

    /**
     * Sets the chooseType.
     *
     * @param chooseType The chooseType to set
     */
    public void setPopupType(String popupType) {
        this.popupType = popupType;
    }

    public String getPreCall() {
        return preCall;
    }

    public void setPreCall(String preCall) {
        this.preCall = preCall;
    }

    public String getPostCall() {
        return postCall;
    }

    public void setPostCall(String postCall) {
        this.postCall = postCall;
    }

    public String getPostFill() {
        return postFill;
    }

    public void setPostFill(String postFill) {
        this.postFill = postFill;
    }

    public boolean isUseDomName() {
		return useDomName;
	}

	public void setUseDomName(boolean useDomName) {
		this.useDomName = useDomName;
	}

	public String getValue() {
		return value;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public String getRenderIfPageStatusIs() {
		return renderIfPageStatusIs;
	}

	public void setRenderIfPageStatusIs(String renderIfPageStatusIs) {
		this.renderIfPageStatusIs = renderIfPageStatusIs;
	}

	public String getRenderIfPageStatusIsNot() {
		return renderIfPageStatusIsNot;
	}

	public void setRenderIfPageStatusIsNot(String renderIfPageStatusIsNot) {
		this.renderIfPageStatusIsNot = renderIfPageStatusIsNot;
	}

	/**
	 * Clears the stored {@link TagWriter}.
	 */
	@Override
	public void doFinally() {
		super.doFinally();
        this.paramValue = null;
        this.retValue = null;
        this.url = null;
        this.title = null;
        this.width = null;
        this.height = null;
        this.popupType = "submit";
        this.preCall = null;
        this.postCall = null;
        this.postFill = null;
        this.value = null;
        this.renderIfPageStatusIs = null;
        this.renderIfPageStatusIsNot = null;
        this.useDomName = false;
        this.forceEdit = null;
        this.value = null;
        setCssClass(null);
        setOnclick(null);
	}
}
