/*
 * 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.
 */

package monitoring.web.controls;

import ilog.cpl.IlpEquipment;
import ilog.cpl.equipment.EquipmentSelectionEvent;
import ilog.cpl.equipment.EquipmentSelectionListener;
import ilog.cpl.service.IlpContext;
import ilog.tgo.faces.equipment.dhtml.component.IltFacesDHTMLEquipmentView;
import ilog.views.faces.dhtml.component.IlvFacesDHTMLOverview;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;

import javax.faces.context.FacesContext;

import monitoring.shared.LoggingUtils;
import monitoring.shared.drilldown.AbstractDrillDownManager;
import monitoring.web.AbstractSampleContext;
import monitoring.web.SampleConstants;
import monitoring.web.controls.configurator.EquipmentConfigurator;
import monitoring.web.controls.popup.InventoryContextualMenuFactory;
import monitoring.web.drilldown.EquipmentDrillDownManager;
import monitoring.web.utils.WebUtils;

import org.apache.myfaces.trinidad.component.core.layout.CorePanelGroupLayout;

import shared.ResourceUtils;

/**
 * Contains all the equipment related controls in the sample. 
 */
public class EquipmentControls {
  
  //Equipment controls
  private IltFacesDHTMLEquipmentView inventoryEquipmentView;
  private IlvFacesDHTMLOverview inventoryOverview;
  private CorePanelGroupLayout inventoryOverviewPanel;
  private EquipmentDrillDownManager equipmentDrillDownManager;
  private EquipmentConfigurator equipmentConfigurator;
  private InventoryContextualMenuFactory inventoryContextualMenuFactory;
  private EquipmentViewSelectionPropagator inventoryEquipmentViewSelectionPropagator;

  private String equipmentInventoryDisplayLabel;
  private InventoryDisplayLabelUpdater inventoryDisplayLabelUpdater;
  
  /**
   * Creates all the equipment related controls. 
   *
   */
  public EquipmentControls() {

    //Create the inventory equipment view
    inventoryEquipmentView = (IltFacesDHTMLEquipmentView) FacesContext
    .getCurrentInstance().getApplication().createComponent
    (IltFacesDHTMLEquipmentView.getComponentType());

    //This is so because at the time when the view is being created
    //in this sample, the ID of the created JSF component is not yet in synch
    //with the JSP page, so we need to specify it, to ensure that the framework
    //can properly find its components
    inventoryEquipmentView.setId(SampleConstants.INVENTORY_EQUIPMENT_COMPONENT_ID);

    //Initialize the selection propagator
    inventoryEquipmentViewSelectionPropagator = new EquipmentViewSelectionPropagator();

    //Create the equipment drill down manager
    equipmentDrillDownManager = new EquipmentDrillDownManager();

    //Create the equipment configuration loader 
    equipmentConfigurator = new EquipmentConfigurator(this);

    //Set the default stylesheets
    inventoryEquipmentView.setStyleSheets(SampleConstants.INVENTORY_EQUIPMENT_STYLESHEETS);

    //Create contextual menus
    inventoryContextualMenuFactory = new InventoryContextualMenuFactory();
    
    //Create the label updater
    inventoryDisplayLabelUpdater = new InventoryDisplayLabelUpdater();
    
  }

  //////////////////////////////////////////////////////////////////////////////
  //Initialization
  //////////////////////////////////////////////////////////////////////////////
  
  /**
   * Initializes the equipment related controls.
   */
  public void initialize(AbstractSampleContext sampleContext) {

    //1- Update the components with the proper TGO context
    IlpContext context = sampleContext.getTgoContext();

    //This is needed as the settings from the JSP tag have not yet been applied
    //to this faces component
    inventoryEquipmentView.setContext(context);

    //3- Configure the selection propagator for the inventory equipment
    inventoryEquipmentViewSelectionPropagator.setApplicationContext(sampleContext);

    IlpEquipment inventoryEquipment = null;

    try {
      inventoryEquipment = getInventoryEquipmentView().getEquipment();
    } catch (Exception e) {
      LoggingUtils.getSampleLogger().log(
          Level.SEVERE,
          "Could not find the Inventory Equipment View with this exception:"
          + e.getLocalizedMessage());
      e.printStackTrace();
    }

    //Install the propagator on the inventory equipment view 
    inventoryEquipment.getSelectionModel().addEquipmentSelectionListener(
        inventoryEquipmentViewSelectionPropagator);

    //4- Ensure that the proper startup configuration is loaded in the network 
    equipmentConfigurator.initialize();

    //5- Configure the equipment drill down manager

    //Set the sample context
    equipmentDrillDownManager.setSampleContext(sampleContext);

    //Set the component
    equipmentDrillDownManager.setComponent(inventoryEquipment);

    //Set the tree datasource 
    equipmentDrillDownManager.setTreeDataSource(sampleContext
        .getDataStructures().getDataSources().getInventoryDataSource());

    //Engage the configuration loader
    equipmentDrillDownManager.addPropertyChangeListener(
        AbstractDrillDownManager.CURRENT_ROOT, equipmentConfigurator);

    //The inventory equipment, shows nothing at startup
    equipmentDrillDownManager.clearEquipmentDetails();

    //6- Configure contextual menu
    inventoryContextualMenuFactory.initialize(sampleContext);
    inventoryContextualMenuFactory
    .setTargetFacesViewIdentifier(SampleConstants.INVENTORY_EQUIPMENT_COMPONENT_ID);
    
    //7- Configure and install listener to udpate the inventory label
    inventoryDisplayLabelUpdater.setApplicationContext(sampleContext);

    equipmentDrillDownManager.addPropertyChangeListener(
        AbstractDrillDownManager.CURRENT_ROOT, inventoryDisplayLabelUpdater);
    
    setEquipmentInventoryDisplayLabel(ResourceUtils.getString("labelInventoryRootLevel"));
  }

  //////////////////////////////////////////////////////////////////////////////
  //Accessors and Modifiers
  //////////////////////////////////////////////////////////////////////////////

  public IltFacesDHTMLEquipmentView getInventoryEquipmentView() {
    return inventoryEquipmentView;
  }
  public void setInventoryEquipmentView(
      IltFacesDHTMLEquipmentView inventoryEquipment) {
    this.inventoryEquipmentView = inventoryEquipment;
  }
  public IlvFacesDHTMLOverview getInventoryOverview() {
    return inventoryOverview;
  }
  public void setInventoryOverview(IlvFacesDHTMLOverview inventoryOverview) {
    this.inventoryOverview = inventoryOverview;
  }
  public CorePanelGroupLayout getInventoryOverviewPanel() {
    return inventoryOverviewPanel;
  }
  public void setInventoryOverviewPanel(CorePanelGroupLayout inventoryOverviewPanel) {
    this.inventoryOverviewPanel = inventoryOverviewPanel;
  }
  public EquipmentDrillDownManager getEquipmentDrillDownManager() {
    return equipmentDrillDownManager;
  }
  public InventoryContextualMenuFactory getInventoryContextualMenuFactory() {
    return inventoryContextualMenuFactory;
  }
  public void setInventoryContextualMenuFactory(
      InventoryContextualMenuFactory inventoryContextualMenuFactory) {
    this.inventoryContextualMenuFactory = inventoryContextualMenuFactory;
  }
  public String getEquipmentInventoryDisplayLabel() {
    return equipmentInventoryDisplayLabel;
  }
  public void setEquipmentInventoryDisplayLabel(
      String equipmentInventoryDisplayLabel) {
    this.equipmentInventoryDisplayLabel = equipmentInventoryDisplayLabel;
  }

  //////////////////////////////////////////////////////////////////////////////
  //Internal Types
  //////////////////////////////////////////////////////////////////////////////

  /**
   * Handles the propagation of selections in the main view to the other main 
   * components (tree and table).
   */
  static class EquipmentViewSelectionPropagator implements EquipmentSelectionListener {

    private AbstractSampleContext sampleContext;

    public AbstractSampleContext getSampleContext() {
      return sampleContext;
    }
    public void setApplicationContext(AbstractSampleContext sampleContext) {
      this.sampleContext = sampleContext;
    }

    public void objectsAdded(EquipmentSelectionEvent event) {
      if(WebUtils.isApplicationLive()) {
        sampleContext
        .getActionProviders()
        .getSharedActions()
        .handleSelectionObjectAddedOnCurrentView(event.getObjects());
      }  
    }

    public void objectsRemoved(EquipmentSelectionEvent event) {
      if(WebUtils.isApplicationLive()) {
        sampleContext.getActionProviders().getSharedActions()
        .handleSelectionObjectRemovedOnCurrentView(
            event.getEquipmentSelectionModel());
      }  
    }
  }
  
  /**
   * Ensures that the label of network module's network display label.
   */
  class InventoryDisplayLabelUpdater implements PropertyChangeListener {
    private AbstractSampleContext sampleContext;

    public AbstractSampleContext getSampleContext() {
      return sampleContext;
    }
    public void setApplicationContext(AbstractSampleContext sampleContext) {
      this.sampleContext = sampleContext;
    }
    public void propertyChange(PropertyChangeEvent evt) {
      sampleContext.getActionProviders().getEquipmentActions().updateInventoryEquipmentDisplayLabel();
    }
  }
}