package data.ooimpl;

import data.*;

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

  /**
    * The {@link Stock} that contains this {@link StockItem}.
    *
    * @serial
    */
  private StockImpl m_stiOwner;

  /**
    * Create a new StockItemImpl.
    *
    * @param sName the name of the new item.
    */
  public StockItemImpl(String sName) {
    super (sName);
  }

  /**
    * Get the Stock that contains this StockItem.
    *
    * @override Never
    */
  public Stock getStock() {
    return m_stiOwner;
  }

  /**
    * Get the CatalogItem that is associated with this StockItem.
    *
    * <p>If the {@link StockItem} has a {@link #getStock Stock}, the associated {@link CatalogItem} is the
    * CatalogItem of the same name that is found in the Stock's {@link Stock#getCatalog associated Catalog}.
    * Otherwise, it is <code>null</code>.
    *
    * @param db the DataBasket used to determine visibility.
    *
    * @override Never
    */
  public CatalogItem getAssociatedItem (DataBasket db) {
    if (getStock() != null) {
      if (getStock().getCatalog (db) != null) {
        try {
          return getStock().getCatalog (db).get (getName(), db, false);
        }
        catch (data.events.VetoException ve) {}
      }
    }

    return null;
  }

  /**
    * Set the Stock that contains this StockItem.
    *
    * @override Never
    */
  protected void setStock (StockImpl sti) {
    m_stiOwner = sti;
    attach (sti); // as NameContext
  }

  /**
    * Clone this StockItem.
    *
    * @override Always
    */
  public Object clone() {
    return new StockItemImpl (getName());
  }

  /**
    * Get a shallow clone of this item.
    *
    * <p>For a normal item, shallow and deep clones are identical, which is why the default implementation
    * returns <code>((StockItemImpl) clone())</code>. However, when making a shallow clone of a Stock, the
    * individual StockItems will not be cloned.</p>
    *
    * @override Sometimes  The default implementation returns <code>(StockItemImpl) clone()</code>.
    */
  public StockItemImpl getShallowClone() {
    return (StockItemImpl) clone();
  }

  /**
    * Check whether this StockItem equals the given object.
    *
    * @override Sometimes The default implementation returns <code>(this == o)</code>.
    */
  public boolean equals (Object o) {
    return (this == o);
  }

  /**
    * Compare this StockItem to the given object.
    *
    * @override Sometimes The default implementation will assume <code>o</code> to be a StockItem and will
    * compare the names. Stocks, however, will always be greater than StockItems.
    *
    * @exception ClassCastException if the given object cannot be converted into a {@link StockItem}.
    */
  public int compareTo (Object o) {
    if ((o instanceof Stock) &&
        (!(this instanceof Stock))){
      return -1;
    }

    return getName().compareTo (((StockItem) o).getName());
  }

  /**
    * Internal communication method needed for referential integrity in StoringStocks.
    *
    * <p><strong>Attention</strong>: This method must not be called directly.</p>
    *
    * @override Never
    */
  void internalSetName (String sNewName) {
    // we need to trick the NameContext, because, normally, Stocks will not allow their members to change their
    // name.
    NameContext nc = detachNC();

    try {
      setName (sNewName, null);
    }
    catch (NameContextException nce) {}

    attach (nc);
  }

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

  /**
    * Helper method used to maintain StockImpl - CatalogImpl links in nested Stocks/Catalogs. For internal use only.
    *
    * @param db the DataBasket that protecting this activity.
    * @param nAction the action that occurred. Can be either {@link #COMMIT_ACTION}, {@link #ROLLBACK_ACTION},
    * {@link #STARTEDIT_ACTION}.
    */
  void relinkCatalog (DataBasket db, int nAction) {}
  static final int COMMIT_ACTION = 1;
  static final int ROLLBACK_ACTION = 2;
  static final int STARTEDIT_ACTION = 3;
}