package data.ooimpl;

import data.*;

import java.beans.*;

/**
  * Pure Java implementation of the {@link CatalogItem} interface. See the documentation for
  * {@link CatalogItem} for a description of the semantics of this class.
  *
  * @author Steffen Zschaler
  * @version 2.0 19/08/1999
  * @since v2.0
  */
public abstract class CatalogItemImpl extends AbstractNameable implements CatalogItem, DataBasketKeys {

  /**
    * The Catalog that owns this CatalogItem, if any.
    *
    * @serial
    */
  private CatalogImpl m_ciOwner;

  /**
    * The value of this CatalogItem.
    *
    * @serial
    */
  private Value m_vValue;

  /**
    * Create a new CatalogItemImpl. The item's value defaults to an {@link IntegerValue} of 0.
    *
    * @param sName the name of the new item.
    */
  public CatalogItemImpl (String sName) {
    this (sName, new IntegerValue (0));
  }

  /**
    * Create a new CatalogItemImpl.
    *
    * @param sName the name of the new item.
    * @param vValue the value of the item.
    */
  public CatalogItemImpl (String sName,
                          Value vValue) {
    super (sName);

    m_vValue = vValue;
  }

  /**
    * Get the item's value.
    *
    * @override Never
    *
    * @return a clone of the item's value.
    */
  public Value getValue() {
    return (Value) m_vValue.clone();
  }

  /**
    * Set the item's value. This method is protected so that subclasses can decide whether or not to allow
    * clients to set the value of a CatalogItem once it has been created.
    *
    * <p>The method will fire a property change event for the &quot;value&quot; property.</p>
    *
    * @override Sometimes
    */
  protected void setValue (Value vNew) {
    Value v = m_vValue;

    m_vValue = vNew;

    m_pcsPropertyListeners.firePropertyChange (VALUE_PROPERTY, v, m_vValue);
  }

  /**
    * Return true if this CatalogItem is editable.
    *
    * @override Never
    */
  public boolean isEditable() {
    return ((getCatalog() == null) ||
            (((CatalogImpl) getCatalog()).getEditingItemsContainer().get (getName()) == this));
  }

  /**
    * Get the Catalog of this CatalogItem.
    *
    * @override Never
    */
  public Catalog getCatalog() {
    return m_ciOwner;
  }

  /**
    * Set the Catalog of this CatalogItem. Used internally only.
    *
    * @override Never
    */
  void setCatalog (CatalogImpl ci) {
    m_ciOwner = ci;
    attach (ci);
  }

  /**
    * Return a String representation of the item.
    *
    * @override Sometimes
    */
  public String toString() {
    return "Abstract CatalogItem \"" + getName() + "\"";
  }

  /**
    * Get a shallow clone of the CatalogItem. For normal CatalogItem's there is no difference between a shallow
    * and a deep clone.
    *
    * @override Always
    */
  protected abstract CatalogItemImpl getShallowClone();

  /**
    * Compare this CatalogItem to an object.
    *
    * @override Sometimes The default implementation assumes that the given object is also a CatalogItem and
    * compares the {@link #getValue values} of these two CatalogItems.
    *
    * @exception ClassCastException if the given object cannot be cast into a CatalogItem.
    */
  public int compareTo (Object o) {
    return getValue().compareTo (((CatalogItem) o).getValue());
  }

  /**
    * Check whether two objects are equal.
    *
    * @override Sometimes The default implementation returns true iff <code>o</code> is identical to this
    * object.
    */
  public boolean equals (Object o) {
    return (this == o);
  }

  /**
    * Add a PropertyChangeListener that will receive events whenever the &quot;value&quot; property changes.
    *
    * @override Never
    */
  public void addValueListener (PropertyChangeListener pcl) {
    m_pcsPropertyListeners.addPropertyChangeListener (VALUE_PROPERTY, pcl);
  }

  /**
    * Remove a PropertyChangeListener for the &quot;value&quot; property.
    *
    * @override Never
    */
  public void removeValueListener (PropertyChangeListener pcl) {
    m_pcsPropertyListeners.removePropertyChangeListener (VALUE_PROPERTY, pcl);
  }
}