// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3) fieldsfirst 
// 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
{

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

	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);
	}

}
