package com.sptci.echo2;

import java.io.Serializable;
import java.util.Formatter;

/**
 * A simple bean that represents an item that can be added to a
 * <code>ListModel</code>.
 *
 * <p>Copyright 2006 Sans Pareil Technologies, Inc.</p>
 * @author Rakesh Vidyadharan 2006-01-31
 * @version $Id: ListItem.java,v 1.3 2006/02/09 16:15:37 rakesh Exp $
 */
public class ListItem 
  implements Serializable, Comparable<ListItem>, Cloneable
{
  /**
   * The item or value stored in the list.
   */
  protected String value;

  /**
   * A flag indicating whether the {@link #value} is selected or not.
   */
  protected boolean selected;

  /**
   * Default constructor.  Cannot be initialised.
   */
  protected ListItem() {}

  /**
   * Create a new instance of the bean using the specified object.
   * Set the {@link #selected} to <code>false</code> for the
   * specified object.
   *
   * @param value The {@link #value} to set.
   */
  public ListItem( String value )
  {
    this( value, false );
  }

  /**
   * Designated constructor.  Create a new bean using the specified
   * values.
   *
   * @param value The {@link #value} to set.
   * @param selected The {@link #selected} value to set.
   */
  public ListItem( String value, boolean selected )
  {
    this();
    setValue( value );
    setSelected( selected );
  }

  /**
   * Return a string representation of this object.
   *
   * @return String The string representation of the fields of the
   *   object.
   */
  @Override
  public String toString()
  {
    StringBuilder builder = new StringBuilder( 256 );
    Formatter formatter = new Formatter( builder );
    formatter.format( "%s value: {%s} selected: {%s}%n",
        getClass().getName(), value, selected );
    return builder.toString();
  }

  /**
   * Check the specified object with this object for equality.
   *
   * @param object The object that is to be checked for equality with.
   * @return boolean Returns <code>true</code> if the object is of the
   *   same type as this object and has the same field values.
   */
  @Override
  public boolean equals( Object object )
  {
    if ( this == object ) return true;

    boolean result = false;
    if ( object != null && object.getClass() == getClass() )
    {
      ListItem item = (ListItem) object;
      result = ( selected == item.selected );
      result = result && ( ( value == item.value ) ||
          ( ( value != null ) && value.equals( item.value ) ) );
    }

    return result;
  }

  /**
   * Return a hash code value for this object.
   *
   * @return int The hash code value.
   */
  @Override
  public int hashCode()
  {
    int hash = 7;
    hash = ( 31 * hash ) + ( ( value == null ) ? 0 : value.hashCode() );
    hash = ( 31 * hash ) + ( ( selected ) ? 1 : 0 );
    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 item - The object with which this class is to
   *   be compared.
   * @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( ListItem item )
  {
    return ( this.hashCode() - item.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();
  }
  
  /**
   * Returns {@link #value}.
   *
   * @return String The value/reference of/to value.
   */
  public final String getValue()
  {
    return value;
  }
  
  /**
   * Set {@link #value}.
   *
   * @param value The value to set.
   */
  public void setValue( String value )
  {
    this.value = value;
  }
  
  /**
   * Returns {@link #selected}.
   *
   * @return boolean The value/reference of/to selected.
   */
  public final boolean getSelected()
  {
    return selected;
  }
  
  /**
   * Returns the status of {@link #selected}.
   *
   * @return boolean The value/reference of/to selected.
   */
  public final boolean isSelected()
  {
    return getSelected();
  }
  
  /**
   * Set {@link #selected}.
   *
   * @param selected The value to set.
   */
  public void setSelected( boolean selected )
  {
    this.selected = selected;
  }
}
