/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.taglib;

import java.lang.reflect.InvocationTargetException;

import javax.servlet.jsp.JspException;

import org.ow2.jonas.webapp.jonasadmin.WhereAreYou;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.taglib.html.LinkTag;
import org.apache.struts.taglib.TagUtils;

/**
 * @author Michel-Ange ANTON
 */
public class JonasButtonTag extends LinkTag {

// ----------------------------------------------------- Manifest Constants

    private static final String s_ImageBorder = "dot.gif";

// ----------------------------------------------------- Instance Variables

    protected String ms_PathImage = null;
    protected String ms_LastStyleClass = null;
    protected String ms_StyleClassButton = "btn";

// ------------------------------------------------------------- Properties

    private int widthBorder = 1;
    private int heightBorder = 1;
    private String imagesDir = null;
    private String styleClassBorderLight = "btnBorderLight";
    private String styleClassBorderShadow = "btnBorderShadow";
    private String styleClassBackground = "btn";
    private String styleClassDisabled = "btnDisabled";
    private String disabledName = null;
    private String disabledProperty = null;
    private String disabledValueEqual = null;
    private String disabledValueNotEqual = null;

    public int getHeightBorder() {
        return heightBorder;
    }

    public void setHeightBorder(int heightBorder) {
        this.heightBorder = heightBorder;
    }

    public String getImagesDir() {
        return imagesDir;
    }

    public void setImagesDir(String imagesDir) {
        this.imagesDir = imagesDir;
    }

    public int getWidthBorder() {
        return widthBorder;
    }

    public void setWidthBorder(int widthBorder) {
        this.widthBorder = widthBorder;
    }

    public String getStyleClassBorderLight() {
        return styleClassBorderLight;
    }

    public void setStyleClassBorderLight(String styleClassBorderLight) {
        this.styleClassBorderLight = styleClassBorderLight;
    }

    public String getStyleClassBorderShadow() {
        return styleClassBorderShadow;
    }

    public void setStyleClassBorderShadow(String styleClassBorderShadow) {
        this.styleClassBorderShadow = styleClassBorderShadow;
    }

    public String getStyleClassBackground() {
        return styleClassBackground;
    }

    public void setStyleClassBackground(String styleClassBackground) {
        this.styleClassBackground = styleClassBackground;
    }

    public String getStyleClassDisabled() {
        return styleClassDisabled;
    }

    public void setStyleClassDisabled(String styleClassDisabled) {
        this.styleClassDisabled = styleClassDisabled;
    }

    public String getDisabledName() {
        return disabledName;
    }

    public void setDisabledName(String disabledName) {
        this.disabledName = disabledName;
    }

    public String getDisabledProperty() {
        return disabledProperty;
    }

    public void setDisabledProperty(String disabledProperty) {
        this.disabledProperty = disabledProperty;
    }

    public String getDisabledValueEqual() {
        return disabledValueEqual;
    }

    public void setDisabledValueEqual(String disabledValueEqual) {
        this.disabledValueEqual = disabledValueEqual;
    }

    public String getDisabledValueNotEqual() {
        return disabledValueNotEqual;
    }

    public void setDisabledValueNotEqual(String disabledValueNotEqual) {
        this.disabledValueNotEqual = disabledValueNotEqual;
    }

// ------------------------------------------------------------- Public methods

    /**
     * Render the beginning of the hyperlink.
     *
     * @exception JspException if a JSP exception has occurred
     */
    public int doStartTag()
        throws JspException {

        // Test if button disabled
        boolean bDisabled = getDisabled();
        TagUtils tagUtils = TagUtils.getInstance();
        if ((getDisabledName() != null) &&
            ((getDisabledValueEqual() != null) || (getDisabledValueNotEqual() != null))) {
            String sValue = lookupProperty(getDisabledName(), getDisabledProperty());
            if (getDisabledValueEqual() != null) {
                bDisabled = getDisabledValueEqual().equals(sValue);
            } else {
                bDisabled = !getDisabledValueNotEqual().equals(sValue);
            }
        }

        // Force style class to the Link Tag
        ms_LastStyleClass = getStyleClass();
        if (getStyleClass() == null) {
            setStyleClass(ms_StyleClassButton);
        }
        // Prepare path image
        makePathImage();
        // Add the begining of render button
        StringBuffer sb = new StringBuffer(
            "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">");
        sb.append(prepareBorderTop());
        sb.append("<tr>");
        sb.append(prepareBorderColumn(styleClassBorderLight));
        sb.append("<td nowrap class=\"");
        if (bDisabled == false) {
            sb.append(styleClassBackground);
        } else {
            sb.append(styleClassDisabled);
        }
        sb.append("\">");
        tagUtils.write(pageContext, sb.toString());

        if (bDisabled == false) {
            // Add link if enabled
            return (super.doStartTag());
        }
        return (EVAL_BODY_BUFFERED);
    }

    /**
     * Render the end of the hyperlink.
     *
     * @exception JspException if a JSP exception has occurred
     */
    public int doEndTag()
        throws JspException {
        StringBuffer sb = new StringBuffer();
        int iRet = EVAL_PAGE;
        TagUtils tagUtils = TagUtils.getInstance();

        // If body text exist pre-fix and post-fix with space
        if (text != null) {
            StringBuffer sbText = new StringBuffer("&nbsp;");
            sbText.append(text);
            sbText.append("&nbsp;");
            text = sbText.toString();
        }

        if (getDisabled() == false) {
            // Add link if enabled
            iRet = super.doEndTag();
        } else {
            sb.append(text);
        }

        // Add the end of render button
        sb.append("</td>");
        sb.append(prepareBorderColumn(styleClassBorderShadow));
        sb.append("</tr>");
        sb.append(prepareBorderBottom());
        sb.append("</table>");
        tagUtils.write(pageContext, sb.toString());

        // Force last style
        setStyleClass(ms_LastStyleClass);
        ms_LastStyleClass = null;

        return (iRet);
    }

    public String getImagesRoot() {
        String sImagesRoot = null;
        WhereAreYou oWhere = getWhereAreYouInstance();
        if (oWhere != null) {
            sImagesRoot = oWhere.getImagesRoot();
        }
        return sImagesRoot;
    }

    public void release() {
        super.release();
        ms_PathImage = null;
        imagesDir = null;
        ms_StyleClassButton = null;
        styleClassBorderLight = null;
        styleClassBorderShadow = null;
        styleClassBackground = null;
        styleClassDisabled = null;
    }

// --------------------------------------------------------- Protected Methods
    protected void makePathImage() {
        // Prepare image separator
        if (imagesDir != null) {
            ms_PathImage = imagesDir + "/" + s_ImageBorder;
        }
        else if (getImagesRoot() != null) {
            ms_PathImage = getImagesRoot() + "/" + s_ImageBorder;
        }
        else {
            ms_PathImage = s_ImageBorder;
        }
    }

    /**
     * Return render image.
     * @return
     */
    protected String prepareImage() {
        StringBuffer sb = new StringBuffer("<img src=\"");
        sb.append(ms_PathImage);
        sb.append("\" width=\"");
        sb.append(widthBorder);
        sb.append("\" height=\"");
        sb.append(heightBorder);
        sb.append("\" border=\"0\">");
        return sb.toString();
    }

    /**
     * Return render image.
     * @return
     */
    protected String prepareBorderColumn(String ps_Class) {
        StringBuffer sb = new StringBuffer("<td width=\"");
        sb.append(widthBorder);
        sb.append("\" height=\"");
        sb.append(heightBorder);
        sb.append("\" class=\"");
        //btnBorderLight
        sb.append(ps_Class);
        sb.append("\">");
        sb.append(prepareImage());
        sb.append("</td>");
        return sb.toString();
    }

    protected String prepareBorderTop() {
        StringBuffer sb = new StringBuffer("<tr>");
        sb.append(prepareBorderColumn(styleClassBorderLight));
        sb.append(prepareBorderColumn(styleClassBorderLight));
        sb.append(prepareBorderColumn(styleClassBorderLight));
        sb.append("</tr>");
        return sb.toString();
    }

    protected String prepareBorderBottom() {
        StringBuffer sb = new StringBuffer("<tr>");
        sb.append(prepareBorderColumn(styleClassBorderLight));
        sb.append(prepareBorderColumn(styleClassBorderShadow));
        sb.append(prepareBorderColumn(styleClassBorderShadow));
        sb.append("</tr>");
        return sb.toString();
    }

    protected WhereAreYou getWhereAreYouInstance() {
        return (WhereAreYou) pageContext.getSession().getAttribute(WhereAreYou.SESSION_NAME);
    }

    protected String lookupProperty(String beanName, String property)
        throws JspException {

        TagUtils tagUtils = TagUtils.getInstance();
        Object bean = tagUtils.lookup(this.pageContext, beanName, null);
        if (bean == null) {
            throw new JspException(messages.getMessage("getter.bean", beanName));
        }
        if (property == null) {
            return bean.toString();
        }
        try {
            return (PropertyUtils.getProperty(bean, property)).toString();
        } catch (IllegalAccessException e) {
            throw new JspException(messages.getMessage("getter.access", property, beanName));

        } catch (InvocationTargetException e) {
            Throwable t = e.getTargetException();
            throw new JspException(messages.getMessage("getter.result", property, t.toString()));

        } catch (NoSuchMethodException e) {
            throw new JspException(messages.getMessage("getter.method", property, beanName));
        }
    }
}