/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the
 * License at http://www.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.bebop;


import com.arsdigita.bebop.util.GlobalizationUtil ; 


import com.arsdigita.util.Assert;
import com.arsdigita.xml.Element;

/**
 * Consists of two table cells with a dividing
 * bar in the middle. This container is used only for layout.
 * It is intended to be used as a parent class for a wizard-type
 * SplitWizard component.
 * <p>
 *
 * This container contains three components: "left", "right" and "header".
 * All three components must be present (non-null) before <code>SplitPanel</code>
 * is locked. An exception will be thrown if this is not the case.
 *
 * @author Stanislav Freidin 
 * @version $Id: //core-platform/dev/src/com/arsdigita/bebop/SplitPanel.java#10 $
 */

public class SplitPanel extends SimpleContainer {
    public static final String versionId = "$Id: //core-platform/dev/src/com/arsdigita/bebop/SplitPanel.java#10 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    private Component m_left, m_right, m_header;
    private int m_divider;

    /**
     * The border attribute.
     */
    public final static String BORDER = "border";

    /**
     * Constructs a new, empty SplitPanel.
     */
    public SplitPanel() {
        this(new Label("&nbsp;", false), new Label("&nbsp;", false), new Label("&nbsp;", false));
    }

    /**
     * Constructs a new SplitPanel with the specified left and right
     * components.
     */
    public SplitPanel(Component left, Component right) {
        this(new Label("&nbsp;", false), left, right);
    }

    /**
     * Constructs a new SplitPanel with the specified left, right and header
     * components.
     */
    public SplitPanel(Component header, Component left, Component right) {
        super();
        setDivider(25);
        if (header != null) {
            setHeader(header);
        }
        if (left != null) {
            setLeftComponent(left);
        }
        if (right != null) {
            setRightComponent(right);
        }
        setAttribute("cellpadding", "5");
        setAttribute("cellspacing" , "0");
        setAttribute("width", "100%");
        setBorder(true);
    }

    /**
     * Sets the divider position. The position must be an integer in
     * the range of 0 (all the way to the left) to 100
     * (all the way to the right).
     *
     * @param divider the position of the divider
     */
    public void setDivider(int divider) {
        Assert.assertNotLocked(this);

        if (divider < 0 || divider > 100) {
            throw new IllegalArgumentException("Divider must be in range 0..100");
        }

        m_divider = divider;
    }

    /**
     * Retrieves the divider position
     *
     * @return the divider position in HTML, such as "25%".
     */
    public final int getDivider() {
        return m_divider;
    }

    /**
     * 
     * Sets the border.
     * @param hasBorder <code>true</code> if the split panel
     * will have a border
     *
     */
    public void setBorder(boolean border) {
        setAttribute(BORDER, border ? "1" : "0");
    }

    /**
     * 
     * Determine whether this panel has a border.
     *
     * @return <code>true</code> if the split panel has a border;
     * <code>false</code> otherwise.
     */
    public boolean getBorder() {
        String border = getAttribute(BORDER);
        return ("1".equals(border));
    }

    /**
     * Gets the left component.
     *
     * @return the component on the left.
     */
    public final Component getLeftComponent() {
        return m_left;
    }

    /**
     * Gets the right component.
     *
     * @return the component on the right.
     */
    public final Component getRightComponent() {
        return m_right;
    }

    /**
     * Gets the header component.
     *
     * @return the component at the top.
     */
    public final Component getHeader() {
        return m_header;
    }

    /**
     * Sets the header. Will throw an IllegalStateException
     * if the header component has already been set.
     *
     * @param c the new component to be put in the header
     */
    public void setHeader(Component c) {
        Assert.assertNotLocked(this);

        if (!super.contains(c)) {
            super.add(c);
        }

        m_header = c;
    }

    /**
     * Sets the left component. Will throw an IllegalStateException
     * if the left component has already been set.
     *
     * @param c the new component to be put in the left slot
     */
    public void setLeftComponent(Component c) {
        Assert.assertNotLocked(this);

        if (!super.contains(c)) {
            super.add(c);
        }

        m_left = c;
    }

    /**
     * Sets the right component. Will throw an IllegalStateException
     * if the right component has already been set.
     *
     * @param c the new component to be put in the right slot
     */
    public void setRightComponent(Component c) {
        Assert.assertNotLocked(this);

        if (!super.contains(c)) {
            super.add(c);
        }

        m_right = c;
    }

    /**
     * Generates XML for the panel. The DOM fragment will look
     * like the following:
     * <p><code><pre>
     * &lt;bebop:splitPanel&gt;
     *   &lt;XML for the left component /&gt;
     *   &lt;XML for the right component /&gt;
     * &lt;/bebop:splitPanel&gt;</pre></code>
     * @param state the current page state
     * @param parent the parent under which the XML should be placed
     *
     */
    public void generateXML(PageState state, Element parent) {

        if ( ! isVisible(state) ) {
            return;
        }

        Element panel = parent.newChildElement("bebop:splitPanel", BEBOP_XML_NS);
        exportAttributes(panel);
        panel.addAttribute("divider_left", Integer.toString(m_divider) + "%");
        panel.addAttribute("divider_right", Integer.toString(100 - m_divider) + "%");
        Element header = panel.newChildElement("bebop:cell", BEBOP_XML_NS);
        Element left = panel.newChildElement("bebop:cell", BEBOP_XML_NS);
        Element right = panel.newChildElement("bebop:cell", BEBOP_XML_NS);
        getHeader().generateXML(state, header);
        getLeftComponent().generateXML(state, left);
        getRightComponent().generateXML(state, right);
    }

    /**
     * Verifies that the header, left, and right components exist.
     */
    public void lock() {
        Assert.assertNotNull(getHeader(), "Header");
        Assert.assertNotNull(getLeftComponent(), "Left Component");
        Assert.assertNotNull(getRightComponent(), "Right Component");
        super.lock();
    }
}
