// ============================================================================
// 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.util.settings.EnumValue;

import javax.swing.*;
import java.awt.*;
import java.util.Locale;
import java.util.prefs.Preferences;

/**
 *  An editor for enum values.
 *
 *  @author <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
public class EnumEditor
        extends AbstractBasicEditorProvider
{
  /**
   *  Internal class used for localization.
   */
  private static class EnumValueLocalizer
          implements EnumValue
  {
    /** The wrapped enum value. */
    private final EnumValue wrapped;
    /** The locale to use for localizatrion. */
    private final Locale locale;

    public EnumValueLocalizer(EnumValue wrapped, Locale locale)
    {
      this.wrapped = wrapped;
      this.locale = locale;
    }

    public String getShortName(Locale l)
    {
      return wrapped.getShortName(l);
    }

    public String getLongName(Locale l)
    {
      return wrapped.getLongName(l);
    }

    public void storeTo(Preferences preferences, String key)
    {
      wrapped.storeTo(preferences, key);
    }

    public boolean isEqualTo(Preferences preferences, String key)
    {
      return wrapped.isEqualTo(preferences, key);
    }

    public Object getRealValue()
    {
      return wrapped.getRealValue();
    }

    public EnumValue getBasicValue()
    {
      return wrapped;
    }

    public String toString()
    {
      return wrapped.getShortName(locale);
    }
  }

  /** The preference property which is set by this editor. */
  private final SwingEnumPreferenceProperty property;

  /** The combobox displaying the values. */
  private JComboBox comboBox;

  /**
   *  Constructor.
   *  @param property edited property
   *  @param l        locale
   */
  public EnumEditor(SwingEnumPreferenceProperty property, final Locale l)
  {
    super(property, l);
    this.property = property;

    final EnumValue[] enumValues = property.getEnumValues(l);
    DefaultComboBoxModel model = new DefaultComboBoxModel();
    final EnumValue value = property.getValue();
    int selected = 0;
    for (int e = 0;  e < enumValues.length;  ++e) {
      if (enumValues[e] == value) {
        selected = e;
      }
      model.addElement(new EnumValueLocalizer(enumValues[e], l));
    }
    comboBox = new JComboBox(model);
    comboBox.setSelectedIndex(selected);
    comboBox.setRenderer(new DefaultListCellRenderer() {
      public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
                                                    boolean cellHasFocus)
      {
        JComponent comp =  (JComponent)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        comp.setToolTipText(((EnumValue)value).getLongName(l));
        return comp;
      }
    });
  }

  /**
   * Get an component for editing .
   *
   * @return editor component
   */
  public JComponent getEditor()
  {
    return comboBox;
  }

  /**
   * Reset the value in the editor to the basic value.
   */
  public void reset()
  {
    DefaultComboBoxModel model = (DefaultComboBoxModel)comboBox.getModel();
    comboBox = new JComboBox(model);
    final EnumValue value = property.getValue();
    for (int e = model.getSize()-1;  e >= 0;  --e) {
      if (((EnumValueLocalizer)model.getElementAt(e)).getBasicValue() == value) {
        comboBox.setSelectedIndex(e);
      }
    }
  }

  /**
   * Set the basic value from the editor.
   */
  public void save()
  {
    EnumValueLocalizer value = (EnumValueLocalizer)comboBox.getSelectedItem();
    property.setValue(value.getBasicValue());
  }

  /**
   * Called when the editor provider is no longer used.
   */
  public void goodBye()
  {
  }
}
