#include <complex.h>
#include "ObjProArith/hrdarth.h"
#include "ObjProGui/sigintfc.h"
#include "ObjProComGui/cgidbg.h"
#include "ObjProDSP/pltenm.h"
#include "ObjProNet/dfnode.h"

#include "ObjProUsr/dyplot.h"
#include "ObjProGen/outtok.h"
#include "ObjProGui/intfc.h"
#include "ObjProGui/remmen.h"
#include "ObjProGui/user.h"
#include "ObjProGui/dynmnu.h"
#include "ObjProArith/typout.h"
#include "ObjProGui/array.h"
#include "ObjProGui/interinit.h"
#include "ObjProGen/stattyp.h"
#include "ObjProGui/yacintfc.h"
static EntityList * PlotNodeList = 0 ;
static InteractiveEntity * IntEntPlot ;
void PlotNodesInit();
Plot::Plot (const char * Name, const char * Caption):
	GenericBlockPlotStr(Name, 
	 new StreamStr(SizeVariable , SizeVariable , ArithType::ArithCapabilityAny), Caption, 0.000000e+00, 0.000000e+00, 0.000000e+00, 0.000000e+00, 
	1, 0, TimingTypeLinear, PlotDynDyn)
,
	Caption_1(Caption)
{
	if (!PlotNodeList) PlotNodesInit() ;
	PlotNodeList->Append(MakeDeclaredEntity(this, IntEntPlot)) ;
	InitArithType(TheArithType);
	NewMenuItem("Plot",GetName());
#line 46 "../dyplot.usr"
 
#ifdef INTERACTIVE
	set_delete_if_unlinked();
#endif
#line 39 "../dyplot.cxx"
} // end constructor

Plot::~Plot()
{
	TheMenuServer->DeleteMenuItem("Plot",GetName());
	PlotNodeList->Delete(GetName()) ;
} // end destructor

int Plot::CheckSafeDelete()
{
	int Safe_Check_Return = DfNode::CheckSafeDelete();
	if (!Safe_Check_Return) return 0;
	return 1;
} // end check safe delete

double Plot::TimeFirst( DfNodeInLink * , DfNodeOutLink * )
{
#line 69 "../dyplot.usr"
	return 0.0;
	// timing is irrelevant for a node with no output channels
#line 60 "../dyplot.cxx"
} // end timing code

Plot * PlotDef;

ErrCode Plot::DoNode(int32 k)
{
#line 74 "../dyplot.usr"
 
	if (State.IsError()) return FatalError ;
	CheckSetup() ;
	// int count = 0 ;
	int BlockS = 1 ;
	int EltSz = GetDriverElementSize(0);
	if (GetBlockSize()) BlockS = GetBlockSize() ;
	for (int32 i = 0 ; i < k ; i++ )
	    for (int32 j = 0 ; j < EltSz; j++)
	    for (int32 l = 0 ; l < BlockS; l++) {
			if (State.IsError()) return FatalError ;
			MachWord Next ;
			if (binary_read_flag) Next = ReadInteger();
			else Next = ReadWord();
			WriteDataWord(Next);
			// count++ ;
	}
	// LogOut << "Wrote " << count << "words.\n" ;
	WriteBuffer(0);
	return OK ;
#line 88 "../dyplot.cxx"
} // end kernel code

static UserEntity * MakePlot(OutTokens& Out, EntityReq Request,
	InteractiveEntity& IntNode,
	ArithType::ArithCapabilities arith = (ArithType::ArithCapabilities) TheArithType) ;
int Plot::CppList(OutTokens& Out, CppListCmds Cmd)
{
	return IntEntPlot->CppList(Out,Cmd,this);
}

void Plot::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakePlot(Out,EntityReqDescribeFull,*IntEntPlot, (ArithType::ArithCapabilities) TheArithType);
		Out.NewLine();
		Out.NextFillOut("The");
		Out.NextQuoteOut("Caption");
		Out.NextQuoteOut(GetCaption());
		Out.NextFillOut("is displayed");
		Out.NextFillOut("at the base of the plot. The default value of 0");
		Out.NextFillOut("causes the plot node name to be used for the caption.");
		Out.NextFillOut("The caption cannot contain blanks. Use underscore instead.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntPlot->GetOneParameter("Caption")->
			StringP->CurrentValue = Caption_1;
		break;
	}
} // end  list entity switch

void PlotNodesInit()
{
	if (PlotNodeList)  return ;

	static StringParam PlotNameParam =
		{"Plot", MakeNewEntityName, 0, LegalEntityName};
	static StringParam PlotCaptionParam = {
		 0, 0, 0};

	static OneParameter PlotParArray[] = {
		{"Name", 0, "node name", 0, 0, &PlotNameParam},
		{"Caption", 0, 
			"plot caption",
			0, 0, &PlotCaptionParam},
		{0}
	};

	PlotNodeList = new EntityList;
	IntEntPlot = new InteractiveEntity("Plot", PlotNodeList,
		MakePlot, InteractiveDisplay, "dyplot.h",
		0, "GenericBlockPlotStr");
	IntEntPlot->SetParameters(new UserParameters(PlotParArray));
	TheNodes->Append(IntEntPlot);
} // end initalization

static UserEntity * MakePlot(OutTokens& Out, EntityReq Request,
	InteractiveEntity& IntNode,
	ArithType::ArithCapabilities arith)
{
	switch(Request) {
case EntityReqDescribe:

case EntityReqDescribeFull:
		Out.NextQuoteOut("Plot");
		Out.NextFillOut("displays signals in graphical form.");
		Out.NextFillOut("The plot can be captioned by setting");
		Out.NextQuoteOut("Caption");
		Out.NextFillOutConcat(".");
		Out.NextFillOut("If");
		Out.NextQuoteOut("Caption");
		Out.NextFillOut("is the default (0) a caption is constructed");
		Out.NextFillOut("from the plot node name and the name of its driver node.");
		Out.NextFillOut("The data is auto-scaled. You can display it with a fixed scale and");
		Out.NextFillOut("alternate between the default full scale display and a  fixed scale.");
		Out.NextFillOut("See the help file on `change plot detail' accessible under `Help' in the menu bar");
		Out.NextFillOut("in any plot window.");
		Out.NewLine();
		break;

case EntityReqCreate:
	{
		const char * Name = IntNode.GetStringParameterValue("Name");
		const char * Caption =
			IntNode.GetStringParameterValue("Caption");
		return new Plot(Name, Caption);

	}
	}
	return 0;
}

static InitObj LocalInit(PlotNodesInit, "Plot", "GenericBlockPlotStr");

