// ====================================================================
// File:		StateButton
// 
// Project:             General Swing support
//
// Purpose:		A JToggleButton which displayes a state.
//
// Author:		rammi
// Date: 		31.03.2002
// Time: 		13:28:39
// --------------------------------------------------------------------
// Copyright Notice:	(c) 2002 Rammi (rammi@caff.de)
//                      This code is in the public domain.
//                      Use at own risk.
//                      No guarantees given.
//
// Latest change:       $Date$
//
// History: 		$Log$
// ====================================================================
package de.caff.gimmicks.swing;

import javax.swing.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

/**
 *  Button which displays a {@link State}.
 *
 *  @author  <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
public class StateButton
  extends    JToggleButton
  implements PropertyChangeListener,
             ItemListener
{
  /** The state which this button displays. */
  private State state;

  /**
   *  Create a new button from a state.
   *  @param state state from which to create the button
   */
  public StateButton(final State state)
  {
    super();

    setModel(new ToggleButtonModel() {
      /**
       * Sets the button to pressed or unpressed.
       *
       * @param b true to set the button to "pressed"
       */
      public void setPressed(boolean b) {
        if (!state.isActivated()  ||  b) {
          super.setPressed(b);
        }
      }
    });

    this.state = state;

    Icon icon = (Icon)state.getValue(State.INACTIVE_ICON_PROPERTY);
    if (icon != null) {
      setIcon(icon);


      icon = (Icon)state.getValue(State.ACTIVE_ICON_PROPERTY);
      if (icon != null) {
        setSelectedIcon(icon);
      }

      icon = (Icon)state.getValue(State.DISABLED_ICON_PROPERTY);
      if (icon != null) {
        setDisabledIcon(icon);
        setDisabledSelectedIcon(icon);
      }
    }
    else {
      setText((String)state.getValue(State.LABEL_TEXT_PROPERTY));
    }

    String ttt = (String)state.getValue(State.TOOLTIP_TEXT_PROPERTY);
    if (ttt != null) {
      setToolTipText(ttt);
    }

    setEnabled(state.isEnabled());
    setSelected(state.isActivated());

    addItemListener(this);
    state.addPropertyChangeListener(this);
  }

  /**
   * This method gets called when a bound property is changed.
   * @param evt A PropertyChangeEvent object describing the event source
   *   	and the property that has changed.
   */

  public void propertyChange(PropertyChangeEvent evt)
  {
    String property = evt.getPropertyName();

    if (State.ACTIVATION_PROPERTY.equals(property)) {
      boolean state = ((Boolean)evt.getNewValue()).booleanValue();
      if (state != isSelected()) {
        setSelected(state);
      }
    }
    else if (State.ENABLE_PROPERTY.equals(property)) {
      boolean state = ((Boolean)evt.getNewValue()).booleanValue();
      if (state != isEnabled()) {
        setEnabled(state);
      }
    }
    else if (State.ACTIVE_ICON_PROPERTY.equals(property)) {
      Icon icon = (Icon)evt.getNewValue();
      if (!icon.equals(getSelectedIcon())) {
        setSelectedIcon(icon);
      }
    }
    else if (State.DISABLED_ICON_PROPERTY.equals(property)) {
      Icon icon = (Icon)evt.getNewValue();
      if (!icon.equals(getDisabledIcon())) {
        setDisabledIcon(icon);
        setDisabledSelectedIcon(icon);
      }
    }
    else if (State.INACTIVE_ICON_PROPERTY.equals(property)) {
      Icon icon = (Icon)evt.getNewValue();
      if (!icon.equals(getIcon())) {
        setIcon(icon);
      }
    }
    else if (State.LABEL_TEXT_PROPERTY.equals(property)) {
      String text = (String)evt.getNewValue();
      if (getIcon() == null) {
        setText(text);
      }
    }
    else if (State.TOOLTIP_TEXT_PROPERTY.equals(property)) {
      String text = (String)evt.getNewValue();
      setToolTipText(text);
    }
  }

  /**
   * Invoked when an item has been selected or deselected by the user.
   * The code written for this method performs the operations
   * that need to occur when an item is selected (or deselected).
   */
  public void itemStateChanged(ItemEvent e)
  {
    if (e.getStateChange() == ItemEvent.SELECTED) {
      state.activate();
    }
  }

}
