package com.sptci.echo2demo;

import javax.jdo.InstanceCallbacks;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.Formatter;
import java.util.ArrayList;
import java.util.List;
import com.sptci.echo2.ListItem;
import java.util.Map;
import java.util.TreeMap;

/**
 * A JavaBean that represents the data represented by 
 * {@link com.sptci.echo2demo.InputForm}.
 *
 * @author com.sptci.echo2.JDOBeanGenerator 2006-02-09 10:00:15-0600
 * @version $Id: InputFormModel.java,v 1.1 2006/02/13 23:39:45 rakesh Exp $
 */
public class InputFormModel
  implements InstanceCallbacks, Cloneable, Comparable<InputFormModel>, Serializable
{
  /**
   * The default value to use as the base for hashCode.
   */
  protected static final int HASH = 7;

  /**
   * The field used to store pre-computed hashCode.
   */
  protected int hash = HASH;

  /**
   * Field that represents the checkBoxes field of type
   * checkBoxes
   */
  private Map<String, Boolean> checkBoxes;

  /**
   * Field that represents the listBox field of type
   * listBox
   */
  private List<ListItem> listBox;

  /**
   * Field that represents the selectField field of type
   * selectField
   */
  private List<ListItem> selectField;

  /**
   * Field that represents the textArea field of type
   * textArea
   */
  private String textArea;

  /**
   * Field that represents the textField field of type
   * textField
   */
  private String textField;

  /**
   * The property change event dispatcher.  This object
   * is lazily loaded.
   */
  private transient PropertyChangeSupport propertyChangeSupport;

  /**
   * Default constructor.  Uses the designated constructor.
   */
  public InputFormModel()
  {
    checkBoxes = new TreeMap<String, Boolean>();
    listBox = new ArrayList<ListItem>();
    selectField = new ArrayList<ListItem>();
    for ( int i = 0; i < 3; ++i )
    {
      checkBoxes.put( "Check " + i, false );
      listBox.add( new ListItem( "List Item " + i ) );
      selectField.add( new ListItem( "Select " + i ) );
    }
  }

  /**
   * Designated constructor.  Initialises the
   * fields with the specified values.
   */
  public InputFormModel( Map<String, Boolean> checkBoxes,
    List<ListItem> listBox,
    List<ListItem> selectField,
    String textArea,
    String textField )
  {
    setCheckBoxes( checkBoxes );
    setListBox( listBox );
    setSelectField( selectField );
    setTextArea( textArea );
    setTextField( textField );
  }

  /**
   * Return a String representation of the fields of this class.
   * The String representation is returned as an XML document.
   *
   * @return String An XML representation of the class fields.
   */
  @Override
  public String toString()
  {
    StringBuilder builder = new StringBuilder( 4096 );
    Formatter formatter = new Formatter( builder );
    formatter.format( "<InputFormModel package='%s'>%n", getClass().getPackage().getName() );

    formatter.format( "<checkBoxes type='Map&lt;String, Boolean&gt;'>%n" );
    for ( Map.Entry<String, Boolean> entry : checkBoxes.entrySet() )
    {
      formatter.format( "<key>%n%s%n</key>%n", entry.getKey() );
      formatter.format( "<value>%n%s%n</value>%n", entry.getValue() );
    }
    formatter.format( "</checkBoxes>%n" );

    formatter.format( "<listBox type='List&lt;ListItem&gt;'>%n" );
    for ( ListItem entry : listBox )
    {
      formatter.format( "<entry>%n%s%n</entry>%n", entry );
    }
    formatter.format( "</listBox>%n" );

    formatter.format( "<selectField type='List&lt;ListItem&gt;'>%n" );
    for ( ListItem entry : selectField )
    {
      formatter.format( "<entry>%n%s%n</entry>%n", entry );
    }
    formatter.format( "</selectField>%n" );

    formatter.format( "<textArea type='String'>%n" );
    formatter.format( "%s%n", textArea );
    formatter.format( "</textArea>%n" );

    formatter.format( "<textField type='String'>%n" );
    formatter.format( "%s%n", textField );
    formatter.format( "</textField>%n" );

    formatter.format( "</InputFormModel>%n" );
    return builder.toString();
  }
  /**
   * Compare the specified object with this object for equality.
   * Returns <code>true</code> if the specified object is of the
   * same type as this  object, and the values of the fields
   * are equal.
   *
   * @param object The object that is to compared with this object.
   * @return boolean Returns <code>true</code> if the values of
   *   the class fields are the same.
   */
  @Override
  public boolean equals( Object object )
  {
    if ( this == object ) return true;

    boolean value = false;
    if ( ( object != null ) &&
        ( getClass() == object.getClass() ) )
    {
      InputFormModel obj = (InputFormModel) object;

      value = ( hashCode() == obj.hashCode() );
      value = value &&  ( ( checkBoxes == obj.checkBoxes ) ||
          ( checkBoxes != null &&
            checkBoxes.equals( obj.checkBoxes ) ) );
      value = value &&  ( ( listBox == obj.listBox ) ||
          ( listBox != null &&
            listBox.equals( obj.listBox ) ) );
      value = value &&  ( ( selectField == obj.selectField ) ||
          ( selectField != null &&
            selectField.equals( obj.selectField ) ) );
      value = value &&  ( ( textArea == obj.textArea ) ||
          ( textArea != null &&
            textArea.equals( obj.textArea ) ) );
      value = value &&  ( ( textField == obj.textField ) ||
          ( textField != null &&
            textField.equals( obj.textField ) ) );
    }

    return value;
  }
  /**
   * Return a hash code for this object.  Returns a hash code
   * computed from the class fields.
   *
   * @return int The hashCode value.
   */
  @Override
  public int hashCode()
  {
    if ( hash == HASH )
    {
      hash = ( 31 * hash ) +
        ( ( checkBoxes == null ) ? 0 : checkBoxes.hashCode() );
      hash = ( 31 * hash ) +
        ( ( listBox == null ) ? 0 : listBox.hashCode() );
      hash = ( 31 * hash ) +
        ( ( selectField == null ) ? 0 : selectField.hashCode() );
      hash = ( 31 * hash ) +
        ( ( textArea == null ) ? 0 : textArea.hashCode() );
      hash = ( 31 * hash ) +
        ( ( textField == null ) ? 0 : textField.hashCode() );
    }

    return hash;
  }

  /**
   * Implementation of the <code>Comparable</code> interface.
   * Compares this object with the specified object for order. Returns
   * a negative integer, zero, or a positive integer as this object is
   * less than, equal to, or greater than the specified object.
   * The comparison is done by comparing the {@link #hashCode()} values
   * of the objects.
   *
   * @param object - The object with which this class is to
   *   be compared.  No class type checking is done.
   * @return int - A negative integer, zero, or a positive integer as
   *   this object is less than, equal to, or greater than the
   *   specified object.
   */
  public int compareTo( InputFormModel object )
  {
    return ( this.hashCode() - object.hashCode() );
  }

  /**
   * Creates and returns a copy of this object.  Implementation of
   * the <code>Cloneable</code> interface.  No special actions are
   * performed.  This method simply allows public access to the
   * <code>Object.clone</code> method.
   *
   * @return Object A clone of this instance.
   * @throws CloneNotSupportedException If the super-class implementation
   *   throws an error.
   */
  @Override
  public Object clone() throws CloneNotSupportedException
  {
    return super.clone();
  }

  /**
   * Adds a property change listener to this <code>bean</code>.
   * Delegates handling to {@link #propertyChangeSupport}
   *
   * @param listener The listener to add.
   */
  public void addPropertyChangeListener( PropertyChangeListener listener )
  {
    if ( propertyChangeSupport == null )
    {
      propertyChangeSupport = new PropertyChangeSupport( this );
    }

    propertyChangeSupport.addPropertyChangeListener( listener );
  }

  /**
   * Removes a property change listener from this <code>bean</code>.
   * Delegates handling to {@link #propertyChangeSupport}
   *
   * @param listener The listener to be removed.
   */
  public void removePropertyChangeListener(
      PropertyChangeListener listener )
  {
    if ( propertyChangeSupport != null )
    {
      propertyChangeSupport.removePropertyChangeListener( listener );
    }
  }

  /**
   * Reports a bound property change to the registerd
   * <code>PropertyChangeListener</code>s.
   * Delegates handling to {@link #propertyChangeSupport}
   *
   * @param propertyName The name of the changed property.
   * @param oldValue The previous value of the property.
   * @param newValue The present value of the property.
   */
  protected void firePropertyChange( String propertyName,
      Object oldValue, Object newValue )
  {
    if ( propertyChangeSupport != null )
    {
      propertyChangeSupport.firePropertyChange(
          propertyName, oldValue, newValue );
    }
  }


  /**
   * Returns the value of {@link #checkBoxes}.
   *
   * @return Map<String, Boolean> The value of checkBoxes.
   */
  public final Map<String, Boolean> getCheckBoxes()
  {
    return checkBoxes;
  }

  /**
   * Sets the value of {@link #checkBoxes}.  Resets {@link #hash}.
   *
   * @param checkBoxes The value to set.
   */
  public final void setCheckBoxes( Map<String, Boolean> checkBoxes )
  {
    Map<String, Boolean> oldValue = this.checkBoxes;
    this.checkBoxes = checkBoxes;
    hash = HASH;
    firePropertyChange( "checkBoxes", oldValue, checkBoxes );
  }

  /**
   * Returns the value of {@link #listBox}.
   *
   * @return List<ListItem> The value of listBox.
   */
  public final List<ListItem> getListBox()
  {
    return listBox;
  }

  /**
   * Sets the value of {@link #listBox}.  Resets {@link #hash}.
   *
   * @param listBox The value to set.
   */
  public final void setListBox( List<ListItem> listBox )
  {
    List<ListItem> oldValue = this.listBox;
    this.listBox = listBox;
    hash = HASH;
    firePropertyChange( "listBox", oldValue, listBox );
  }

  /**
   * Returns the value of {@link #selectField}.
   *
   * @return List<ListItem> The value of selectField.
   */
  public final List<ListItem> getSelectField()
  {
    return selectField;
  }

  /**
   * Sets the value of {@link #selectField}.  Resets {@link #hash}.
   *
   * @param selectField The value to set.
   */
  public final void setSelectField( List<ListItem> selectField )
  {
    List<ListItem> oldValue = this.selectField;
    this.selectField = selectField;
    hash = HASH;
    firePropertyChange( "selectField", oldValue, selectField );
  }

  /**
   * Returns the value of {@link #textArea}.
   *
   * @return String The value of textArea.
   */
  public final String getTextArea()
  {
    return textArea;
  }

  /**
   * Sets the value of {@link #textArea}.  Resets {@link #hash}.
   *
   * @param textArea The value to set.
   */
  public final void setTextArea( String textArea )
  {
    String oldValue = this.textArea;
    this.textArea = textArea;
    hash = HASH;
    firePropertyChange( "textArea", oldValue, textArea );
  }

  /**
   * Returns the value of {@link #textField}.
   *
   * @return String The value of textField.
   */
  public final String getTextField()
  {
    return textField;
  }

  /**
   * Sets the value of {@link #textField}.  Resets {@link #hash}.
   *
   * @param textField The value to set.
   */
  public final void setTextField( String textField )
  {
    String oldValue = this.textField;
    this.textField = textField;
    hash = HASH;
    firePropertyChange( "textField", oldValue, textField );
  }

  /**
   * Called after the values are loaded from the
   * data store into this instance.
   * InstanceCallbacks method implementation.  No actions required
   * by default.
   */
  public void jdoPostLoad() {}

  /**
   * Called before the values are stored from this instance
   * to the data store.
   * InstanceCallbacks method implementation.
   * Pre-calculate {@link #hash} using {@link #hashCode}.
   */
  public void jdoPreStore()
  {
    hash = hashCode();
  }

  /**
   * Called before the values in the instance are cleared.
   * InstanceCallbacks method implementation.  No actions required
   * by default.
   */
  public void jdoPreClear() {}

  /**
   * Called before the instance is deleted.
   * InstanceCallbacks method implementation.  No actions required
   * by default.
   */
  public void jdoPreDelete() {}
}
