package sale;

import java.io.Serializable;
import java.io.IOException;

import log.*;
import users.*;

import data.Stock;
import data.Catalog;

/**
  * A context that allows processes to run and access certain functionality.
  *
  * <p>A ProcessContext provides {@link SaleProcess processes} with an environment in which they
  * can work. Although some of the functionality could be accessed directly at the {@link Shop},
  * some can't, and for the rest the usage of ProcessContexts provides an extra level of flexibility.
  * It is therefore explicitly recommended that your processes access all of the needed functionality
  * through their context, except in cases where you want to make sure that a special service is
  * carried out at Shop level.</p>
  *
  * <p>The methods comprising the ProcessContext interface fall into three categories:</p>
  *
  * <ol>
  *   <li>Display related methods:
  *     <ul>
  *       <li>{@link #setFormSheet}</li>
  *       <li>{@link #popUpFormSheet}</li>
  *       <li>{@link #setMenuSheet}</li>
  *       <li>{@link #hasUseableDisplay}</li>
  *     </ul>
  *   </li>
  *   <li>Data and service related methods:
  *     <ul>
  *       <li>{@link #log}</li>
  *       <li>{@link #getCurrentUser}</li>
  *       <li>{@link #getStock}</li>
  *       <li>{@link #getCatalog}</li>
  *     </ul>
  *   </li>
  *   <li>Process management methods:
  *     <ul>
  *       <li>{@link #processStarted}</li>
  *       <li>{@link #processFinished}</li>
  *     </ul>
  *     These methods will not be called directly, but rather the Framework will call them as
  *     appropriate.
  *   </li>
  * </ol>
  *
  * @author Steffen Zschaler
  * @version 2.0 27/05/1999
  * @since v2.0
  */
public interface ProcessContext extends Serializable {

  // display related methods

  /**
    * Set a FormSheet for a process.
    *
    * <p>The FormSheet will be displayed on the ProcessContext's display for the given process, if there
    * is one and it is useable. Setting a <code>null</code> FormSheet will remove any FormSheet
    * currently being displayed.</p>
    *
    * @override Always
    *
    * @param p the process that wishes to set a FormSheet
    * @param fs the FormSheet that is to be set.
    *
    * @exception InterruptedException if an interrupt occurred while waiting for the FormSheet to be
    * closed. See {@link Display#setFormSheet Display.setFormSheet} for details.
    *
    * @see Display#setFormSheet
    */
  public void setFormSheet (SaleProcess p, FormSheet fs)
    throws InterruptedException;

  /**
    * Pop up a FormSheet for a process.
    *
    * <p>The FormSheet will be popped up on the ProcessContext's display for the given process, if there
    * is one and it is useable.</p>
    *
    * @override Always
    *
    * @param p the process that wishes to pop up a FormSheet
    * @param fs the FormSheet that is to be set.
    *
    * @exception InterruptedException if an interrupt occurred while waiting for the FormSheet to be
    * closed. See {@link Display#popUpFormSheet Display.popUpFormSheet} for details.
    *
    * @see Display#popUpFormSheet
    */
  public void popUpFormSheet (SaleProcess p, FormSheet fs)
    throws InterruptedException;

  /**
    * Set a MenuSheet for a process.
    *
    * <p>The MenuSheet will be displayed on the ProcessContext's display for the given process, if there
    * is one and it is useable. Setting a <code>null</code> MenuSheet will remove any MenuSheet
    * currently being displayed.</p>
    *
    * @override Always
    *
    * @param p the process that wishes to set a MenuSheet
    * @param ms the MenuSheet that is to be set.
    *
    * @see Display#setMenuSheet
    */
  public void setMenuSheet (SaleProcess p, MenuSheet ms);

  /**
    * True if the ProcessContext has a useable display for the given process.
    *
    * @override Always
    *
    * @param p the process whose display is to be checked.
    *
    * @see Display#isUseableDisplay
    */
  public boolean hasUseableDisplay (SaleProcess p);

  // data and service related methods

  /**
    * Put an entry into the ProcessContext's log stream for a process.
    *
    * @override Always
    *
    * @param p the process that wishes to put data into the log stream.
    * @param la the information that is to be logged.
    *
    * @exception IOException if any problems occurred while writing to the log stream.
    */
  public void log (SaleProcess p, Loggable la)
    throws IOException;

  /**
    * Get the user currently associated with the given process.
    *
    * @override Always
    *
    * @param p the process that wishes to know its current user.
    *
    * @return the current user for the given process.
    */
  public User getCurrentUser (SaleProcess p);

  /**
    * Get a Stock by its name.
    *
    * <p>The Stock's name is resolved relative to the ProcessContext, so that the same call can result
    * in different Stocks in different ProcessContexts.</p>
    *
    * @override Always
    *
    * @param sName the name of the Stock to be returned.
    *
    * @return the Stock that was found for the given name, if any.
    */
  public Stock getStock (String sName);

  /**
    * Get a Catalog by its name.
    *
    * <p>The Catalog's name is resolved relative to the ProcessContext, so that the same call can result
    * in different Catalogs in different ProcessContexts.</p>
    *
    * @override Always
    *
    * @param sName the name of the Catalog to be returned.
    *
    * @return the Catalog that was found for the given name, if any.
    */
  public Catalog getCatalog (String sName);

  // process management methods

  /**
    * Notification that a process was started in this ProcessContext.
    *
    * <p>This method is usually not called directly, but rather the Framework calls it as appropriate.</p>
    *
    * @override Always
    *
    * @param p the process that was started.
    */
  public void processStarted (SaleProcess p);

  /**
    * Notification that a process was finished in this ProcessContext.
    *
    * <p>This method is usually not called directly, but rather the Framework calls it as appropriate.</p>
    *
    * @override Always
    *
    * @param p the process that was finished.
    */
  public void processFinished (SaleProcess p);
}