package data.stdforms.singletableformsheet;

import sale.*;
import sale.stdforms.*;

import data.*;
import data.stdforms.*;

import users.*;

/**
  * Strategy that can be associated to the "Remove" button of a SingleTableFormSheet that displays
  * the contents of a Catalog.
  *
  * @author Steffen Zschaler
  * @version 2.0 20/08/1999
  * @since v2.0
  */
public class DefaultRemoveCatalogItemStrategy extends EditButtonStrategy {

  /**
    * The Catalog that is being edited.
    *
    * @serial
    */
  protected Catalog m_cCatalog;

  /**
    * Create a new DefaultRemoveCatalogItemStrategy.
    *
    * @param c the Catalog to be edited. Must be the same that is displayed by the {@link SingleTableFormSheet}.
    */
  public DefaultRemoveCatalogItemStrategy (Catalog c) {
    super();

    m_cCatalog = c;
  }

  /**
    * @override Never
    */
  public Transition getEditProcess (SingleTableFormSheet stfs,
                                    SaleProcess p,
                                    SalesPoint sp) {
    return new GateChangeTransition (getCheckGate (stfs));
  }

  /**
    * Get the Gate that checks whether the removal is allowed. If this is the case, the Gate must be left
    * through {@link #getRemoveTransition}, otherwise, a transition to the
    * {@link SingleTableFormSheet#getGate SingleTableFormSheet's gate} should be triggered.
    *
    * @override Sometimes The default implementation puts up a MsgForm asking for the user to confirm the
    * removal. Caption and text of the message are obtained via {@link #getConfirmationCaption} and
    * {@link #getConfirmationText}, resp.
    *
    * @param stfs the FormSheet that triggered the operation.
    */
  protected Gate getCheckGate (final SingleTableFormSheet stfs) {
    CatalogItem ci = (CatalogItem) stfs.getSelectedRecord();
    FormSheet fs = new MsgForm (getConfirmationCaption (stfs, ci),
                                getConfirmationText (stfs, ci));

    final UIGate uigCheckGate = new UIGate (fs, null);

    fs.addContentCreator (new FormSheetContentCreator() {
      protected void createFormSheetContent (FormSheet fs) {
        fs.removeAllButtons();

        fs.addButton ("Yes", FormSheet.BTNID_OK, new Action() {
          public void doAction (SaleProcess p, SalesPoint sp) {
            uigCheckGate.setNextTransition (getRemoveTransition (stfs));
          }
        });

        fs.addButton ("No", FormSheet.BTNID_CANCEL, new Action() {
          public void doAction (SaleProcess p, SalesPoint sp) {
            uigCheckGate.setNextTransition (new GateChangeTransition (stfs.getGate()));
          }
        });
      }
    });

    return uigCheckGate;
  }

  /**
    * Get the caption for the default confirmation {@link MsgForm}.
    *
    * @param stfs the FormSheet that triggered the operation.
    * @param ci the CatalogItem that is going to be removed.
    *
    * @override Sometimes The default implementation returns
    * <code>(stfs.getCaption() + " - Confirmation")</code>.
    */
  protected String getConfirmationCaption (SingleTableFormSheet stfs,
                                           CatalogItem ci) {
    return (stfs.getCaption() + " - Confirmation");
  }

  /**
    * Get the text for the default confirmation {@link MsgForm}.
    *
    * @param stfs the FormSheet that triggered the operation.
    * @param ci the CatalogItem that is going to be removed.
    *
    * @override Sometimes The default implementation returns
    * <code>("Are you sure, you want to remove \"" + ci.getName() + "\"?")</code>.
    */
  protected String getConfirmationText (SingleTableFormSheet stfs,
                                        CatalogItem ci) {
    return ("Are you sure, you want to remove \"" + ci.getName() + "\"?");
  }

  /**
    * Get the transition that performs the actual removal. This basically calls {@link #doRemove}.
    *
    * @param stfs the FormSheet that triggered the operation.
    *
    * @override Never Instead, override {@link #doRemove}.
    */
  protected Transition getRemoveTransition (final SingleTableFormSheet stfs) {
    return new Transition() {
      public Gate perform (SaleProcess p, User u) {
        doRemove (p, (CatalogItem) stfs.getSelectedRecord(), p.getBasket());

        return stfs.getGate();
      }
    };
  }

  /**
    * Perform the actual removal.
    *
    * <p>Any error condition should be passed on to {@link FormSheetStrategy#error} in
    * {@link FormSheetStrategy}.</p>
    *
    * @override Sometimes
    *
    * @param p the process in which this sub-process will be implanted.
    * @param ci the CatalogItem to be removed. Can be <code>null</code>.
    * @param db the DataBasket relative to which to perform the operation.
    */
  protected void doRemove (SaleProcess p, CatalogItem ci, DataBasket db) {
    if (ci != null) {
      try {
        m_cCatalog.remove (ci, db);
      }
      catch (data.events.VetoException ve) {
        error (p, REMOVE_VETO_EXCEPTION);
      }
    }
  }
}