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

#include "ObjProUsr/ramp.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 * RampNodeList = 0 ;
static InteractiveEntity * IntEntRamp ;
void RampNodesInit();
Ramp::Ramp (const char * Name, int32 Min, int32 Max, int32 Increment):
	Signal(Name, 1, 1, 1, 1, TimingTypeLinear, 
	(ArithType::ArithCapabilities)ArithType::ArithTypeUndefined)
,
	Min_1(Min),
	Max_2(Max),
	Increment_3(Increment)
{
	if (!RampNodeList) RampNodesInit() ;
	RampNodeList->Append(MakeDeclaredEntity(this, IntEntRamp)) ;
	InitArithType(TheArithType);
	NewMenuItem("Ramp",GetName());
#line 40 "../ramp.usr"
 
	NextOut = GetMin();
#line 33 "../ramp.cxx"
} // end constructor

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

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

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

Ramp * RampDef;

ErrCode Ramp::DoNode(int32 k)
{
#line 63 "../ramp.usr"
 
	for (int32 i = 0 ; i < k ; i++ ) {
		WriteWord( (MachWordCast) NextOut) ;
		if ((NextOut += GetIncrement()) > GetMax()) NextOut = GetMin();
	}
	return OK ;
#line 67 "../ramp.cxx"
} // end kernel code

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

void Ramp::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakeRamp(Out,EntityReqDescribeFull,*IntEntRamp, (ArithType::ArithCapabilities) TheArithType);
		Out.NewLine();
		Out.NextQuoteOut("Min");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetMin()));
		Out.NextFillOut(")");
		Out.NextFillOut("is the minimum and initial value of the ramp function.");
		Out.NextQuoteOut("Max");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetMax()));
		Out.NextFillOut(")");
		Out.NextFillOut("is an upper bound on the ramp function. Before exceeding");
		Out.NextQuoteOut("Max");
		Out.NextFillOut("a sample will be reset to");
		Out.NextQuoteOut("Min");
		Out.NextFillOutConcat(".");
		Out.NextQuoteOut("Increment");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetIncrement()));
		Out.NextFillOut(")");
		Out.NextFillOut("is the amount added to the previous sample");
		Out.NextFillOut("to generate the next sample.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntRamp->GetOneParameter("Min")->
			IntP->CurrentValue = Min_1;
		IntEntRamp->GetOneParameter("Max")->
			IntP->CurrentValue = Max_2;
		IntEntRamp->GetOneParameter("Increment")->
			IntP->CurrentValue = Increment_3;
		break;
	}
} // end  list entity switch

static ValueType * SetMin(OutTokens&,EntityReq Request,
		UserParameters * Param,UserEntity *This) 
{
	switch (Request) {
case EntityReqDescribe:
	break ;
case EntityReqDescribeFull:
	break ;
case EntityReqCall:
		{		// Call procedure
				int32 Min =
			Param->GetIntParameterValue("Min");
		((Ramp *) This)->SetMin(Min);
		return 0 ;
	}
	}
	return 0;
}

static ValueType * SetMax(OutTokens&,EntityReq Request,
		UserParameters * Param,UserEntity *This) 
{
	switch (Request) {
case EntityReqDescribe:
	break ;
case EntityReqDescribeFull:
	break ;
case EntityReqCall:
		{		// Call procedure
				int32 Max =
			Param->GetIntParameterValue("Max");
		((Ramp *) This)->SetMax(Max);
		return 0 ;
	}
	}
	return 0;
}

static ValueType * SetIncrement(OutTokens&,EntityReq Request,
		UserParameters * Param,UserEntity *This) 
{
	switch (Request) {
case EntityReqDescribe:
	break ;
case EntityReqDescribeFull:
	break ;
case EntityReqCall:
		{		// Call procedure
				int32 Increment =
			Param->GetIntParameterValue("Increment");
		((Ramp *) This)->SetIncrement(Increment);
		return 0 ;
	}
	}
	return 0;
}

void RampNodesInit()
{
	if (RampNodeList)  return ;

	static StringParam RampNameParam =
		{"Ramp", MakeNewEntityName, 0, LegalEntityName};
	static IntParam RampMinParam = {
		 0, 0, 0, -2.14748e+09, 0, 2.14748e+09};
	static IntParam RampMaxParam = {
		 0, 0, 0, -2.14748e+09, 0, 2.14748e+09};
	static IntParam RampIncrementParam = {
		 1, 0,  0,  1, 0, 2.14748e+09};

	static OneParameter RampParArray[] = {
		{"Name", 0, "node name", 0, 0, &RampNameParam},
		{"Min", 0, 
			"minimum value of ramp sample",
			&RampMinParam},
		{"Max", 0, 
			"maximum value of ramp sample",
			&RampMaxParam},
		{"Increment", 0, 
			"increment between samples",
			&RampIncrementParam},
		{0}
	};

	static OneParameter SetMinRampList[] = {
		{"Min", 0, "minimum value of ramp sample",
			 &RampMinParam},
			{0}
	};
	UserParameters * SetMinMemberParam = new UserParameters
		(SetMinRampList);

	Procedure * SetMemberProcMin = new Procedure("SetMin", SetMin,
		 SetMinMemberParam, "void");
	static OneParameter SetMaxRampList[] = {
		{"Max", 0, "maximum value of ramp sample",
			 &RampMaxParam},
			{0}
	};
	UserParameters * SetMaxMemberParam = new UserParameters
		(SetMaxRampList);

	Procedure * SetMemberProcMax = new Procedure("SetMax", SetMax,
		 SetMaxMemberParam, "void");
	static OneParameter SetIncrementRampList[] = {
		{"Increment", 0, "increment between samples",
			 &RampIncrementParam},
			{0}
	};
	UserParameters * SetIncrementMemberParam = new UserParameters
		(SetIncrementRampList);

	Procedure * SetMemberProcIncrement = new Procedure("SetIncrement", SetIncrement,
		 SetIncrementMemberParam, "void");
static ValueType * RampMembers[4] ;
	int ii = 0 ;
	RampMembers[ii++] = new ValueType(DecProcedure, SetMemberProcMin) ;
	RampMembers[ii++] = new ValueType(DecProcedure, SetMemberProcMax) ;
	RampMembers[ii++] = new ValueType(DecProcedure, SetMemberProcIncrement) ;
	RampMembers[ii++] = 0 ;
	RampNodeList = new EntityList;
	IntEntRamp = new InteractiveEntity("Ramp", RampNodeList,
		MakeRamp, InteractiveSignal, "ramp.h",
		RampMembers, "Signal");
	IntEntRamp->SetParameters(new UserParameters(RampParArray));
	TheNodes->Append(IntEntRamp);
} // end initalization

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

case EntityReqDescribeFull:
		Out.NextQuoteOut("Ramp");
		Out.NextFillOut("generates a linear ramp function with the initial value");
		Out.NextFillOut("of");
		Out.NextQuoteOut("Min");
		Out.NextFillOutConcat(", and increment between samples of");
		Out.NextQuoteOut("Increment");
		Out.NextFillOut("and");
		Out.NextFillOut("upper bound on the output of");
		Out.NextQuoteOut("Max");
		Out.NextFillOutConcat(". At the point where the");
		Out.NextFillOut("next output would exceed");
		Out.NextQuoteOut("Max");
		Out.NextFillOut("it is reset to");
		Out.NextQuoteOut("Min");
		Out.NextFillOutConcat(".");
		Out.NewLine();
		break;

case EntityReqCreate:
	{
		const char * Name = IntNode.GetStringParameterValue("Name");
		int32 Min =
			IntNode.GetIntParameterValue("Min");
		int32 Max =
			IntNode.GetIntParameterValue("Max");
		int32 Increment =
			IntNode.GetIntParameterValue("Increment");
		return new Ramp(Name, Min, Max, Increment);

	}
	}
	return 0;
}

static InitObj LocalInit(RampNodesInit, "Ramp", "Signal");

