package de.ugoe.cs.autoquest.tasktrees.nodeequality;

import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;

/**
 * <p>
 * This rule is capable of comparing sequences. If both sequences do not have children, they are
 * treated as lexically equal. Sequences are lexically equal, if they have the same number and
 * order of lexically equal children. The rule can not decide, if two sequences are syntactically
 * or semantically equal.
 * </p>
 * 
 * @version $Revision: $ $Date: 19.02.2012$
 * @author 2012, last modified by $Author: patrick$
 */
public class SequenceComparisonRule implements NodeComparisonRule {

    /** the rule manager for internally comparing task tree nodes */
    private NodeEqualityRuleManager mRuleManager;

    /**
     * <p>
     * simple constructor to provide the rule with the node equality rule manager to be able
     * to perform comparisons of the children of provided task tree nodes
     * </p>
     * 
     * @param ruleManager the rule manager for comparing task tree nodes
     */
    SequenceComparisonRule(NodeEqualityRuleManager ruleManager) {
        super();
        mRuleManager = ruleManager;
    }

    /*
     * (non-Javadoc)
     * 
     * @see de.ugoe.cs.tasktree.nodeequality.NodeEqualityRule#apply(TaskTreeNode, TaskTreeNode)
     */
    @Override
    public NodeEquality compare(ITaskTreeNode node1, ITaskTreeNode node2) {
        if ((!(node1 instanceof ISequence)) || (!(node2 instanceof ISequence))) {
            return null;
        }

        if (node1 == node2) {
            return NodeEquality.IDENTICAL;
        }

        // if both sequences do not have children, they are equal although this doesn't make sense
        if ((node1.getChildren().size() == 0) && (node2.getChildren().size() == 0)) {
            return NodeEquality.LEXICALLY_EQUAL;
        }

        if (node1.getChildren().size() != node2.getChildren().size()) {
            return NodeEquality.UNEQUAL;
        }

        NodeEquality resultingEquality = NodeEquality.LEXICALLY_EQUAL;
        for (int i = 0; i < node1.getChildren().size(); i++) {
            ITaskTreeNode child1 = node1.getChildren().get(i);
            ITaskTreeNode child2 = node2.getChildren().get(i);

            NodeEquality nodeEquality = mRuleManager.applyRules(child1, child2);

            if ((nodeEquality == null) || (nodeEquality == NodeEquality.UNEQUAL)) {
                return NodeEquality.UNEQUAL;
            }
            
            resultingEquality = resultingEquality.getCommonDenominator(nodeEquality);
        }

        return resultingEquality;
    }

}
