// 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:   Function.java

package lt.monarch.function;

import lt.monarch.function.node.ConstantNode;

// Referenced classes of package lt.monarch.function:
//			AbstractIdentifier, Variable, Node, Identifier, 
//			NodeCompiler, CompiledFunctionSet

public class Function extends AbstractIdentifier
{

	protected Node body;
	protected Variable params[];

	public int parameterCount()
	{
		return params.length;
	}

	public Variable[] parameters()
	{
		return params;
	}

	public boolean isConstant()
	{
		return body instanceof ConstantNode;
	}

	public Node body()
	{
		return body;
	}

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

		return body.evaluate();
	}

	public Identifier derivative(int i)
	{
		return (Identifier)new Function(name() + "'" + (i + 1), params, body.derivative(params[i]));
	}

	public String javaFunctionName()
	{
		return name().replace('\'', '_');
	}

	public String javaFunctionDescriptor()
	{
		StringBuffer stringbuffer = new StringBuffer();
		for(int i = 0; i < params.length; i++)
			stringbuffer.append('D');

		return "(" + stringbuffer.toString() + ")D";
	}

	public void compile(NodeCompiler nodecompiler)
	{
		nodecompiler.setParameters(params);
		nodecompiler.compile(body);
	}

	public void compileRef(NodeCompiler nodecompiler, Node anode[])
	{
		if(!nodecompiler.functionSet().hasMethod(javaFunctionName(), javaFunctionDescriptor()))
		{
			NodeCompiler nodecompiler1 = new NodeCompiler(nodecompiler.functionSet(), javaFunctionName());
			nodecompiler1.setParameters(true, javaFunctionDescriptor(), params);
			nodecompiler1.compile(body);
			nodecompiler.functionSet().addMethod(nodecompiler1);
		}
		for(int i = 0; i < anode.length; i++)
			anode[i].compile(nodecompiler);

		nodecompiler.appendStaticCall(null, javaFunctionName(), javaFunctionDescriptor());
		nodecompiler.freeStack(2 * (params.length - 1));
	}

	public Function(String s, Variable avariable[], Node node)
	{
		super(s);
		body = node.simplify();
		params = avariable;
	}
}
