/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
import java.util.logging.Logger;

import ilog.cpl.graphic.IlpGraphicComponent;
import ilog.cpl.service.IlpContext;
import ilog.cpl.service.IlpDefaultContext;
import ilog.tgo.IltSystem;
import ilog.tgo.faces.service.IltFacesDefaultContext;

/**
 * Context object used to maintain references to objects that are needed by the
 * sample. It also triggers the sample initialization process.
 */
abstract public class AbstractSampleContext {

  /**
   * The sample's component.
   */
  protected IlpGraphicComponent component;

  /**
   * The sample's TGO context.
   */
  protected IlpContext context;

  /**
   * The Logger for this sample.
   */
  public Logger logger;

  /**
   * Uses the default deployment file location:
   * <code>resources/configuration/deployment/deploy.xml</code>, then uses the
   * two String argument constructor.
   */
  public AbstractSampleContext(String loggerName) {
    this("resources/configuration/deployment/deploy.xml", loggerName);
  }

  /**
   * Performs the followings tasks in the following order:
   * <ol>
   * <li>Create the context
   * <li>Initializes the context with the provided deployment file
   * <li>Initializes the sample's Logger
   * <li>Initializes the sample
   * <li>Creates the component
   * </ol>
   */
  public AbstractSampleContext(String deploymentFile, String loggerName) {
    // Make sure this method is thread safe. TGO initialization in Web
    // Applications must happen in thread-safe environments to prevent two
    // distinct clients trying to initialize the static resources at the
    // same time
    synchronized (IltFacesDefaultContext.class) {
      // Initialize logger for this sample
      this.logger = createLogger(loggerName);

      // Initialize TGO
      try {
        IltSystem.Init();
      } catch (Exception e) {
        logger.severe("Could not initialize TGO with this exception: " + e.getLocalizedMessage());
      }

      // Create the context
      context = createContext();

      // Initialize the context
      if (context instanceof IlpDefaultContext) {
        ((IlpDefaultContext) context).setDeploymentFile(deploymentFile);
      }

      // Initialize sample
      initializeSample();

      // Create the component
      component = createComponent();
    }
  }

  /**
   * Creates a logger to be used in this sample
   * 
   * @param name
   *          Logger name
   * @return Logger instance
   * @see java.util.logging.Logger
   */
  protected Logger createLogger(String name) {
    return Logger.getLogger(name);
  }

  //////////////////////////////////////////////////////////////////////////////
  // Context Objects Accessors
  //////////////////////////////////////////////////////////////////////////////

  /**
   * Returns the IlpContext being used by the sample.
   */
  public IlpContext getContext() {
    return context;
  }

  /**
   * Returns the IlpGraphicComponent being used by the sample.
   */
  public IlpGraphicComponent getGraphicComponent() {
    return component;
  }

  //////////////////////////////////////////////////////////////////////////////
  // Sample Dependent
  //////////////////////////////////////////////////////////////////////////////

  /**
   * Should create the IlpContext that will be used by the sample. The default
   * implementation creates an instance of <code>IltFacesDefaultContext</code>.
   */
  protected IlpContext createContext() {
    return new IltFacesDefaultContext();
  }

  /**
   * Should create the <code>IlpGraphicComponent</code> that will be used by the
   * sample.
   */
  abstract protected IlpGraphicComponent createComponent();

  /**
   * Should initialize the sample by performing customizations, creating
   * business object or adjusting settings if needed.
   */
  abstract protected void initializeSample();

}