#include "ObjProGui/sigintfc.h"
#include "ObjProNet/dfnode.h"

#include "ObjProUsr/cos.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 * CosNodeList = 0 ;
static InteractiveEntity * IntEntCos ;
void CosNodesInit();
Cos::Cos (const char * Name, double Frequency, double Phase, double Amplitude):
	Signal(Name, 1, 1, 1, 1, TimingTypeLinear, 
	(ArithType::ArithCapabilities)ArithType::ArithTypeUndefined)
,
	Frequency_1(Frequency),
	Phase_2(Phase),
	Amplitude_3(Amplitude)
{
	if (!CosNodeList) CosNodesInit() ;
	CosNodeList->Append(MakeDeclaredEntity(this, IntEntCos)) ;
	InitArithType(TheArithType);
	NewMenuItem("Cos",GetName());
#line 47 "../cos.usr"
 
	CurrentIndex = 0;
#line 33 "../cos.cxx"
} // end constructor

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

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

double Cos::TimeFirst( DfNodeInLink * , DfNodeOutLink * )
{
#line 63 "../cos.usr"
	return 0.0 ;
#line 53 "../cos.cxx"
} // end timing code

Cos * CosDef;

ErrCode Cos::DoNode(int32 k)
{
#line 70 "../cos.usr"
 
	for (int32 i = 0 ; i < k ; i++ ) {
		MachWord Value = (MachWordCast) (
			GetAmplitude() * cos (GetPhase() +
				GetFrequency() * CurrentIndex++)) ;
		WriteWord(Value) ;
	}
	return OK ;
#line 69 "../cos.cxx"
} // end kernel code

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

void Cos::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakeCos(Out,EntityReqDescribeFull,*IntEntCos, (ArithType::ArithCapabilities) TheArithType);
		Out.NewLine();
		Out.NextQuoteOut("Frequency");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetFrequency()));
		Out.NextFillOut(")");
		Out.NextFillOut("specifies the signal frequency in radians per");
		Out.NextFillOut("sample. In other words the phase of a given sample is");
		Out.NextQuoteOut("Frequency");
		Out.NextFillOut("radians plus the phase of the previous sample.");
		Out.NextQuoteOut("Phase");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetPhase()));
		Out.NextFillOut(")");
		Out.NextFillOut("specifies the initial phase of the first sample");
		Out.NextFillOut("of the signal.");
		Out.NextQuoteOut("Amplitude");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetAmplitude()));
		Out.NextFillOut(")");
		Out.NextFillOut("specifies the maximum amplitude of the continuous");
		Out.NextFillOut("cosine function. This may not be the maximum");
		Out.NextFillOut("amplitude of the samples generated. If the");
		Out.NextFillOut("function is sampled at a phase that is an integer multiple");
		Out.NextFillOut("of Pi, then the samples will obtain this maximum.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntCos->GetOneParameter("Frequency")->
			FloatP->CurrentValue = Frequency_1;
		IntEntCos->GetOneParameter("Phase")->
			FloatP->CurrentValue = Phase_2;
		IntEntCos->GetOneParameter("Amplitude")->
			FloatP->CurrentValue = Amplitude_3;
		break;
	}
} // end  list entity switch

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

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

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

void CosNodesInit()
{
	if (CosNodeList)  return ;

	static StringParam CosNameParam =
		{"Cos", MakeNewEntityName, 0, LegalEntityName};
	static FloatParam CosFrequencyParam = {
		 0.125663706144, 0,  0,  -3.1416,  0,  3.1416};
	static FloatParam CosPhaseParam = {
		 0.0, 0,  0,  -6.2832,  0,  6.2832};
	static FloatParam CosAmplitudeParam = {
		 1024., 0, 0, -1e+100, 0, 1e+100};

	static OneParameter CosParArray[] = {
		{"Name", 0, "node name", 0, 0, &CosNameParam},
		{"Frequency", 0, 
			"frequency (in radians per sample)",
			0, &CosFrequencyParam},
		{"Phase", 0, 
			"phase (in radians) of first sample",
			0, &CosPhaseParam, 0, 0, 0, 1},
		{"Amplitude", 0, 
			"absolute maximum amplitude of the continuous cosine function",
			0, &CosAmplitudeParam, 0, 0, 0, 1},
		{0}
	};

	static OneParameter SetFrequencyCosList[] = {
		{"Frequency", 0, "frequency (in radians per sample)",
			 0, &CosFrequencyParam},
			{0}
	};
	UserParameters * SetFrequencyMemberParam = new UserParameters
		(SetFrequencyCosList);

	Procedure * SetMemberProcFrequency = new Procedure("SetFrequency", SetFrequency,
		 SetFrequencyMemberParam, "void");
	static OneParameter SetPhaseCosList[] = {
		{"Phase", 0, "phase (in radians) of first sample",
			 0, &CosPhaseParam, 0, 0, 0, 1},
			{0}
	};
	UserParameters * SetPhaseMemberParam = new UserParameters
		(SetPhaseCosList);

	Procedure * SetMemberProcPhase = new Procedure("SetPhase", SetPhase,
		 SetPhaseMemberParam, "void");
	static OneParameter SetAmplitudeCosList[] = {
		{"Amplitude", 0, "absolute maximum amplitude of the continuous cosine function",
			 0, &CosAmplitudeParam, 0, 0, 0, 1},
			{0}
	};
	UserParameters * SetAmplitudeMemberParam = new UserParameters
		(SetAmplitudeCosList);

	Procedure * SetMemberProcAmplitude = new Procedure("SetAmplitude", SetAmplitude,
		 SetAmplitudeMemberParam, "void");
static ValueType * CosMembers[4] ;
	int ii = 0 ;
	CosMembers[ii++] = new ValueType(DecProcedure, SetMemberProcFrequency) ;
	CosMembers[ii++] = new ValueType(DecProcedure, SetMemberProcPhase) ;
	CosMembers[ii++] = new ValueType(DecProcedure, SetMemberProcAmplitude) ;
	CosMembers[ii++] = 0 ;
	CosNodeList = new EntityList;
	IntEntCos = new InteractiveEntity("Cos", CosNodeList,
		MakeCos, InteractiveSignal, "cos.h",
		CosMembers, "Signal");
	IntEntCos->SetParameters(new UserParameters(CosParArray));
	TheNodes->Append(IntEntCos);
	new Cos("Cos8", 0.78539816339744830961, 0.0, 1024.);
} // end initalization

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

case EntityReqDescribeFull:
		Out.NextQuoteOut("Cos");
		Out.NextFillOut("generates the sampled real function:");
		Out.NextQuoteOut("Amplitude");
		Out.NextFillOut("cos(");
		Out.NextFillOutConcat("Phase");
		Out.NextFillOut("+ N");
		Out.NextQuoteOut("Frequency");
		Out.NextFillOutConcat("). N is the sample index that");
		Out.NextFillOut("starts with N = 0.");
		Out.NewLine();
		break;

case EntityReqCreate:
	{
		const char * Name = IntNode.GetStringParameterValue("Name");
		double Frequency =
			IntNode.GetFloatParameterValue("Frequency");
		double Phase =
			IntNode.GetFloatParameterValue("Phase");
		double Amplitude =
			IntNode.GetFloatParameterValue("Amplitude");
		return new Cos(Name, Frequency, Phase, Amplitude);

	}
	}
	return 0;
}

static InitObj LocalInit(CosNodesInit, "Cos", "Signal");

