/**
 * This class is an equivalent to the pair class in c++
 * 
 * @author OPEN SOURCE
 *
 * @param <A> Type of first component
 * @param <B> Type of second component
 */
package Model;

public class Pair<A, B> {
	
	private A first;
    private B second;

    /**
     * Explicit constructor
     * 
     * @param first First component of the pair
     * @param second Second component of the pair
     */
    public Pair(A first, B second) {
        super();
        this.first = first;
        this.second = second;
    }
    
    /**
     * Creates HashCode of this Object
     * 
     * return	HashCode
     */
    public int hashCode() {
        int hashFirst = first != null ? first.hashCode() : 0;
        int hashSecond = second != null ? second.hashCode() : 0;

        return (hashFirst + hashSecond) * hashSecond + hashFirst;
    }

    /**
     * Checks equality of argument
     * 
     * @param other
     * 			Object which is supposed to be compared
     * @return 1 if equal, 0 else
     */
    public boolean equals(Object other) {
        if (other instanceof Pair) {
        		//suppressed warning
                @SuppressWarnings("unchecked")
				Pair<A,B> otherPair = (Pair<A,B>) other;
                return 
                ((  this.first == otherPair.first ||
                        ( this.first != null && otherPair.first != null &&
                          this.first.equals(otherPair.first))) &&
                 (      this.second == otherPair.second ||
                        ( this.second != null && otherPair.second != null &&
                          this.second.equals(otherPair.second))) );
        }

        return false;
    }

    /**
     * Computes string representation of this object
     * 
     * @return String representation
     */
    public String toString()
    { 
           return "(" + first + ", " + second + ")"; 
    }

    /**
     * This method returns first component
     * 
     * @return first component of this pair
     */
    public A getFirst() {
        return first;
    }

    /**
     * This method sets first component
     * 
     * @param first
     */
    public void setFirst(A first) {
        this.first = first;
    }

    /**
     * This method returns second component
     * 
     * @return second component of this pair
     */
    public B getSecond() {
        return second;
    }

    /**
     * This method sets second component
     * 
     * @param second
     */
    public void setSecond(B second) {
        this.second = second;
    }


}
