/**
 * Representation for the product of two subexpressions
 * 
 * @author Rusell C. Bjork
 * @version March 26, 2008
 */
public class Product extends BinaryOperation
{
    /** Constructor
     * 
     *  @param left the first subexpression
     *  @param right the second subexpression
     */
    public Product(Expression left, Expression right) {
        super(left, '*', right);
    }
   
    // toString is inherited from BinaryOperation
    
    public double evaluate(double x) {
        return left.evaluate(x) * right.evaluate(x);
    }
    
    public Expression derivative() {
        Expression vDu = new Product(right, left.derivative());
        Expression uDv = new Product(left, right.derivative());
        return new Sum(vDu, uDv);
    }
    
    // simplify() is inherited from Binary Operation
    
    public Expression simplify(Expression simplifiedLeft,
                               Expression simplifiedRight) {
        if (simplifiedLeft instanceof Constant && simplifiedLeft.evaluate(0) == 0)
            return new Constant(0);
        else if (simplifiedRight instanceof Constant && simplifiedRight.evaluate(0) == 0)
            return new Constant(0);
        else if (simplifiedLeft instanceof Constant && simplifiedLeft.evaluate(0) == 1)
            return simplifiedRight;
        else if (simplifiedRight instanceof Constant && simplifiedRight.evaluate(0) == 1)
            return simplifiedLeft;
        else if (simplifiedLeft instanceof Constant && simplifiedLeft.evaluate(0) == -1)
            return new Negation(simplifiedRight).simplify();
        else if (simplifiedRight instanceof Constant && simplifiedRight.evaluate(0) == -1)
            return new Negation(simplifiedLeft).simplify();
        else if (simplifiedLeft == left && simplifiedRight == right)
            return this;
        else
            return new Product(simplifiedLeft, simplifiedRight);
    }
    
    // draw is inherited from BinaryOperation
}
