/*********************************************************************************
 JPlotJFunction.cc
 
	JPlotJFunction class.
 
	Copyright @ 1997 by Glenn W. Bach. All rights reserved.

 ********************************************************************************/

#include <JPlotJFunction.h>
#include <jParseFunction.h>
#include <JVariableList.h>
#include <JFunction.h>
#include <JString.h>
#include <jAssert.h>

/*********************************************************************************
 Create

 ********************************************************************************/

JBoolean
JPlotJFunction::Create
	(
	JPlotJFunction**	plotfunction, 
	J2DPlotWidget*		plot, 
	JVariableList*		varList, 
	const JCharacter*	function, 
	const JIndex		xIndex,
	const JFloat		xMin,
	const JFloat		xMax
	)
{
	JFunction* f;
	if (JParseFunction(function, varList, &f))
		{
		*plotfunction = new JPlotJFunction(plot, varList, f, kTrue, xIndex, xMin, xMax);
		return kTrue;
		}
	else
		{
		*plotfunction = NULL;
		return kFalse;
		}
}

/*********************************************************************************
 Constructor 

 ********************************************************************************/

JPlotJFunction::JPlotJFunction
	(
	J2DPlotWidget*	plot,
	JVariableList*	varList,
	JFunction*		f,
	const JBoolean	ownsFn,
	const JIndex	xIndex,
	const JFloat	xMin,
	const JFloat	xMax
	)
	:
	JPlotFunctionBase(kScatterPlot, plot, xMin, xMax)
{
	itsVarList    = varList;
	itsFunction   = f;
	itsOwnsFnFlag = ownsFn;
	itsXIndex     = xIndex;

	ListenTo(itsVarList);
}

/*********************************************************************************
 Destructor

 ********************************************************************************/

JPlotJFunction::~JPlotJFunction()
{
	if (itsOwnsFnFlag)
		{
		delete itsFunction;
		}
}

/*********************************************************************************
 GetYValue

 ********************************************************************************/

JBoolean
JPlotJFunction::GetYValue
	(
	const JFloat	x,
	JFloat*			y
	)
	const
{
	itsVarList->SetNumericValue(itsXIndex, 1, x);
	return itsFunction->Evaluate(y);
}

/*********************************************************************************
 GetFunctionString (virtual)

 ********************************************************************************/

JString
JPlotJFunction::GetFunctionString()
	const
{
	return itsFunction->Print();
}

/******************************************************************************
 Receive (virtual protected)

 ******************************************************************************/

void
JPlotJFunction::Receive
	(
	JBroadcaster*	sender,
	const Message&	message
	)
{
	if (sender == itsVarList && message.Is(JVariableList::kVarInserted))
		{
		const JVariableList::VarInserted* info =
			dynamic_cast(const JVariableList::VarInserted*, &message);
		assert( info != NULL );
		info->AdjustIndex(&itsXIndex);
		}

	else if (sender == itsVarList && message.Is(JVariableList::kVarRemoved))
		{
		const JVariableList::VarRemoved* info =
			dynamic_cast(const JVariableList::VarRemoved*, &message);
		assert( info != NULL );
		const JBoolean ok = info->AdjustIndex(&itsXIndex);
		assert( ok );	// client must insure this
		}

	else if (sender == itsVarList && message.Is(JVariableList::kVarMoved))
		{
		const JVariableList::VarMoved* info =
			dynamic_cast(const JVariableList::VarMoved*, &message);
		assert( info != NULL );
		info->AdjustIndex(&itsXIndex);
		}

	else if (sender == itsVarList && message.Is(JVariableList::kVarValueChanged))
		{
		const JVariableList::VarValueChanged* info =
			dynamic_cast(const JVariableList::VarValueChanged*, &message);
		assert( info != NULL );
		if (info->GetVarIndex() != itsXIndex)
			{
			UpdateFunction();
			Broadcast(CurveChanged());
			}
		}

	else
		{
		JPlotFunctionBase::Receive(sender, message);
		}
}
