package com.googlecode.prolog_cafe.lang;

import com.googlecode.prolog_cafe.exceptions.InternalException;

/**
 * Variable.<br>
 * The <code>VariableTerm</code> class represents a logical variable.<br>
 * For example,
 * <pre>
 *   Term t = new VariableTerm();
 * </pre>
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.0
 */
@SuppressWarnings("EqualsWrongThing")
public class VariableTerm extends Term implements Undoable {
    /** Holds a term to which this variable is bound. Initial value is <code>this</code> (self-reference). */
    private Term val;
    /** A CPF time stamp when this object is newly constructed. */
    private long timeStamp;

    /** Constructs a new logical variable so that
     * the <code>timeStamp</code> field is set to <code>Long.MIN_VALUE</code>.
     */
    public VariableTerm() {
	val = this;
    timeStamp = Long.MIN_VALUE;
    }

    /** Constructs a new logical variable so that
     * the <code>timeStamp</code> field is set to the current value of
     * <code>CPFTimeStamp</code> of the specified Prolog engine.
     * @param engine Current Prolog engine.
     * @see Prolog#getCPFTimeStamp
     */
    public VariableTerm(Prolog engine) {
	val = this;
	timeStamp = engine.getCPFTimeStamp();
    }

    /** Returns a string representation of this object.*/
    protected String variableName() { return "_" + Integer.toHexString(hashCode()).toUpperCase(); }

    @Override
    public int type() {
      return TYPE_VARIABLE;
    }

    /** 
     * Checks whether the argument term is unified with this one.
     * If this is an unbound variable, the <code>unify</code> method binds this to 
     * the dereferenced value of argument term: <code>bind(t.dereference(), trail)</code>,
     * and returns <code>true</code>.
     * Otherwise, it returns a <code>boolean</code> whose value is <code>val.unify(t, trail)</code>.
     * @param t the term to be unified with.
     * @param trail Trail Stack.
     * @return <code>true</code> if succeeds, otherwise <code>false</code>.
     * @see #val
     * @see #bind(Term,Trail)
     * @see Trail
     */
    @Override
    public boolean unify(Term t, Trail trail) {
	if (val != this)
	    return val.unify(t, trail);
	t = t.dereference();
	if (this != t)
	    bind(t, trail);
	return true;
    }

    /** 
     * Binds this variable to a given term. 
     * And pushs this variable to trail stack if necessary. 
     * @param t a term to be bound.
     * @param trail Trail Stack
     * @see Trail
     */
  public void bind(Term t, Trail trail) {
    if (t instanceof VariableTerm) {
      VariableTerm v = (VariableTerm) t;
      if (v.timeStamp >= this.timeStamp) {
        v.val = this;
        if (v.timeStamp < trail.timeStamp)
          trail.push(v);
        return;
      }
    }

    val = t;
    if (timeStamp < trail.timeStamp)
      trail.push(this);
  }

    /** 
     * Checks whether this object is convertible with the given Java class type 
     * if this variable is unbound.
     * Otherwise, returns the value of <code>val.convertible(type)</code>.
     * @param type the Java class type to compare with.
     * @return <code>true</code> if this (or dereferenced term) is 
     * convertible with <code>type</code>. Otherwise <code>false</code>.
     * @see #val
     */
    @Override
    public boolean convertible(Class<?> type) {
	if (val != this)
	    return val.convertible(type);
	return convertible(this.getClass(), type);
    }

    /** 
     * Returns a copy of this object if unbound variable.
     * Otherwise, returns the value of <code>val.copy(engine)</code>.
     * @see #val
     */
    @Override
    protected Term copy(Prolog engine) {
	VariableTerm co;
	if (val != this)
	    return val.copy(engine);
	co = engine.copyHash.get(this);
	if (co == null) {
	    //	    co = new VariableTerm(engine);
	    co = new VariableTerm();
	    engine.copyHash.put(this, co);
	}
	return co;
    }

    @Override
    public Term dereference() {
	if (val == this)
	    return this;
	return val.dereference();
    }

    @Override
    public boolean isGround() {
	if (val != this)
	    return val.isGround();
	return false;
    }

    @Override
    public String name() {
    if (val == this)
      return "";
    return val.dereference().name();
    }

    /** 
     * Returns <code>this</code> if this variable is unbound.
     * Otherwise, returns a Java object that corresponds to the dereferenced term:
     * <code>val.toJava()</code>.
     * @return a Java object defined in <em>Prolog Cafe interoperability with Java</em>.
     * @see #val
     */
    @Override
    public Object toJava() { 
	if (val != this)
	    return val.toJava();
	return this;
    }

    /**
     * Returns a quoted string representation of this term if unbound.
     * Otherwise, returns the value of dereferenced term:
     * <code>val.toQuotedString()</code>
     * @see #val
     */
    @Override
    public String toQuotedString() {
	if (val != this)
	    return val.toQuotedString();
	return variableName();
    }

    /* Object */
    /**
     * Checks <em>term equality</em> of two terms.
     * This method returns a <code>boolean</code> whose value is
     * (<code>this == obj</code>) if this variable is unbound.
     * Otherwise, it returns the value of <code>val.equals(obj)</code>.
     * @param obj the object to compare with. This must be dereferenced.
     * @return <code>true</code> if this (or dereferenced term) is the same as the argument;
     * <code>false</code> otherwise.
     * @see #val
     * @see #compareTo
    */
    @Override
    public boolean equals(Object obj) {
	if(val != this)
	    return val.equals(obj);
	if (! (obj instanceof VariableTerm)) // ???
	    return false; //???
	return this == obj;
    }

    @Override
    public int hashCode() {
      return System.identityHashCode(this);
    }

    /**
     * Returns a string representation of this term if unbound.
     * Otherwise, returns the value of dereferenced term:
     * <code>val.toString()</code>
     * @see #val
     */
    @Override
    public String toString() {
	if (val != this)
	    return val.toString();
	return variableName();
    }

    /* Undoable */
    @Override
    public void undo() { val = this; }

    /* Comparable */
    /** 
     * Compares two terms in <em>Prolog standard order of terms</em>.<br>
     * It is noted that <code>t1.compareTo(t2) == 0</code> has the same
     * <code>boolean</code> value as <code>t1.equals(t2)</code>.
     * @param anotherTerm the term to compare with. It must be dereferenced.
     * @return the value <code>0</code> if two terms are identical; 
     * a value less than <code>0</code> if this term is <em>before</em> the <code>anotherTerm</code>;
     * and a value greater than <code>0</code> if this term is <em>after</em> the <code>anotherTerm</code>.
     */
    @Override
    public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
	if(val != this)
	    return val.compareTo(anotherTerm);
	if (! (anotherTerm instanceof VariableTerm))
	    return BEFORE;
	if (this == anotherTerm) 
	    return EQUAL;
	int x = this.hashCode() - ((VariableTerm)anotherTerm).hashCode();
	if (x != 0)
	    return x;
	throw new InternalException("VariableTerm is not unique");
    }
}
