package com.googlecode.prolog_cafe.lang;

import com.googlecode.prolog_cafe.exceptions.EvaluationException;
import com.googlecode.prolog_cafe.exceptions.IllegalTypeException;

/**
 * Integer.<br>
 * The class <code>IntegerTerm</code> wraps a value of primitive type 
 * <code>int</code>. 
 * <pre>
 *   Term t = new IntegerTerm(100);
 *   int i = ((IntegerTerm)t).intValue();
 * </pre>
 *
 * @author Mutsunori Banbara (banbara@kobe-u.ac.jp)
 * @author Naoyuki Tamura (tamura@kobe-u.ac.jp)
 * @version 1.0
 */
public class IntegerTerm extends NumberTerm {
    /** Holds an <code>int</code> value that this <code>IntegerTerm</code> represents. */
    protected int val;

    /** Constructs a new Prolog integer that represents the specified <code>int</code> value. */
    public IntegerTerm(int i) {	val = i; }

    /**
     * Returns the value of <code>val</code>.
     * @see #val
     */
    public int value() { return val; }

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

    /* Term */
    public boolean unify(Term t, Trail trail) {
	if (t instanceof VariableTerm)
	    return ((VariableTerm)t).unify(this, trail);
	if (! (t instanceof IntegerTerm))
	    return false;
	else 
	    return this.val == ((IntegerTerm)t).value();
    }

    /** 
     * @return the <code>boolean</code> whose value is
     * <code>convertible(Integer.class, type)</code>.
     * @see Term#convertible(Class, Class)
     */
    public boolean convertible(Class type) { return convertible(Integer.class, type); }

    public String name() { return ""; }

    /** 
     * Returns a <code>java.lang.Integer</code> corresponds to this <code>IntegerTerm</code>
     * according to <em>Prolog Cafe interoperability with Java</em>.
     * @return a <code>java.lang.Integer</code> object equivalent to
     * this <code>IntegerTerm</code>.
     */
    public Object toJava() { return Integer.valueOf(val); }

    /* Object */
    /** Returns a string representation of this <code>IntegerTerm</code>. */
    public String toString() { return Integer.toString(this.val); }

    /**
     * Checks <em>term equality</em> of two terms.
     * The result is <code>true</code> if and only if the argument is an instance of
     * <code>IntegerTerm</code> and has the same <code>int</code> value as this object.
     * @param obj the object to compare with. This must be dereferenced.
     * @return <code>true</code> if the given object represents a Prolog integer 
     * equivalent to this <code>IntegerTerm</code>, false otherwise.
     * @see #compareTo
    */
    public boolean equals(Object obj) {
	if (! (obj instanceof IntegerTerm))
	    return false;
	return this.val == ((IntegerTerm)obj).value();
    }

    public int hashCode() { return this.val; }

    /* 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 compared 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>.
     */
    public int compareTo(Term anotherTerm) { // anotherTerm must be dereferenced.
	if (anotherTerm instanceof VariableTerm || anotherTerm instanceof DoubleTerm)
	    return AFTER;
	if (! (anotherTerm instanceof IntegerTerm))
	    return BEFORE;
	int v = ((IntegerTerm)anotherTerm).value();
	if (this.val == v)
	    return EQUAL;
	if (this.val > v)
	    return AFTER;
	return BEFORE;
    }

    /* NumberTerm */
    public int intValue() { return this.val; }

    public long longValue() { return (long)(this.val); }

    public double doubleValue() { return (double)(this.val); }

    public int arithCompareTo(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    return - (t.arithCompareTo(this));
	int v = t.intValue();
	if (this.val == v)
	    return EQUAL;
	if (this.val > v)
	    return AFTER;
	return BEFORE;
    }

    public NumberTerm abs() { return new IntegerTerm(Math.abs(this.val)); }

    public NumberTerm acos() { return new DoubleTerm(Math.acos(this.doubleValue())); }

    public NumberTerm add(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    return t.add(this);
	return new IntegerTerm(this.val + t.intValue());
    }

    /** 
     * @exception IllegalTypeException if the given argument
     * <code>NumberTerm</code> is a floating point number.
     */
    public NumberTerm and(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    throw new IllegalTypeException("integer", t);
	return new IntegerTerm(this.val & t.intValue());
    }

    public NumberTerm asin() { return new DoubleTerm(Math.asin(this.doubleValue())); }

    public NumberTerm atan() { return new DoubleTerm(Math.atan(this.doubleValue())); }

    public NumberTerm ceil() { return this; }

    public NumberTerm cos() { return new DoubleTerm(Math.cos(this.doubleValue())); }

    /** 
     * @exception EvaluationException if the given argument
     * <code>NumberTerm</code> represents <coe>0</code>.
     */
    public NumberTerm divide(NumberTerm t) { 
	if (t.doubleValue() == 0)
	    throw new EvaluationException("zero_divisor");
	return new DoubleTerm(this.doubleValue() / t.doubleValue()); 
    }

    public NumberTerm exp() { return new DoubleTerm(Math.exp(this.doubleValue())); }

    public NumberTerm floatIntPart() { throw new IllegalTypeException("float", this); }

    public NumberTerm floatFractPart() { throw new IllegalTypeException("float", this); }

    public NumberTerm floor() { return this; }

    /** 
     * @exception IllegalTypeException if the given argument
     * <code>NumberTerm</code> is a floating point number.
     * @exception EvaluationException if the given argument
     * <code>NumberTerm</code> represents <coe>0</code>.
     */
    public NumberTerm intDivide(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    throw new IllegalTypeException("integer", t);
	if (t.intValue() == 0)
	    throw new EvaluationException("zero_divisor");
	return new IntegerTerm((int) (this.val / t.intValue()));
    }

    /** 
     * @exception EvaluationException if this object represents <coe>0</code>.
     */
    public NumberTerm log() { 
	if (this.val == 0)
	    throw new EvaluationException("undefined");
	return new DoubleTerm(Math.log(this.doubleValue())); 
    }

    public NumberTerm max(NumberTerm t) {
	if (t instanceof DoubleTerm) 
	    return t.max(this);
	return new IntegerTerm(Math.max(this.val, t.intValue()));
    }

    public NumberTerm min(NumberTerm t) {
	if (t instanceof DoubleTerm) 
	    return t.min(this);
	return new IntegerTerm(Math.min(this.val, t.intValue()));
    }

    /** 
     * @exception IllegalTypeException if the given argument
     * <code>NumberTerm</code> is a floating point number.
     * @exception EvaluationException if the given argument
     * <code>NumberTerm</code> represents <coe>0</code>.
     */
    public NumberTerm mod(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    throw new IllegalTypeException("integer", t);
	if (t.intValue() == 0)
	    throw new EvaluationException("zero_divisor");
	return new IntegerTerm(this.val % t.intValue());
    }

    public NumberTerm multiply(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    return t.multiply(this);
	return new IntegerTerm(this.val * t.intValue());
    }

    public NumberTerm negate() { return new IntegerTerm(- this.val); }

    public NumberTerm not() { return new IntegerTerm(~ this.val); }

    /** 
     * @exception IllegalTypeException if the given argument
     * <code>NumberTerm</code> is a floating point number.
     */
    public NumberTerm or(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    throw new IllegalTypeException("integer", t);
	return new IntegerTerm(this.val | t.intValue());
    }

    public NumberTerm pow(NumberTerm t) { return new DoubleTerm(Math.pow(this.doubleValue(), t.doubleValue())); }

    public NumberTerm rint() { return new DoubleTerm(this.doubleValue()); }

    public NumberTerm round() { return this; }

    /** 
     * @exception IllegalTypeException if the given argument
     * <code>NumberTerm</code> is a floating point number.
     */
    public NumberTerm shiftLeft(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    throw new IllegalTypeException("integer", t);
	return new IntegerTerm(this.val << t.intValue());
    }

    /** 
     * @exception IllegalTypeException if the given argument
     * <code>NumberTerm</code> is a floating point number.
     */
    public NumberTerm shiftRight(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    throw new IllegalTypeException("integer", t);
	return new IntegerTerm(this.val >> t.intValue());
    }

    public NumberTerm signum() {return new IntegerTerm((int) Math.signum((double) this.val)); }

    public NumberTerm sin() { return new DoubleTerm(Math.sin(this.doubleValue())); }

    /** 
     * @exception EvaluationException if this object represents
     * an integer less than <coe>0</code>.
     */
    public NumberTerm sqrt() { 
	if (this.val < 0)
	    throw new EvaluationException("undefined");
	return new DoubleTerm(Math.sqrt(this.doubleValue())); 
    }

    public NumberTerm subtract(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    return new DoubleTerm(this.doubleValue() - t.doubleValue());
	return new IntegerTerm(this.val - t.intValue());
    }

    public NumberTerm tan() { return new DoubleTerm(Math.tan(this.doubleValue())); }

    public NumberTerm toDegrees() { return new DoubleTerm(Math.toDegrees(this.doubleValue())); }

    public NumberTerm toFloat() { return new DoubleTerm((double) this.val); }

    public NumberTerm toRadians() { return new DoubleTerm(Math.toRadians(this.doubleValue())); }

    public NumberTerm truncate() { return this; }

    /** 
     * @exception IllegalTypeException if the given argument
     * <code>NumberTerm</code> is a floating point number.
     */
    public NumberTerm xor(NumberTerm t) {
	if (t instanceof DoubleTerm)
	    throw new IllegalTypeException("integer", t);
	return new IntegerTerm(this.val ^ t.intValue());
    }
}
