
package uk.co.wingpath.gui;

import java.util.*;
import java.util.List;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import uk.co.wingpath.util.*;
import uk.co.wingpath.event.*;
import uk.co.wingpath.event.Event;


/**
* This class implements <code>WComponent</code> using a <code>JCheckBox</code>.
*/
public class WCheckBox
    extends WAbstractComponent<Boolean>
{
    private final JCheckBox checkBox;
    private final String text;
    private Boolean value;

    /**
    * Constructs a <code>WCheckBox</code>.
    * <p>A <code>WCheckBox</code> may have two labels: an associated
    * <code>JLabel</label> (which would normally appear to the left of the
    * checkbox), and the label that is part of the <code>JCheckBox</code>
    * (which would normally appear to the right of the checkbox).
    * @param label text for the associated label, or <code>null</code> if
    * there is no associated label.
    * @param text text for the label that is part of the <code>JCheckBox</code>,
    * or <code>null</code> if this label is not required.
    * @param initVal initial value for the component.
    */
    public WCheckBox (String label, String text, boolean initVal)
    {
        Event.checkIsEventDispatchThread ();
        value = initVal;
        checkBox = new JCheckBox (text, initVal);
        initialize (checkBox, label);
        this.text = text;

        checkBox.addItemListener (new ItemListener ()
            {
                public void itemStateChanged (ItemEvent e)
                {
                    boolean val = checkBox.isSelected ();
                    if (val != value)
                    {
                        value = val;
                        fireValueChanged (false);
                    }
                }
            });
    }

    /**
    * Constructs a <code>WCheckBox</code> with no associated
    * <code>JLabel</code>.
    * @param text text for the label that is part of the <code>JCheckBox</code>,
    * or <code>null</code> if this label is not required.
    * @param initVal initial value for the component.
    */
    public WCheckBox (String text, boolean initVal)
    {
        this (null, text, initVal);
    }

    /**
    * Gets the value of the component.
    * @return the value of the component.
    */
    public Boolean getValue ()
    {
        return value;
    }

    /**
    * Sets the value of the component.
    * <p>This method does NOT fire a value event.
    * @param value the new value for the component.
    */
    public void setValue (Boolean value)
    {
        Event.checkIsEventDispatchThread ();
        // The order of the next two statements is important - we don't
        // want to fire a ValueEvent.
        this.value = value;
        checkBox.setSelected (value);
    }

    @Override
    public void setMnemonic (int mnemonic)
    {
        Event.checkIsEventDispatchThread ();
        JLabel label = getLabel ();
        if (label != null)
            label.setDisplayedMnemonic (mnemonic);
        else if (text != null)
            checkBox.setMnemonic (mnemonic);
    }

    @Override
    public void setMnemonic (int mnemonic, int index)
    {
        Event.checkIsEventDispatchThread ();
        JLabel label = getLabel ();
        if (label != null)
        {
            if (index < label.getText ().length ())
            {
                label.setDisplayedMnemonic (mnemonic);
                label.setDisplayedMnemonicIndex (index);
                return;
            }
            index -= label.getText ().length ();
        }
        if (text != null)
        {
            checkBox.setMnemonic (mnemonic);
            checkBox.setDisplayedMnemonicIndex (index);
        }
    }

    @Override
    public void setBackground (Color bg)
    {
        if (bg == Gui.COLOUR_BACKGROUND_NORMAL)
            bg = Gui.COLOUR_BACKGROUND_PANEL;
        checkBox.setBackground (bg);
    }
}
