// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) space 
// Source File Name:   IdentifierNode.java

package lt.monarch.function.node;

import lt.monarch.function.*;

// Referenced classes of package lt.monarch.function.node:
//            AbstractNode, ConstantNode, MulNode, PlusNode

public class IdentifierNode extends AbstractNode
{

    public void visited(lt.monarch.function.Node.Visitor visitor)
    {
        super.visited(visitor);
        for (int i = 0; i < params.length; i++)
            params[i].visited(visitor);

    }

    public Node cloneNode()
    {
        Node anode[] = new Node[params.length];
        for (int i = 0; i < anode.length; i++)
            anode[i] = params[i].cloneNode();

        return (Node)new IdentifierNode(identifier, anode);
    }

    public String toString()
    {
        StringBuffer stringbuffer = new StringBuffer(identifier.name());
        if (params.length != 0)
        {
            stringbuffer.append("(");
            for (int i = 0; i < params.length; i++)
            {
                if (i != 0)
                    stringbuffer.append(", ");
                stringbuffer.append(params[i].toString());
            }

            stringbuffer.append(")");
        }
        return stringbuffer.toString();
    }

    public Node simplify()
    {
        if (identifier instanceof MacroIdentifier)
            return ((MacroIdentifier)identifier).expand(params);
        boolean flag = true;
        for (int i = 0; i < params.length; i++)
        {
            params[i] = params[i].simplify();
            flag &= params[i] instanceof ConstantNode;
        }

        if (params.length != 0 && flag || identifier.isConstant())
            return (Node)new ConstantNode(evaluate());
        else
            return (Node)this;
    }

    public double evaluate()
    {
        for (int i = 0; i < params.length; i++)
            values[i] = params[i].evaluate();

        return identifier.evaluate(values);
    }

    public boolean equals(Object obj)
    {
        if (!super.equals(obj))
        {
            return false;
        } else
        {
            IdentifierNode identifiernode = (IdentifierNode)obj;
            return identifier.equals(identifiernode.identifier) && paramsEquals(identifiernode.params);
        }
    }

    private boolean paramsEquals(Node anode[])
    {
        if (anode.length != params.length)
            return false;
        for (int i = 0; i < params.length; i++)
            if (!params[i].equals(anode[i]))
                return false;

        return true;
    }

    public Node derivative(Variable variable)
    {
        if (variable == identifier)
            return (Node)new ConstantNode(1.0D);
        Object obj = new ConstantNode(0.0D);
        for (int i = 0; i < params.length; i++)
        {
            IdentifierNode identifiernode = new IdentifierNode(identifier.derivative(i), params);
            Node node = params[i].derivative(variable);
            Node node1 = (new MulNode(identifiernode, node)).simplifyOperation();
            obj = (new PlusNode(((Node) (obj)), node1)).simplifyOperation();
        }

        return ((Node) (obj));
    }

    public void compile(NodeCompiler nodecompiler)
    {
        identifier.compileRef(nodecompiler, params);
    }

    public IdentifierNode(Identifier identifier1, Node anode[])
    {
        identifier = identifier1;
        params = anode;
        if (params.length != 0)
            values = new double[params.length];
    }

    public IdentifierNode(Identifier identifier1, Node node)
    {
        this(identifier1, new Node[] {
            node
        });
    }

    public IdentifierNode(Identifier identifier1)
    {
        this(identifier1, noParams);
    }

    protected static Node noParams[] = new Node[0];
    protected Identifier identifier;
    protected Node params[];
    protected double values[];

}
