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

import de.ugoe.cs.quest.eventcore.guimodel.GUIElement;
import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonDown;
import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonInteraction;
import de.ugoe.cs.quest.eventcore.userinteraction.MouseButtonUp;
import de.ugoe.cs.quest.eventcore.userinteraction.MouseClick;
import de.ugoe.cs.quest.tasktrees.treeifc.InteractionTask;
import de.ugoe.cs.quest.tasktrees.treeifc.Sequence;
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: 18.03.2012$
 * @author 2012, last modified by $Author: patrick$
 */
//-------------------------------------------------------------------------------------------------
public class DefaultMouseClickReductionRule implements TemporalRelationshipRule
{

  //-----------------------------------------------------------------------------------------------
  /* (non-Javadoc)
   * @see de.ugoe.cs.tasktree.temporalrelation.TemporalRelationshipRule#apply(TaskTreeNode, TaskTreeBuilder, TaskTreeNodeFactory)
   */
  //-----------------------------------------------------------------------------------------------
  @Override
  public RuleApplicationResult apply(TaskTreeNode        parent,
                                     TaskTreeBuilder     builder,
                                     TaskTreeNodeFactory nodeFactory,
                                     boolean             finalize)
  {
    if (!(parent instanceof Sequence))
    {
      return null;
    }
    
    RuleApplicationResult result = new RuleApplicationResult();
    
    int index = 0;
    while (index < parent.getChildren().size() - 2) // -2 because we don't need to go to the end
    {
      if (mouseClickSequenceFound(parent.getChildren().get(index),
                                  parent.getChildren().get(index + 1),
                                  parent.getChildren().get(index + 2)))
      {
         builder.removeChild((Sequence) parent, index);
         builder.removeChild((Sequence) parent, index);
         result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
         return result;
      }
      else if ((parent.getChildren().get(index) instanceof Sequence) &&
               (parent.getChildren().get(index).getChildren().size() == 2) &&
               (mouseClickSequenceFound(parent.getChildren().get(index).getChildren().get(0),
                                        parent.getChildren().get(index).getChildren().get(1),
                                        parent.getChildren().get(index + 1))))
      {
        builder.removeChild((Sequence) parent, index);
        result.setRuleApplicationStatus(RuleApplicationStatus.RULE_APPLICATION_FINISHED);
        return result;
      }
      
      index++;
    }
    
    return result;
  }

  //-----------------------------------------------------------------------------------------------
  /**
   * 
   */
  //-----------------------------------------------------------------------------------------------
  private boolean mouseClickSequenceFound(TaskTreeNode mouseButtonDown,
                                          TaskTreeNode mouseButtonUp,
                                          TaskTreeNode mouseClick)
  {
    // check the first in a row of three for validity
    if (!(mouseButtonDown instanceof InteractionTask))
    {
      return false;
    }
    
    GUIElement guiElement = ((InteractionTask) mouseButtonDown).getGUIElement();
    
    if (!(((InteractionTask) mouseButtonDown).getInteraction() instanceof MouseButtonDown))
    {
      return false;
    }
    
    MouseButtonInteraction.Button button =
      ((MouseButtonDown) ((InteractionTask) mouseButtonDown).getInteraction()).getButton();
    
    
    // check the second node for validity
    if (!(mouseButtonUp instanceof InteractionTask))
    {
      return false;
    }
    
    if (!guiElement.equals(((InteractionTask) mouseButtonUp).getGUIElement()))
    {
      return false;
    }
    
    if (!(((InteractionTask) mouseButtonUp).getInteraction() instanceof MouseButtonUp))
    {
      return false;
    }
    
    if (!button.equals
          (((MouseButtonUp) ((InteractionTask) mouseButtonUp).getInteraction()).getButton()))
    {
      return false;
    }
    
    
    // check the third node for validity
    if (!(mouseClick instanceof InteractionTask))
    {
      return false;
    }
    
    if (!guiElement.equals(((InteractionTask) mouseClick).getGUIElement()))
    {
      return false;
    }
    
    if (!(((InteractionTask) mouseClick).getInteraction() instanceof MouseClick))
    {
      return false;
    }
    
    if (!button.equals(((MouseClick) ((InteractionTask) mouseClick).getInteraction()).getButton()))
    {
      return false;
    }
    
    return true;
  }

}
