//   Copyright 2012 Georg-August-Universität Göttingen, Germany
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

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

/**
 * <p>
 * A task equality denotes, how equal two tasks 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 tasks conceptually. But the other design levels can be
 * identified and compared.
 * </p>
 * <p>
 * Tasks 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>
 * Tasks are lexically equal, if they represent the same events on a key stroke level to be
 * carried out to execute the task. Identical tasks are also lexically equal.
 * </p>
 * <p>
 * Tasks 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 tasks are also syntactically equal.  
 * </p>
 * <p>
 * Tasks 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 tasks
 * are syntactically and, therefore, also lexically different, but semantically equal.
 * Syntactically equal tasks are always also semantically equal.
 * </p>
 * 
 * @version $Revision: $ $Date: 19.02.2012$
 * @author 2012, last modified by $Author: patrick$
 */
public enum TaskEquality {
    IDENTICAL,
    LEXICALLY_EQUAL,
    SYNTACTICALLY_EQUAL,
    SEMANTICALLY_EQUAL,
    UNEQUAL;

    /**
     * <p>
     * Checks for the current task equality, if it is at least identical to the
     * provided one or even more concrete. As an example, the task equality identical also
     * indicates, that the tasks 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 taskEquality the task equality to compare with.
     * 
     * @return as described
     */
    public boolean isAtLeast(TaskEquality taskEquality)
    {
        switch (taskEquality) {
            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 task 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 otherEquality the equality, to compare this with
     * 
     * @return as described
     */
    public TaskEquality getCommonDenominator(TaskEquality otherEquality) {
        if (this.isAtLeast(otherEquality)) {
            return otherEquality;
        }
        else if (otherEquality.isAtLeast(this)) {
            return this;
        }
        else {
            return TaskEquality.UNEQUAL;
        }
    }
}
