// ============================================================================
// File:               $File$
//
// Project:            
//
// Purpose:            
//
// Author:             Rammi
//
// Copyright Notice:   (c) 2005  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.util.settings.swing;

import de.caff.i18n.swing.RJCheckBoxMenuItem;
import de.caff.util.settings.BooleanPreferenceProperty;

import javax.swing.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Locale;
import java.util.prefs.Preferences;

/**
 *  Editable boolean preference property.
 *
 *  @author <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
public class SwingBooleanPreferenceProperty
        extends AbstractBasicSimpleEditablePreferenceProperty
        implements BooleanPreferenceProperty
{
  /** The current value. */
  private boolean value;

  /**
   *
   *  @param basicName  property tag
   *  @param baseTag    i18n tag
   *  @param value      default value
   */
  public SwingBooleanPreferenceProperty(String basicName, String baseTag, boolean value)
  {
    super(basicName, baseTag);
    this.value = value;
  }

  /**
   * Read the property value from the preferences.
   *
   * @param preferences preferences from where to read the property value
   */
  public void readFrom(Preferences preferences)
  {
    setValue(preferences.getBoolean(getBasicName(), value));
  }

  /**
   * Store the current property value in the preferences.
   *
   * @param preferences preferences where to store the property value
   */
  public void storeTo(Preferences preferences)
  {
    preferences.putBoolean(getBasicName(), value);
  }

  /**
   * Get the editor components for editing this preference property.
   *
   * @param l locale used for i18n
   * @return editor components
   */
  public EditorProvider getEditorProvider(Locale l)
  {
    return new BooleanEditor(this, l);
  }

  /**
   *  Get the current value.
   *  @return the value
   */
  public boolean getValue()
  {
    return value;
  }

  /**
   *  Set the value.
   *  @param value new value
   */
  public void setValue(boolean value)
  {
    if (this.value != value) {
      this.value = value;
      fireValueChange(getBasicName(), !value, value);
    }
  }

  private class SpecialMenuItem
          extends RJCheckBoxMenuItem
          implements PropertyChangeListener
  {
    /**
     *  Constructor.
     */
    public SpecialMenuItem()
    {
      super(getBaseTag(), getValue());
      addItemListener(new ItemListener() {
        public void itemStateChanged(ItemEvent e)
        {
          setValue(isSelected());
        }
      });
    }

    /**
     * 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)
    {
      setSelected(((Boolean)evt.getNewValue()).booleanValue());
    }

    /**
     * Notifies this component that it now has a parent component.
     */
    public void addNotify()
    {
      super.addNotify();
      addValueChangeListener(this);
      setSelected(getValue());
    }

    /**
     * Overrides <code>removeNotify</code> to remove this from the value listeners-
     */
    public void removeNotify()
    {
      super.removeNotify();
      removeValueChangeListener(this);
    }
  }

  /**
   *  Create a menu item for this boolean property.
   *  @param l locale
   *  @return menu item
   */
  public JMenuItem createMenuItem(Locale l)
  {
    SpecialMenuItem menuItem = new SpecialMenuItem();
    menuItem.setLocale(l);
    return menuItem;
  }
}
