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

/**
 * <p>
 * A node equality denotes, how equal two task tree nodes are. There are different equality levels
 * which are similar to the usual design levels of GUI design. These levels are
 * <ul>
 *   <li>conceptual design: defines the concepts to be edited using a GUI</li>
 *   <li>semantical design: defines the possible functions for editing the concepts</li>
 *   <li>syntactical design: defines, which steps are needed to execute the functions</li>
 *   <li>lexical design: defines on the key stroke level, how the steps for executing a function
 *       can be performed</li>
 * </ul>
 * It is not possible to compare two task nodes conceptually. But the other design levels can be
 * identified and compared.
 * </p>
 * <p>
 * Nodes can be identical. This is the case if in the java virtual machine, their comparison
 * using the <code>==</code> operator or the equals method return true.
 * </p>
 * <p>
 * Nodes are lexically equal, if they represent the same events on a key stroke level to be
 * carried out to execute the task. Identical nodes are also syntactically equal.
 * </p>
 * <p>
 * Nodes are syntactically equal, if they differ in their events on key stroke level, but the
 * syntactical result is the same. For example, entering the text "hello" into a text field can
 * be done by entering the letters in their correct order, but also by copying the text into the
 * text field. The syntactical result is the same: The text hello was entered. But the tasks
 * lexically differ because the events on key stroke level are different. On the other hand,
 * lexically equal nodes are also syntactically equal.  
 * </p>
 * <p>
 * Task tree nodes are semantically equal, if they execute the same function for editing the
 * concepts. An example are a click on a button and a short cut, both executing the same function.
 * These task tree nodes are syntactically and, therefore, also lexically different, but
 * semantically equal. Syntactically equal task tree nodes are always also semantically equal.
 * </p>
 * 
 * @version $Revision: $ $Date: 19.02.2012$
 * @author 2012, last modified by $Author: patrick$
 */
public enum NodeEquality {
    IDENTICAL,
    LEXICALLY_EQUAL,
    SYNTACTICALLY_EQUAL,
    SEMANTICALLY_EQUAL,
    UNEQUAL;

    /**
     * <p>
     * Checks for the current node equality, if it is at least identical to the
     * provided one or even more concrete. As an example, the node equality identical also
     * indicates, that the nodes are e.g. lexically, syntactically and semantically equal.
     * Therefore, the method called on <code>IDENTICAL</code> with <code>SEMANTICALLY_EQUAL</code>
     * as parameter will return true. If this method is called on <code>SYNTACTICALLY_EQUAL</code>
     * with the parameter <code>IDENTICAL</code> instead, it returns false;
     * </p>
     *
     * @param nodeEquality the node equality to compare with.
     * 
     * @return as described
     */
    public boolean isAtLeast(NodeEquality nodeEquality)
    {
        switch (nodeEquality) {
            case IDENTICAL:
                return
                    (this == IDENTICAL);
            case LEXICALLY_EQUAL:
                return
                    (this == IDENTICAL) ||
                    (this == LEXICALLY_EQUAL);
            case SYNTACTICALLY_EQUAL:
                return
                    (this == IDENTICAL) ||
                    (this == LEXICALLY_EQUAL) ||
                    (this == SYNTACTICALLY_EQUAL);
            case SEMANTICALLY_EQUAL:
                return
                    (this == IDENTICAL) ||
                    (this == LEXICALLY_EQUAL) ||
                    (this == SYNTACTICALLY_EQUAL) ||
                    (this == SEMANTICALLY_EQUAL);
            case UNEQUAL:
                return
                    (this == UNEQUAL);
            default :
                return false;
        }
    }

    /**
     * <p>
     * returns the common denominator of this node equality and the provided one. I.e. if one
     * equality is e.g. syntactical and the other one only semantical, then semantical is returned.
     * </p>
     *
     * @param equality the equality, to compare this with
     * @return
     */
    public NodeEquality getCommonDenominator(NodeEquality otherEquality) {
        if (this.isAtLeast(otherEquality)) {
            return otherEquality;
        }
        else if (otherEquality.isAtLeast(this)) {
            return this;
        }
        else {
            return NodeEquality.UNEQUAL;
        }
    }
}
