#include <complex.h>
#include <signal.h>
#include "ObjProDSP/portable.h"
#include "ObjProComGui/usercom.h"
#include "ObjProArith/hrdarth.h"
#include "ObjProArithGen/arthfnc.h"
#include "ObjProComGui/cgidbg.h"
#include "ObjProArithGen/artherr.h"
#include "ObjProDSPint/netlnk.h"
#include "ObjProNet/dfnode.h"

#include "ObjProUsr/integ.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"
static EntityList * IntegrateNodeList = 0 ;
static InteractiveEntity * IntEntIntegrate ;
void IntegrateNodesInit();
Integrate::Integrate (const char * Name, int32 IntegrationSize, int32 OutputStep, 
		double Scale):
	ProcessNodeStr(Name, 1, 1, new StreamStr(StreamNotSet), 
	new StreamStr(StreamNotSet), 0, OutputStep, 1, IntegrationSize ? IntegrationSize - 1 : 0, 0, 
	TimingTypeLinear)
,
	IntegrationSize_1(IntegrationSize),
	OutputStep_2(OutputStep),
	Scale_3(Scale)
{
	if (!IntegrateNodeList) IntegrateNodesInit() ;
	IntegrateNodeList->Append(MakeDeclaredEntity(this, IntEntIntegrate)) ;
	InitArithType(TheArithType);
	NewMenuItem("Integrate",GetName());
#line 66 "../integ.usr"
 
	ctor();
#line 43 "../integ.cxx"
} // end constructor

Integrate::~Integrate()
{
	TheMenuServer->DeleteMenuItem("Integrate",GetName());
	IntegrateNodeList->Delete(GetName()) ;
#line 70 "../integ.usr"
 
	dtor();
#line 53 "../integ.cxx"
} // end destructor

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

Integrate * IntegrateDef;

ErrCode Integrate::DoNode(int32 k)
{
#line 91 "../integ.usr"
 
	return kernel(k);
#line 70 "../integ.cxx"
} // end kernel code

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

void Integrate::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakeIntegrate(Out,EntityReqDescribeFull,*IntEntIntegrate, (ArithType::ArithCapabilities) TheArithType);
		Out.NewLine();
		Out.NextQuoteOut("IntegrationSize");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetIntegrationSize()));
		Out.NextFillOut(")");
		Out.NextFillOut("is the number of samples to sum.");
		Out.NextFillOut("An output is generated for every");
		Out.NextQuoteOut("OutputStep");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetOutputStep()));
		Out.NextFillOut(")");
		Out.NextFillOut("inputs.");
		Out.NextFillOut("The number of buffers that must be maintained");
		Out.NextFillOut("is");
		Out.NextQuoteOut("IntegrationSize");
		Out.NextFillOut("/");
		Out.NextQuoteOut("OutputStep");
		Out.NextFillOutConcat(".");
		Out.NextQuoteOut("Scale");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetScale()));
		Out.NextFillOut(")");
		Out.NextFillOut("multiplies each output sample.");
		Out.NextFillOut("The intermediate arithmetic is done in double floating point");
		Out.NextFillOut("point.");
		Out.NextQuoteOut("Scale");
		Out.NextFillOut("is applied to the final output");
		Out.NextFillOut("point before it is converted to MachWord.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntIntegrate->GetOneParameter("IntegrationSize")->
			IntP->CurrentValue = IntegrationSize_1;
		IntEntIntegrate->GetOneParameter("OutputStep")->
			IntP->CurrentValue = OutputStep_2;
		IntEntIntegrate->GetOneParameter("Scale")->
			FloatP->CurrentValue = Scale_3;
		break;
	}
} // end  list entity switch

static ValueType * SetScale(OutTokens&,EntityReq Request,
		UserParameters * Param,UserEntity *This) 
{
	switch (Request) {
case EntityReqDescribe:
	break ;
case EntityReqDescribeFull:
	break ;
case EntityReqCall:
		{		// Call procedure
				double Scale =
			Param->GetFloatParameterValue("Scale");
		((Integrate *) This)->SetScale(Scale);
		return 0 ;
	}
	}
	return 0;
}

void IntegrateNodesInit()
{
	if (IntegrateNodeList)  return ;

	static StringParam IntegrateNameParam =
		{"Integrate", MakeNewEntityName, 0, LegalEntityName};
	static IntParam IntegrateIntegrationSizeParam = {
		 1, 0,  0,  0, 0, 2.14748e+09};
	static IntParam IntegrateOutputStepParam = {
		 1, 0,  0,  1, 0, 2.14748e+09};
	static FloatParam IntegrateScaleParam = {
		 1.0, 0, 0, -1e+100, 0, 1e+100};

	static OneParameter IntegrateParArray[] = {
		{"Name", 0, "node name", 0, 0, &IntegrateNameParam},
		{"IntegrationSize", 0, 
			"Number of samples to sum",
			&IntegrateIntegrationSizeParam},
		{"OutputStep", 0, 
			"number of input samples for one output",
			&IntegrateOutputStepParam, 0, 0, 0, 0, 1},
		{"Scale", 0, 
			"output is scaled by this factor",
			0, &IntegrateScaleParam, 0, 0, 0, 1},
		{0}
	};

	static OneParameter SetScaleIntegrateList[] = {
		{"Scale", 0, "output is scaled by this factor",
			 0, &IntegrateScaleParam, 0, 0, 0, 1},
			{0}
	};
	UserParameters * SetScaleMemberParam = new UserParameters
		(SetScaleIntegrateList);

	Procedure * SetMemberProcScale = new Procedure("SetScale", SetScale,
		 SetScaleMemberParam, "void");
static ValueType * IntegrateMembers[2] ;
	int ii = 0 ;
	IntegrateMembers[ii++] = new ValueType(DecProcedure, SetMemberProcScale) ;
	IntegrateMembers[ii++] = 0 ;
	IntegrateNodeList = new EntityList;
	IntEntIntegrate = new InteractiveEntity("Integrate", IntegrateNodeList,
		MakeIntegrate, InteractiveNode, "integ.h",
		IntegrateMembers, "ProcessNodeStr");
	IntEntIntegrate->SetParameters(new UserParameters(IntegrateParArray));
	TheNodes->Append(IntEntIntegrate);
} // end initalization

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

case EntityReqDescribeFull:
		Out.NextQuoteOut("Integrate");
		Out.NextFillOut("sums");
		Out.NextQuoteOut("IntegrationSize");
		Out.NextFillOut("consecutive samples and");
		Out.NextFillOut("outputs this sum for every");
		Out.NextQuoteOut("OutputStep");
		Out.NextFillOut("input samples.");
		Out.NextFillOut("In effect it is a Fir filter with all the coefficients equal");
		Out.NextFillOut("to 1.");
		Out.NextFillOut("If");
		Out.NextQuoteOut("IntegrationSize");
		Out.NextFillOut("is 0 then the sum is continuous and");
		Out.NextFillOut("the output is normalized by the number of samples. The");
		Out.NextFillOut("summation is done in double floating point. The output");
		Out.NextFillOut("is scaled by");
		Out.NextQuoteOut("Scale");
		Out.NextFillOut("before being converted to `MachWord'.");
		Out.NewLine();
		break;

case EntityReqCreate:
	{
		const char * Name = IntNode.GetStringParameterValue("Name");
		int32 IntegrationSize =
			IntNode.GetIntParameterValue("IntegrationSize");
		int32 OutputStep =
			IntNode.GetIntParameterValue("OutputStep");
		double Scale =
			IntNode.GetFloatParameterValue("Scale");
		return new Integrate(Name, IntegrationSize, OutputStep, Scale);

	}
	}
	return 0;
}

static InitObj LocalInit(IntegrateNodesInit, "Integrate", "ProcessNodeStr");

