#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/tomach.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 * ToMachNodeList = 0 ;
static InteractiveEntity * IntEntToMach ;
void ToMachNodesInit();
ToMach::ToMach (const char * Name, int16 SignedConversion):
	ProcessNodeStr(Name, 1, 1, 
	 new StreamStr(SizeVariable , SizeVariable , ArithType::ArithCapabilityAnyInt), new StreamStr(StreamNotSet), 0, 1, 1, 0, 0, TimingTypeLinear)
,
	SignedConversion_1(SignedConversion)
{
	if (!ToMachNodeList) ToMachNodesInit() ;
	ToMachNodeList->Append(MakeDeclaredEntity(this, IntEntToMach)) ;
	InitArithType(TheArithType);
	NewMenuItem("ToMach",GetName());
#line 36 "../tomach.usr"
 
#line 38 "../tomach.cxx"
} // end constructor

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

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

ToMach * ToMachDef;

ErrCode ToMach::DoNode(int32 k)
{
#line 53 "../tomach.usr"
 
	int32 left = k * GetBlockSize() * GetEltSize();
	int32 total = left ;
	int32 in = 0 ;
	int32 out= 0 ;
	int32 i;
	do {
		if (!in) in = GetContiguousAvailableData();
		int32 * pin = (int32 *) GetBinReadPtr();
		if (!out) out = GetContiguousSpace();
		MachWord * pout = GetWritePtr();
		int32 to_do =  left ;
		if (to_do > in) to_do = in ;
		if (to_do > out) to_do = out ;
		if (to_do < 1) break ;
		// for (i = 0 ; i < to_do; i++) LogOut << (MachWordCast) pin[i] << " Cast\n" ;
		// for (i = 0 ; i < to_do; i++) LogOut << pin[i] << " in\n" ;
		if (GetSignedConversion()) for (i = 0 ; i < to_do; i++)
			pout[i] = (MachWordCast) (IntegerMachWord) pin[i];
		else for (i = 0 ; i < to_do; i++) pout[i] = (MachWordCast) pin[i];
		// for (i = 0 ; i < to_do; i++) LogOut << pout[i] << " out\n" ;
		in -=to_do ;
		out -=to_do ;
		left -=to_do ;
		UpdateRead(to_do);
		UpdateWrite(to_do);
	} while (left);
	return OK ;
#line 87 "../tomach.cxx"
} // end kernel code

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

void ToMach::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakeToMach(Out,EntityReqDescribeFull,*IntEntToMach, (ArithType::ArithCapabilities) TheArithType);
		Out.NewLine();
		Out.NextFillOut("If");
		Out.NextQuoteOut("SignedConversion");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetSignedConversion()));
		Out.NextFillOut(")");
		Out.NextFillOut("is set the input integer will treated as");
		Out.NextFillOut("a two's compliment signed value. Otherwise it will be considered");
		Out.NextFillOut("unsigned.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntToMach->GetOneParameter("SignedConversion")->
			IntP->CurrentValue = SignedConversion_1;
		break;
	}
} // end  list entity switch

void ToMachNodesInit()
{
	if (ToMachNodeList)  return ;

	static StringParam ToMachNameParam =
		{"ToMach", MakeNewEntityName, 0, LegalEntityName};
	static IntParam ToMachSignedConversionParam = {
		 0, 0,  0,  0,  0,  1};

	static OneParameter ToMachParArray[] = {
		{"Name", 0, "node name", 0, 0, &ToMachNameParam},
		{"SignedConversion", 0, 
			"conversion of unsigned(0) or signed(1) integer input to `MachWord",
			&ToMachSignedConversionParam},
		{0}
	};

	ToMachNodeList = new EntityList;
	IntEntToMach = new InteractiveEntity("ToMach", ToMachNodeList,
		MakeToMach, InteractiveNode, "tomach.h",
		0, "ProcessNodeStr");
	IntEntToMach->SetParameters(new UserParameters(ToMachParArray));
	TheNodes->Append(IntEntToMach);
} // end initalization

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

case EntityReqDescribeFull:
		Out.NextQuoteOut("ToMach");
		Out.NextFillOut("converts a binary data stream to type");
		Out.NextFillOut("`MachWord'");
		Out.NextFillOutConcat(".");
		Out.NextFillOut("If");
		Out.NextQuoteOut("SignedConversion");
		Out.NextFillOut("is set the input will be treated as");
		Out.NextFillOut("two's compliment signed values. Otherwise it will be treated");
		Out.NextFillOut("as unsigned.");
		Out.NextFillOut("The inverse operation is");
		Out.NextFillOut("`ToInteger'");
		Out.NextFillOutConcat(".");
		Out.NextFillOut("`ToInteger'");
		Out.NextFillOut("and");
		Out.NextFillOut("`ToMach'");
		Out.NextFillOut("are meaningless and not available on the 16 bit");
		Out.NextFillOut("integer simulator.");
		Out.NewLine();
		break;

case EntityReqCreate:
	{
		const char * Name = IntNode.GetStringParameterValue("Name");
		int16 SignedConversion =
			IntNode.GetIntParameterValue("SignedConversion");
		return new ToMach(Name, SignedConversion);

	}
	}
	return 0;
}

static InitObj LocalInit(ToMachNodesInit, "ToMach", "ProcessNodeStr");

