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

import ilog.cpl.IlpEquipment;
import ilog.cpl.datasource.IlpDataSource;
import ilog.cpl.equipment.IlpEquipmentAdapter;
import ilog.cpl.graph.IlpGraphSelectionModel;
import ilog.cpl.model.IlpObject;
import ilog.tgo.faces.equipment.dhtml.component.IltFacesDHTMLEquipmentView;

import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import javax.faces.component.UIComponent;

import monitoring.shared.CommonUtils;
import monitoring.shared.LoggingUtils;
import monitoring.shared.drilldown.EquipmentDrillDownManager;
import monitoring.web.SampleDataModels;
import shared.ResourceUtils;


/**
 * Action provider that holds the equipment related actions.
 */
public class EquipmentActionProvider extends BaseActionProvider {

  /**
   * Changes the visibility of the inventory module's overview and handles the logistics involved.
   */
  public void changeInventoryOverviewVisibility() {

    //1- Find the overview panel
    UIComponent overviewPanel = 
      getControls().getEquipmentControls().getInventoryOverviewPanel();

    //2- Toggle its visibility 
    overviewPanel.setRendered(!overviewPanel.isRendered());
  }

  /**
   * Triggers the drill down process on the inventory module's equipment with the
   * provided object as the root.
   * 
   * @param showDetails if true, the provided object will be made the root, otherwise 
   * its parent will be used as the root.
   */
  public void triggerDrillDownOnInventoryEquipment(IlpObject object, boolean showDetails) {

    //1- Get the drill down manager
    EquipmentDrillDownManager drillDownManager = getControls().getEquipmentControls().getEquipmentDrillDownManager();

    IlpObject objectToFocus = null;

    //2- Update inventory origin
    if (showDetails) {
      //The object itself is the object to filter the table on 
      objectToFocus = object;  
    } else {

      //The parent is the object to filter the table on 
      objectToFocus = CommonUtils.getParent(object, getDataStructures().getDataSources().getInventoryDataSource());    
    }

    //3- Show the object now
    drillDownManager.show(objectToFocus);

    //4- Update inventory table filter's origins
    updateInventoryTableOrigin(objectToFocus);
  }

  /**
   * Updates the inventory module's managed object table with the provided object
   * as the root. 
   */
  public void updateInventoryTableOrigin(IlpObject origin) {
    updateInventoryTableOrigin(getInventoryEquipment(), origin);
  }

  /**
   * Selects the objects that are related to the provided object in the 
   * inventory module's tree view.
   * 
   * @param clearCurrentSelection if false the current selection is kept, otherwise
   * it is removed.
   */
  public void selectRelatedObjectsOnInventoryView(IlpObject object, boolean clearCurrentSelection) {

    //Propagate the selection to the inventory equipment view only if the 
    //the equipment view is showing something

    //1- Find the current origins 
    List<Object> currentOrigins = getInventoryEquipment().getAdapter().getOrigins();

    //2- Propgate the selection is needed
    if (currentOrigins != null && !currentOrigins.isEmpty()) {

      //1- Find the selection model
      IlpGraphSelectionModel selectionModel = getInventoryEquipmentSelectionModel();

      //2- Find the objects to select on the view
      List<IlpObject> viewObjectsToBeSelected = getViewSpecificObjects(object);

      //5- Update the selection
      if (selectionModel != null) {
        getActionProviders().getSharedActions().selectObjects(
            selectionModel, viewObjectsToBeSelected,
            clearCurrentSelection);
      }
    }
  }

  /**
   * Updates the display label of the inventory module's equipment with the 
   * appropriate identifier string representation of the current root. 
   */
  public void updateInventoryEquipmentDisplayLabel() {

    String label = null;

    IlpEquipmentAdapter adapter = getInventoryEquipment().getAdapter();

    if (adapter != null) {
      List<Object> origins = adapter.getOrigins();

      if (origins.isEmpty()) {
        label = ResourceUtils.getString("labelInventoryRootLevel");
      } else if (origins.size() == 1) {
        IlpDataSource dataSource = 
          getDataStructures().getDataSources().getInventoryDataSource();

        IlpObject object = dataSource.getObject(origins.get(0));
        String name = (String) object.getAttributeValue("name");
        label = (name != null) ? name : ResourceUtils.getString("labelNoObjectName");
      } else {
        label = ResourceUtils.getString("labelInventoryMultipleRoots");
      }
    }

    getControls().getEquipmentControls().setEquipmentInventoryDisplayLabel(label);
  }


  //////////////////////////////////////////////////////////////////////////////
  //Private Methods
  //////////////////////////////////////////////////////////////////////////////

  private void updateInventoryTableOrigin(IlpEquipment equipment, IlpObject origin) {

    SampleDataModels dataModels = getDataStructures().getDataModels();

    getActionProviders().getSharedActions().updateTableOrigin(
        dataModels.getInventoryObjectsTableModelProvider(), origin);
  }

  private List<IlpObject> getViewSpecificObjects(IlpObject object) {
    List<IlpObject> relatedObjects = new ArrayList<IlpObject>();

    int currentModule = getActionProviders().getSharedActions().getCurrentModule();
    if (SharedActionProvider.INVENTORY_MODULE == currentModule) {
      relatedObjects.add(object);
    }
    return relatedObjects;
  }

  private IlpEquipment getInventoryEquipment() {

    try {
      return getInventoryEquipmentView().getEquipment();
    } catch (Exception e) {
      LoggingUtils.getSampleLogger().log(
          Level.SEVERE,
          "Could not find the selection model of the inventory equipment view with this exception:"
          + e.getLocalizedMessage());
      return null;
    }
  }

  private IlpGraphSelectionModel getInventoryEquipmentSelectionModel() {

    try {
      return getInventoryEquipment().getSelectionModel();
    } catch (Exception e) {
      LoggingUtils.getSampleLogger().log(
          Level.SEVERE,
          "Could not find the selection model of the inventory equipment view with this exception:"
          + e.getLocalizedMessage());
      return null;
    }
  }

  private IltFacesDHTMLEquipmentView getInventoryEquipmentView() {
    return getControls().getEquipmentControls().getInventoryEquipmentView();
  }
}