/*
 * 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
 *
 * Initial developer(s): Michel-Ange ANTON
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.webapp.taglib;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;

public class TabsTag extends WhereAreYouTag {

// ----------------------------------------------------- Constants

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

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

    private ArrayList m_LabelTabs = new ArrayList();
    private ArrayList m_HrefTabs = new ArrayList();
    private ArrayList m_SelectedTabs = new ArrayList();
    private String m_Body = null;

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

    private int widthTab = 0;
    private int heightTab = 0;
    private String width = "100%";
    private String height = "";
    private int widthSeparator = 3;
    private int heightSeparator = 1;
    private int marginPanel = 5;
    private String imagesDir = null;

    /**
     * Accessor WidthTab property.
     */
    public int getWidthTab() {
        return widthTab;
    }

    public void setWidthTab(int widthTab) {
        this.widthTab = widthTab;
    }

    /**
     * Accessor HeightTab property.
     */
    public int getHeightTab() {
        return heightTab;
    }

    public void setHeightTab(int heightTab) {
        this.heightTab = heightTab;
    }

    /**
     * Accessor Width property.
     */
    public String getWidth() {
        return width;
    }

    public void setWidth(String width) {
        this.width = width;
    }

    /**
     * Accessor Height property.
     */
    public String getHeight() {
        return height;
    }

    /**
     * Accessor Height property.
     */
    public void setHeight(String height) {
        this.height = height;
    }

    /**
     * Accessor WidthSeparator property.
     */
    public int getWidthSeparator() {
        return widthSeparator;
    }

    public void setWidthSeparator(int widthSeparator) {
        this.widthSeparator = widthSeparator;
    }

    /**
     * Accessor HeightSeparator property.
     */
    public int getHeightSeparator() {
        return heightSeparator;
    }

    public void setHeightSeparator(int heightSeparator) {
        this.heightSeparator = heightSeparator;
    }

    /**
     * Accessor MarginPanel property.
     */
    public int getMarginPanel() {
        return marginPanel;
    }

    public void setMarginPanel(int marginPanel) {
        this.marginPanel = marginPanel;
    }

    /**
     * Accessor ImagesDir property.
     */
    public String getImagesDir() {
        return imagesDir;
    }

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

// --------------------------------------------------------- Public Methods

    public int doStartTag()
        throws JspException {

        this.m_LabelTabs.clear();
        this.m_HrefTabs.clear();
        this.m_SelectedTabs.clear();
        this.m_Body = null;

        return (EVAL_BODY_BUFFERED);
    }

    /**
     * Render this instant actions control.
     *
     * @exception JspException if a processing error occurs
     */
    public int doEndTag()
        throws JspException {
        JspWriter out = pageContext.getOut();
        try {
            verifySelected();
            render(out);
        }
        catch (IOException e) {
            throw new JspException(e);
        }
        return (EVAL_PAGE);
    }

    /**
     * Release all state information set by this tag.
     */
    public void release() {
        this.m_LabelTabs.clear();
        this.m_HrefTabs.clear();
        this.m_SelectedTabs.clear();
        this.m_Body = null;
        this.width = null;
        this.height = null;
        this.imagesDir = null;
    }

// -------------------------------------------------------- Package Methods

    /**
     * Add a new Action to the set that will be rendered by this control.
     *
     * @param label Localized label visible to the user
     * @param selected Initial selected state of this option
     * @param url URL to which control should be transferred if selected
     */

    void addTab(String ps_Label, String ps_Href, boolean ps_Selected) {
        m_LabelTabs.add(ps_Label);
        m_HrefTabs.add(ps_Href);
        m_SelectedTabs.add(new Boolean(ps_Selected));
    }

    void setBody(String ps_Body) {
        m_Body = ps_Body;
    }

// ------------------------------------------------------ Private Methods

    private void render(JspWriter out)
        throws IOException, JspException {
        out.println("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"100%\">");
        out.println("<tr>");
        out.println("<td>");
        renderTabs(out);
        out.println("</td>");
        out.println("</tr>");
        out.println("<tr>");
        out.println("<td>");
        renderPanel(out);
        out.println("</td>");
        out.println("</tr>");
        out.println("</table>");
    }

    private void renderPanel(JspWriter out)
        throws IOException, JspException {
        // Render the panel of this element
        out.print("<table border=\"0\" cellspacing=\"0\" cellpadding=\"");
        out.print(marginPanel);
        out.print("\"");
        out.print(" width=\"");
        out.print(width);
        out.print("\"");
        out.println(">");
        out.println("<tr valign=\"top\">");
        out.println("<td class=\"panel\">");
        out.print("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" width=\"");
        out.print(width);
        out.print("\"");
        out.println(">");
        out.println("<tr valign=\"top\">");
        out.print("<td height=\"");
        out.print(height);
        out.println("\" class=\"panel\">");
        if (m_Body != null) {
            out.println(m_Body);
        }
        out.println("</td>");
        out.println("</tr>");
        out.println("</table>");
        out.println("</td>");
        out.println("</tr>");
        out.println("</table>");
    }

    private void renderTabs(JspWriter out)
        throws IOException, JspException {
        int i = 0;
        boolean bSelected = false;
        StringBuffer sbLabel = null;
        String sImageSep = null;

        // Prepare image separator
        if (imagesDir != null) {
            sImageSep = imagesDir + "/" + s_ImageSeparator;
        }
        else if (isUsingWhere()) {
            sImageSep = getImagesRoot() + "/" + s_ImageSeparator;
        }
        else {
            sImageSep = s_ImageSeparator;
        }
        // Render the beginning of this element
        try {
            out.println("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\" >");
        }
        catch (IOException ex) {
        }

        // Render each defined label tab
        int n = m_LabelTabs.size();
        out.println("<tr>");
        for (i = 0; i < n; i++) {
            // Init Label display
            sbLabel = new StringBuffer();
            // Detect selected tab
            bSelected = ((Boolean) m_SelectedTabs.get(i)).booleanValue();
            // Display begin tag
            out.print("<td align=\"center\"");
            // Display width tab and prepare label
            if (widthTab > 0) {
                out.print(" width=\"");
                out.print(widthTab);
                out.print("\"");
                sbLabel.append(m_LabelTabs.get(i));
            }
            else {
                sbLabel.append("&nbsp;");
                sbLabel.append(m_LabelTabs.get(i));
                sbLabel.append("&nbsp;");
            }
            out.print(" class=\"");
            if (bSelected == true) {
                out.print("tabSelect");
            }
            else {
                out.print("tab");
            }
            out.print("\"");
            // Height tab
            if (heightTab > 0) {
                out.print(" height=\"");
                out.print(heightTab);
                out.print("\"");
            }
            out.print(">");

            // Display label
            if ((bSelected == true) || (m_HrefTabs.get(i).toString().length() == 0)) {
                // Simple label
                out.print(sbLabel.toString());
            }
            else {
                // Link label
                out.print("<a href=\"");
                out.print(m_HrefTabs.get(i).toString());
                out.print("\"");
                out.print(" class=\"");
                out.print("tab");
                out.print("\"");
                out.print(">");
                out.print(sbLabel.toString());
                out.print("</a>");
            }
            out.println("</td>");

            if (i < (n - 1)) {
                // Separator Part
                out.print("<td");
                out.print(" class=\"tabSeparatorVertical\"");
                out.print(">");
                // Image
                out.print("<img src=\"");
                out.print(sImageSep);
                out.print("\" width=\"");
                out.print(widthSeparator);
                out.print("\" height=\"");
                out.print(heightSeparator);
                out.print("\" border=\"0\">");
                out.println("</td>");
            }
        }
        out.println("</tr>");

        // Render underline
        out.println("<tr>");
        for (i = 0; i < n; i++) {
            bSelected = ((Boolean) m_SelectedTabs.get(i)).booleanValue();
            // Label Line Part
            out.print("<td");
            out.print(" class=\"");
            if (bSelected == true) {
                out.print("tabSelect");
            }
            else {
                out.print("tabSeparatorHorizontal");
            }
            out.print("\"");
            out.print(">");
            out.print("<img src=\"");
            out.print(sImageSep);
            out.print("\" width=\"");
            out.print(widthSeparator);
            out.print("\" height=\"");
            out.print(heightSeparator);
            out.print("\" border=\"0\">");
            out.println("</td>");

            // Last tab ?
            if (i < (n - 1)) {
                // Separator Line Part
                out.print("<td");
                out.print(" class=\"tabSeparatorHorizontal\"");
                out.print(">");
                out.print("<img src=\"");
                out.print(sImageSep);
                out.print("\" width=\"");
                out.print(widthSeparator);
                out.print("\" height=\"");
                out.print(heightSeparator);
                out.print("\" border=\"0\">");
                out.println("</td>");
            }
        }
        // Display end tag
        out.println("</tr>");
        out.println("</table>");
    }

    /**
     * Verify if one tab is selected else select the first.
     */
    private void verifySelected() {
        boolean bFound = false;
        for (int i = 0; i < m_SelectedTabs.size(); i++) {
            if (bFound == true) {
                // unselect all next if one is found
                m_SelectedTabs.set(i, new Boolean(false));
            }
            else {
                // detect the first selected
                bFound = ((Boolean) m_SelectedTabs.get(i)).booleanValue();
            }
        }
        if ((bFound == false) && (m_SelectedTabs.size() > 0)) {
            m_SelectedTabs.set(0, new Boolean(true));
        }
    }
}
