// StringChoiceEditor.java
// $Id: StringChoiceEditor.java,v 1.2 1998/01/22 13:28:52 bmahe Exp $
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html

package org.w3c.jigadm.editors;

import java.awt.*;
import java.awt.event.*;
import java.util.*;

import org.w3c.tools.resources.*;
import org.w3c.jigadm.*;
import org.w3c.jigsaw.admin.*;

/**
 * An editor for StringChoice attributes.  
 * @author Benoit Mahe <bmahe@sophia.inria.fr>
 */

public class StringChoiceEditor extends AttributeEditor {

  class StringChoiceComponent extends Panel 
                              implements ItemListener, 
                                         TextListener
  {

    EditorFeeder feeder = null;
    String selected = null;
    StringChoiceEditor editor = null;
    Choice choice = null;
    TextField text = null;

    // ItemListener
    public void itemStateChanged(ItemEvent e) {
      if (e.getStateChange() == ItemEvent.SELECTED) {
        text.setText((String)e.getItem());
	editor.setModified();
      }
    }

    //TextListener
    public void textValueChanged(TextEvent e) {
      editor.setModified();
    }

    protected void setSelectedItem(String selected) {
      this.selected = selected;
      text.setText(selected);
    }

    protected String getSelectedItem() {
      return text.getText();
    }

    protected void setDefaultItems(EditorFeeder feeder) {
      choice.removeAll();
      String items[] = feeder.getDefaultItems();
      if (items != null) {
	for (int i = 0 ; i < items.length ; i++) 
	  if ( items[i] != null )
	    choice.addItem(items[i]);
      }
    }

    StringChoiceComponent(StringChoiceEditor editor,
			  String selected,
			  EditorFeeder feeder) 
    {
      this.editor = editor;
      this.feeder = feeder;
      this.selected = selected;
      
      text = new TextField(20);
      text.setText(selected);
      text.addTextListener( this );
      choice = new Choice();
      choice.addItemListener( this );
      setDefaultItems(feeder);
      setLayout( new BorderLayout(5,5));
      add(text,"West");
      add(choice,"Center");
    }
  }

  /**
   * Properties - The feeder's class name.
   */
  public static final String FEEDER_CLASS_P = "feeder.class";

  protected boolean hasChanged = false;
  protected String oldvalue    = null;
  protected StringChoiceComponent comp = null;

  protected Dimension getPopupSize() {
    return new Dimension(400,160);
  }

  protected void createComponent(EditorFeeder feeder, String selected) {
    if ( comp == null ) 
      comp = new StringChoiceComponent(this,
				       selected,
				       feeder);
  }

  protected void setModified() {
    hasChanged = true;
  }

  /**
   * Tells if the edited value has changed
   * @return true if the value changed.
   */
  public boolean hasChanged() {
    return hasChanged;
  }

  /**
   * set the current value to be the original value, ie: changed
   * must return <strong>false</strong> after a reset.
   */
  public void clearChanged() {
    hasChanged = false;
  }

  /**
   * reset the changes (if any)
   */
  public void resetChanges() {
    hasChanged = false;
    comp.setSelectedItem(oldvalue);
  }

  /**
   * Get the current value of the edited value
   * @return an object or <strong>null</strong> if the object was not
   * initialized
   */
  public Object getValue() {
    return comp.getSelectedItem();    
  }

  /**
   * Set the value of the edited value
   * @param o the new value.
   */
  public void setValue(Object o) {
    this.oldvalue = (String) o;
    comp.setSelectedItem(oldvalue);
  }

  /**
   * get the Component created by the editor.
   * @return a Component
   */
  public Component getComponent() {
    return comp;
  }

  
  
  /**
   * Initialize the editor
   * @param w the ResourceWrapper father of the attribute
   * @param a the Attribute we are editing
   * @param o the value of the above attribute
   * @param p some Properties, used to fine-tune the editor
   */
  public void initialize(RemoteResourceWrapper w
			 , Attribute a
			 , Object o
			 , Properties p) 
    throws RemoteAccessException
  {
    // Get the feeder class fromproperties:
    EditorFeeder feeder      = null;
    String       feederClass = null;
    
    feederClass = (String)p.get(FEEDER_CLASS_P);
    if ( feederClass == null )
      throw new RuntimeException("StringChoiceEditor mis-configuration: "+
				 FEEDER_CLASS_P + " property undefined.");
    try {
      Class c = Class.forName(feederClass);
      feeder  = (EditorFeeder) c.newInstance();
      feeder.initialize(w,p);
    } catch (Exception ex) {
      ex.printStackTrace();
      throw new RuntimeException("StringChoiceEditor mis-configured: "+
				 " unable to instantiate "+
				 feederClass +".");
    }
    createComponent(feeder, (String) o);
    oldvalue = (String) o;
  }
  
  public StringChoiceEditor() {
    super();
  }
}
