/*
 * 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.model.IlpObject;
import ilog.tgo.model.IltAlarm;

import java.util.logging.Level;

import monitoring.shared.LoggingUtils;
import monitoring.web.controls.TreeControls;
import monitoring.web.model.integration.IntegratedDataModelProvider;
import monitoring.web.model.integration.beans.TGOObjectHierarchical;
import monitoring.web.model.integration.filters.HideTypeFilter;

import org.apache.myfaces.trinidad.component.core.data.CoreTree;
import org.apache.myfaces.trinidad.model.RowKeySet;


/**
 * Action provider that holds the tree related actions.
 */
public class TreeActionProvider extends BaseActionProvider {

  /**
   * Switches the tree area to show the network module's tree. 
   */
  public String switchToNetworkTab() {

    //The Network Tab is at index 0
    switchToTab(0);

    return null;
  }

  /**
   * Switches the tree area to show the inventory module's tree. 
   */
  public String switchToInventoryTab() {

    //The Inventory Tab is at index 1
    switchToTab(1);

    return null;
  }

  /**
   * Switches the tree area to show the service module's tree. 
   */
  public String switchToServiceTab() {

    //The Service Tab is at index 2
    switchToTab(2);

    return null;
  }

  /**
   * Initializes the network module's tree and its tree model provider.
   */
  public void initializeNetworkObjectsTree() {

    //1- Create the appropriate filter 
    HideTypeFilter filter = new HideTypeFilter();
    filter.setType(IltAlarm.GetIlpClass());

    //2- Set it on the model provider 
    getDataStructures().getDataModels().getNetworkTreeModelProvider().setFilter(filter);
    getDataStructures().getDataModels().getInventoryTreeModelProvider().setFilter(filter);
  }

  /**
   * Initializes the inventory module's tree.
   */
  public void initializeInventoryObjectsTree() {
    //NOP
  }

  /**
   * Initializes the service module's tree.
   */
  public void initializeServiceObjectsTree() {
    //NOP
  }

  /**
   * Clears the selection on the current tree(being it the network, 
   * inventory or service tree).
   */
  public void clearSelectionOnCurrentTree() {
    CoreTree tree = getCurrentTree();
    if (tree != null) {
      RowKeySet selection = tree.getSelectedRowKeys();
      if (selection != null) {
        selection.clear();
      }
    }
  }

  /**
   * Clears the expansion state on the current tree(being it the network, 
   * inventory or service tree).
   */
  public void clearExpansionOnCurrentTree() {
    CoreTree tree = getCurrentTree();
    if (tree != null) {
      RowKeySet expansion = tree.getDisclosedRowKeys();
      if (expansion != null) {
        expansion.clear();
      }
    }
  }

  /**
   * Selects the object on the current tree(being it the network, 
   * inventory or service tree) by finding its position on the tree and selecting it.
   * 
   * @param clearExpansionState if true the previous expansion state is cleared, otherwise kept
   * @param clearSelectionState if true the previous selection state is cleared, otherwise kept
   */
  public void selectObjectOnCurrentTree(IlpObject object,
      boolean clearExpansionState, boolean clearSelectionState) {
    if(object != null) {
      selectObjectOnTree(object, getCurrentTreeModelProvider(),
          getCurrentTree(), clearExpansionState, clearSelectionState);
    }
  }

  /**
   * Clears the selection on the current tree (being it the network, 
   * inventory or service tree). 
   */
  public void clearObjectSelectionOnCurrentTree() {

    //1- Find the current tree 
    CoreTree tree = getCurrentTree();

    //2- Get its selection objects
    RowKeySet selection = tree.getSelectedRowKeys();

    //3- Clear the selection
    selection.clear();
  }

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

  private void selectObjectOnTree(IlpObject object, 
                                  IntegratedDataModelProvider modelProvider, CoreTree tree,
                                  boolean clearExpansionState, boolean cleanSelectionState) {
    //1- Retrieve the model object
    TGOObjectHierarchical modelObj = (TGOObjectHierarchical)modelProvider.getModelObject(object);
//if (getSampleContext().COMPLETION_LOCK.executingTask) { tree.getSelectedRowKeys().clear(); tree.getSelectedRowKeys().add(tree.getRowKey()); return; }
    if (null != modelObj) {
      //2- Select
      //Retrieve the list  of selected objects
      RowKeySet selection = tree.getSelectedRowKeys();
      if (null != selection) {
        if (cleanSelectionState) {
          //Clear the selection
          selection.clear();
        }
        
        //Update the selection
        selection.add(modelObj.getModelPath());
      }
      
      //3- Expand
      //Get the list of expanded objects
      RowKeySet expansion = tree.getDisclosedRowKeys();
      
      if (null != expansion) {
        //4- Clear the expansion to focus on newly selected value
        if (clearExpansionState) {
          expansion.clear();
        }
  
        //5- Expand path(s) to display tree node 
        modelObj.updateModelDisclosedRows(expansion);
      }
    } else {
      LoggingUtils.getSampleLogger().log(Level.WARNING,
                                         "Could not find tree node for object '"
                                         + object.getIdentifier()
                                         + "' to be selected in tree.");
    }
  }

  private CoreTree getCurrentTree() {
    CoreTree tree = null;

    int currentModule = 
      getActionProviders().getSharedActions().getCurrentModule();
    if (SharedActionProvider.NETWORK_MODULE == currentModule) {
      tree = getControls().getTreeControls().getNetworkTree();
    } else if (SharedActionProvider.INVENTORY_MODULE == currentModule) {
      tree = getControls().getTreeControls().getInventoryTree();
    } else if (SharedActionProvider.SERVICE_MODULE == currentModule) {
      tree = getControls().getTreeControls().getServiceTree();
    } else {
      LoggingUtils.getSampleLogger().log(Level.SEVERE,
      "Could not find the current tree view.");
    }

    return tree;
  }

  private IntegratedDataModelProvider getCurrentTreeModelProvider() {

    IntegratedDataModelProvider modelProvider = null;

    int currentModule = 
      getActionProviders().getSharedActions().getCurrentModule();
    if (SharedActionProvider.NETWORK_MODULE == currentModule) {
      modelProvider = 
        getDataStructures().getDataModels().getNetworkTreeModelProvider();
    } else if (SharedActionProvider.INVENTORY_MODULE == currentModule) {
      modelProvider = 
        getDataStructures().getDataModels().getInventoryTreeModelProvider();
    } else if (SharedActionProvider.SERVICE_MODULE == currentModule) {
      modelProvider = 
        getDataStructures().getDataModels().getServiceTreeModelProvider();
    } else {
      LoggingUtils.getSampleLogger().log(
          Level.SEVERE,
          "Could not find the '"
          + IntegratedDataModelProvider.class.getName()
          + "' for current tree view.");
    }

    return modelProvider;
  }

  private String switchToTab(int targetTabIndex) {

    //Update tab
    setSelectedTab(targetTabIndex, getControls().getTreeControls().getTabs());

    //Show proper tree
    showTree(targetTabIndex);

    return null;
  }

  private void showTree(int index) {
    TreeControls treeControls = getControls().getTreeControls();
    String selectedFacetName = treeControls.getTreeSwitcherFacetName(index);
    treeControls.getTreeSwitcher().setFacetName(selectedFacetName);
  }
}