//-------------------------------------------------------------------------------------------------
// Module    : $RCSfile: TemporalRelationshipRuleManager.java,v $
// Version   : $Revision: 0.0 $  $Author: patrick $  $Date: 12.02.2012 $
// Project   : TaskTreeCreator
// Creation  : 2012 by patrick
// Copyright : Patrick Harms, 2012
//-------------------------------------------------------------------------------------------------
package de.ugoe.cs.quest.tasktrees.temporalrelation;

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

import de.ugoe.cs.quest.tasktrees.nodeequality.NodeEqualityRuleManager;
import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeBuilder;
import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNode;
import de.ugoe.cs.quest.tasktrees.treeifc.TaskTreeNodeFactory;

//-------------------------------------------------------------------------------------------------
/**
 * TODO comment
 * 
 * @version $Revision: $ $Date: 12.02.2012$
 * @author 2012, last modified by $Author: patrick$
 */
//-------------------------------------------------------------------------------------------------
public class TemporalRelationshipRuleManager
{
  /** */
  private static Logger LOG = Logger.getLogger(TemporalRelationshipRuleManager.class.getName());

  /** */
  private NodeEqualityRuleManager mNodeEqualityRuleManager;

  /** */
  private List<TemporalRelationshipRule> mRuleIndex = new ArrayList<TemporalRelationshipRule>();

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   */
  //-----------------------------------------------------------------------------------------------
  public TemporalRelationshipRuleManager(NodeEqualityRuleManager nodeEqualityRuleManager)
  {
    super();
    mNodeEqualityRuleManager = nodeEqualityRuleManager;
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * TODO: comment
   *
   */
  //-----------------------------------------------------------------------------------------------
  public void init()
  {
    LOG.info("initializing");
    
    mRuleIndex.add(new DefaultMouseClickReductionRule());
    mRuleIndex.add(new DefaultTextInputReductionRule());
    mRuleIndex.add(new DefaultGUIElementSequenceDetectionRule());
    mRuleIndex.add(new TrackBarSelectionDetectionRule(mNodeEqualityRuleManager));
    mRuleIndex.add(new DefaultSequenceDetectionRule());
    mRuleIndex.add(new DefaultIterationDetectionRule(mNodeEqualityRuleManager));
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * returns true, if there is a rule that matches the current situation and if, therefore, a
   * new temporal relationship has been added to the tree.
   * 
   * @param parent
   * @param newChild
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  public void applyRules(TaskTreeNode        parent,
                         TaskTreeBuilder     builder,
                         TaskTreeNodeFactory nodeFactory,
                         boolean             finalize)
  {
    applyRules(parent, builder, nodeFactory, finalize, "");
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * returns true, if there is a rule that matches the current situation and if, therefore, a
   * new temporal relationship has been added to the tree.
   * 
   * @param parent
   * @param newChild
   * @return
   */
  //-----------------------------------------------------------------------------------------------
  private int applyRules(TaskTreeNode        parent,
                         TaskTreeBuilder     builder,
                         TaskTreeNodeFactory nodeFactory,
                         boolean             finalize,
                         String              logIndent)
  {
    LOG.info(logIndent + "applying rules for " + parent);
    
    int noOfRuleApplications = 0;
    
    for (TemporalRelationshipRule rule : mRuleIndex)
    {
      RuleApplicationResult result;
      do
      {
        //LOG.info(logIndent + "trying to apply rule " + rule + " on " + parent);
        result = rule.apply(parent, builder, nodeFactory, finalize);
        
        if ((result != null) &&
            (result.getRuleApplicationStatus() == RuleApplicationStatus.RULE_APPLICATION_FINISHED))
        {
          LOG.info(logIndent + "applied rule " + rule + " on " + parent);
          noOfRuleApplications++;
          
          for (TaskTreeNode newParent : result.getNewlyCreatedParentNodes())
          {
            noOfRuleApplications +=
              applyRules(newParent, builder, nodeFactory, true, logIndent + "  ");
          }
        }
      }
      while ((result != null) &&
             (result.getRuleApplicationStatus() == RuleApplicationStatus.RULE_APPLICATION_FINISHED));
      
      if ((!finalize) && (result != null) &&
          (result.getRuleApplicationStatus() == RuleApplicationStatus.RULE_APPLICATION_FEASIBLE))
      {
        // in this case, don't go on applying rules, which should not be applied yet
        break;
      }
    }
    
    if (noOfRuleApplications <= 0)
    {
      LOG.warning(logIndent + "no rules applied --> no temporal relationship generated");
    }
    
    return noOfRuleApplications;
  }
  
  //-----------------------------------------------------------------------------------------------
  /**
   *
   */
  //-----------------------------------------------------------------------------------------------
  /*private void dumpTask(TaskTreeNode task, String indent)
  {
    System.err.print(indent);
    System.err.print(task);
    System.err.println(" ");
    
    if ((task.getChildren() != null) && (task.getChildren().size() > 0))
    {
      for (TaskTreeNode child : task.getChildren())
      {
        dumpTask(child, indent + "  ");
      }
    }
  }*/

}
