/*
 * Licensed Materials - Property of Rogue Wave Software, Inc. 
 * © Copyright Rogue Wave Software, Inc. 2014, 2015 
 * © 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 ilog.tgo.IltSystem;
import ilog.tgo.faces.equipment.component.IltFacesEquipmentView;
import ilog.tgo.faces.network.component.IltFacesNetworkView;
import ilog.tgo.faces.service.IltFacesDefaultContext;
import ilog.tgo.model.IltLink;
import ilog.tgo.model.IltNetworkElement;
import ilog.tgo.resource.IltSettings;

import ilog.cpl.IlpEquipment;
import ilog.cpl.IlpNetwork;
import ilog.cpl.datasource.IlpDefaultDataSource;
import ilog.cpl.model.IlpClass;
import ilog.cpl.service.IlpContext;
import ilog.cpl.service.IlpDefaultContext;

import ilog.views.faces.IlvFacesPageIdUtil;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Logger;

import javax.faces.context.FacesContext;

/**
 * <p>This is the context object that provides the objects needed for this 
 * sample to function properly. It is the place where the initialization
 * of such objects should be handled.</p>
 * 
 * <p>In order to provide multiple browser pages, some objects must be
 * uniquely associated with one browser page alone (page-specific context).
 * These objects are:</p>
 * <ul>
 *   <li><code>IlpDataSource</code></li>
 *   <li><code>IlpNetwork</code></li>
 *   <li><code>IlpEquipment</code></li>
 * </ul>
 * <p>All other objects can be shared between multiple browser pages.</p>
 */
public class SampleContext {

  /**
   * The default deployment file.
   */
  private static String DEPLOYMENT_FILE = "resources/configuration/deployment/deploy.xml";  

  /**
   * Styles for the equipment component.
   */
  private static String EQUIPMENT_STYLES = "equipment.css";

  /**
   * Styles for the network component.
   */
  private static String NETWORK_STYLES = "network.css";

  /**
   * The network data.
   */
  private static String NETWORK_DATA_FILE = "network.xml";

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

  /**
   * Support for logging error messages.
   */
  public Logger logger;

  /**
   * Constructor.
   * Creates the TGO context and initializes it.
   */
  public SampleContext() {
    // 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
      logger = createLogger("integration.equipment.viewer");

      //Initialize the TGO runtime
      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(DEPLOYMENT_FILE);
      }

      //Initialize sample
      initializeSample();
    }
  }

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

  //////////////////////////////////////////////////////////////////////////////
  //Objects Accessors
  //////////////////////////////////////////////////////////////////////////////
  /**
   * Sets the IlpContext being used by the sample.
   */
  public IlpContext getContext() {
    return context;
  }
  
  /**
   * Returns the IlpDefaultDataSource that is used by the sample.
   */
  private IlpDefaultDataSource getDataSource() {
    // Tries to retrieve the Data Source from the
    // session, based on the page identifier
    IlpDefaultDataSource datasource = (IlpDefaultDataSource)IlvFacesPageIdUtil.getSessionAttributeWithPageId("datasource");
    if (null == datasource) {
      // Data Source has not been created yet. Create it now.
      datasource = createDataSource();
      IlvFacesPageIdUtil.setSessionAttributeWithPageId("datasource", datasource);
    }
    return datasource;
  }
  
  /**
   * Returns the IlpNetwork that is used by the sample.
   */
  public IlpNetwork getNetwork() {
    // Tries to retrieve the Network component from the
    // session, based on the page identifier
    IlpNetwork network = (IlpNetwork)IlvFacesPageIdUtil.getSessionAttributeWithPageId("network");
    if (null == network) {
      // Network component has not been created yet. Create it now.
      network = createNetwork();
      IlvFacesPageIdUtil.setSessionAttributeWithPageId("network", network);
    }
    return network;
  }

  /**
   * Returns the IlpEquipment that is used by the sample.
   */
  public IlpEquipment getEquipment() {
    // Tries to retrieve the Equipment component from the
    // session, based on the page identifier
    IlpEquipment equipment = (IlpEquipment)IlvFacesPageIdUtil.getSessionAttributeWithPageId("equipment");
    if (null == equipment) {
      // Equipment component has not been created yet. Create it now.
      equipment = createEquipment();
      IlvFacesPageIdUtil.setSessionAttributeWithPageId("equipment", equipment);
    }
    return equipment;
  }

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

  //////////////////////////////////////////////////////////////////////////////
  //DataSource
  //////////////////////////////////////////////////////////////////////////////
  /**
   * Creates the IlpDefaultDataSource that will be used by the sample.
   */
  protected IlpDefaultDataSource createDataSource() {
    IlpDefaultDataSource dataSource = new IlpDefaultDataSource(getContext());
    dataSource.setFileName(NETWORK_DATA_FILE);
    return dataSource;
  }

  //////////////////////////////////////////////////////////////////////////////
  //Components
  //////////////////////////////////////////////////////////////////////////////
  /**
   * Creates the IlpNetwork that will be used by the sample.
   * Note that the default Faces configuration file is used.
   */
  protected IlpNetwork createNetwork() {

    // Get the default configuration file name
    String config = IltFacesNetworkView.DefaultConfigurationFileName;
    IlpNetwork network = new IlpNetwork(config, getContext());

    try {

      //Adjust the what types of objects can be viewed in the main view.
      //We only want to show IltNetworkElement and IltLink in the main view
      List<IlpClass> classes = new ArrayList<IlpClass>(2);
      classes.add(IltNetworkElement.GetIlpClass());
      classes.add(IltLink.GetIlpClass());
      network.getAdapter().setAcceptedClasses(classes);

      //Set styles...
      String[] styles = {NETWORK_STYLES};
      network.setStyleSheets(styles);

      //Share the in-memory datasource instance...
      network.setDataSource(getDataSource());

    } catch(Exception e) {
      logger.severe("Cannot set the setup the network component with this exception:\n"
                    + e.getLocalizedMessage());
    }

    return network;
  }

  /**
   * Creates the IlpEquipment that will be used by the sample.
   * Note that the default Faces configuration file is used.
   */
  protected IlpEquipment createEquipment() {

    // Get the default configuration file name
    String config = IltFacesEquipmentView.DefaultConfigurationFileName;
    IlpEquipment equipment = new IlpEquipment(config, getContext());
    
    try {
      //Configure the adapter to show no objects by default
      List<Object> empty = Collections.emptyList();
      equipment.getAdapter().setOrigins(empty, true);

      //Set styles...
      String[] styles = {EQUIPMENT_STYLES};
      equipment.setStyleSheets(styles);

      //Share the in-memory datasource instance...
      equipment.setDataSource(getDataSource());

    } catch(Exception e) {
      logger.severe("Cannot set the setup the equipment component with this exception:\n"
                    + e.getLocalizedMessage());
    }
    return equipment;
  }

  /**
   * Performs the sample initializations.
   */
  private void initializeSample() {

    //Initialize samples' custom types
    try {
      IltSettings settings = new IltSettings(getContext());
      String[] settingsArray = {"settings.css"};
      settings.setStyleSheets(settingsArray);
    } catch (Exception e) {
      logger.severe("Exception caught while loading sample settings:\n" + e.getLocalizedMessage());
    }
  }
}