import objectdraw.*;

/**
 * Representation for the negation of an expression, regarded as an arithmetic expression
 * 
 * @author Russell C. Bjork 
 * @version March 20, 2008
 */
public class Negation extends Node implements Expression
{
    private Expression subExpression; // The expression being negated
    
    /** Constructor
     * 
     *  @param subExpression the expression being negated
     */
    public Negation(Expression subExpression) {
        this.subExpression = subExpression;
    }
    
    // Methods required by the Expression interface
    
    public String toString() {
        return "(- " + subExpression.toString() + ")";
    }
    
    public double evaluate(double x) {
        return - subExpression.evaluate(x);
    }
    
    public Expression derivative() {
        return new Negation(subExpression.derivative());
    }
    
    public Expression simplify() {
        Expression simplifiedSubExpression = subExpression.simplify();
        if (simplifiedSubExpression instanceof Constant)
            return new Constant(simplifiedSubExpression.evaluate(0));
        else if (simplifiedSubExpression instanceof Negation)
            return ((Negation) simplifiedSubExpression).subExpression;
        else if (simplifiedSubExpression == subExpression)
            return this;
        else
            return new Negation(simplifiedSubExpression);
    }

    public void draw(double x, double y, double width, DrawingCanvas canvas) {
        
        // Calculate positions for root and subtree
        
        double centerX = x + width / 2;
        double centerY = y + TREE_NODE_DIAMETER / 2;
        double subtreeWidth = width / 2;
        double centerXSubtree = centerX + subtreeWidth / 2;
        double subtreeY = y + 2 * TREE_NODE_DIAMETER;
        double centerYSubtree = subtreeY + TREE_NODE_DIAMETER / 2;
        
        // Draw the line connecting the root to the subtree
        
        new Line(centerX, centerY, centerXSubtree, centerYSubtree, canvas);
        
        // Draw a node representing the operator at the root - must be done
        // after drawing the line to cover part of it
        
        drawNode("-", x, y, width, canvas);
              
        // Draw the subtrees
        
        subExpression.draw(x + subtreeWidth, subtreeY, subtreeWidth, canvas);
    }}
