package sale;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

/**
  * A special ActionListener that allows to associate Actions with buttons that are not
  * in a FormSheet's button bar or a MenuSheet.
  *
  * <p>You can use subclasses of this class as ActionListeners on any button in a FormSheet
  * that is not in the button bar. You can then think of it as of an {@link Action}
  * associated with that button. The {@link #doAction} method will be called with the same
  * parameters as for an Action associated with a button in the FormSheet's button bar.</p>
  *
  * <p>If you do not override {@link #doAction} in subclasses, it will defer event handling
  * to the Action object handed in on creation. Thus, you can create chains of responsibility
  * which allow for, e.g., a {@link users.Capability capability} to be associated with any
  * {@link java.awt.event.ActionEvent} in the FormSheet.</p>
  *
  * @see FormSheet
  *
  * @author Steffen Zschaler
  * @version 2.0 07/06/1999
  * @since v2.0
  */
public class ActionActionListener extends Object implements Action, ActionListener {

  /**
    * The FormSheet that contains this Action's button.
    *
    * @serial
    */
  protected FormSheet m_fsOwner;

  /**
    * The action to be performed, when the listener is triggered.
    *
    * @serial
    */
  protected Action m_aAction;

  /**
    * Create a new ActionActionListener. You must override {@link #doAction} when using this constructor.
    *
    * @param fsOwner the FormSheet that contains this Action's button.
    */
  public ActionActionListener (FormSheet fsOwner) {
    this (fsOwner, null);
  }

  /**
    * Create a new ActionActionListener. You should not override {@link #doAction} when using this constructor.
    *
    * @param fsOwner the FormSheet that contains this Action's button.
    * @param aAction the Action to perform when the listener is triggered.
    */
  public ActionActionListener (FormSheet fsOwner,
                               Action aAction) {
    super();

    m_fsOwner = fsOwner;
    m_aAction = aAction;
  }

  /**
    * ActionListener interface method. Will redirect the event to the {@link #doAction}
    * method.
    *
    * @override Never
    */
  public final void actionPerformed (ActionEvent e) {
    new Thread ("ActionActionListener event handler") {
      public void run() {
        try {
          doAction (m_fsOwner.getProcess(), m_fsOwner.getSalesPoint());
        }
        catch (ThreadDeath td) { throw td; }
        catch (Throwable t) {
          System.err.println ("Exception occured during event handling:");
          t.printStackTrace();
        }
      }
    }.start();
  }

  /**
    * Action interface method. Unless you override it, it will redirect the event to the
    * {@link Action#doAction doAction()} method of the Action that is associated with this
    * listener.
    *
    * @override Sometimes Override this method when you used
    * {@link #ActionActionListener(sale.FormSheet)} as a constructor and want the listener to be the
     *{@link Action Action object} at the same time.
    *
    * @exception Throwable on any error that shall be reported and lead to cancellation of
    * the action.
    *
    * @see #ActionActionListener(sale.FormSheet, sale.Action)
    */
  public void doAction (SaleProcess p, SalesPoint sp) throws Throwable {
    m_aAction.doAction (p, sp);
  }
}