#include <stream.h>
#include <fcntl.h>
#include <unistd.h>
#include "ObjProComGui/cgidbg.h"
#include "ObjProDSP/sysintfc.h"
#include "ObjProGui/yacintfc.h"
#include "ObjProDSPcom/outfile.h"
#include "ObjProGui/remcom.h"
#include "ObjProNet/dfnode.h"

#include "ObjProUsr/outnode.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 "ObjProDSPcom/ramio.h"
static EntityList * OutputNodeNodeList = 0 ;
static InteractiveEntity * IntEntOutputNode ;
void OutputNodeNodesInit();
OutputNode::OutputNode (const char * Name, const char * FileName, int16 Flags, 
		int16 Channels, int32 FileBlockSize, const char * Caption, 
		int32 DeltaIn):
	DisplayNodeStr(Name, Channels, DeltaIn, 
	 new StreamStr(SizeVariable , SizeVariable , ArithType::ArithCapabilityAny), TimingTypeLinear)
,
	FileName_1(FileName),
	Flags_2(Flags),
	Channels_3(Channels),
	FileBlockSize_4(FileBlockSize),
	Caption_5(Caption),
	DeltaIn_6(DeltaIn)
{
	if (!OutputNodeNodeList) OutputNodeNodesInit() ;
	OutputNodeNodeList->Append(MakeDeclaredEntity(this, IntEntOutputNode)) ;
	InitArithType(TheArithType);
	NewMenuItem("OutputNode",GetName());
#line 125 "../outnode.usr"
 
    already_set = 0 ;
#line 46 "../outnode.cxx"
#line 130 "../outnode.usr"
 
#ifdef INTERACTIVE
	set_delete_if_unlinked();
#endif
	Ctor();
#line 53 "../outnode.cxx"
} // end constructor

ErrCode OutputNode::EmitStaticCtorParameters(OutTokens& Out)
{
	ostream& Outs = *(Out.GetStream());
	Outs << ",\n\tOutputNodeStaticInitbinary_read_flag_" << GetName() << "";
	return OK;
}

ErrCode OutputNode::EmitStaticInit(OutTokens& Out)
{
	ostream& Outs = *(Out.GetStream());
	Outs << "static int OutputNodeStaticInitbinary_read_flag_" << GetName() << " = ";	
	OutStringStaticValue(Outs,"int", &(binary_read_flag)) ;

	Outs << ";\n";
	return OK;
}

OutputNode::~OutputNode()
{
	TheMenuServer->DeleteMenuItem("OutputNode",GetName());
	OutputNodeNodeList->Delete(GetName()) ;
#line 137 "../outnode.usr"
 
	Dtor();
#line 80 "../outnode.cxx"
} // end destructor

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

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

OutputNode * OutputNodeDef;

ErrCode OutputNode::DoNode(int32 k)
{
#line 172 "../outnode.usr"
 
	return TheKernel(k);
#line 105 "../outnode.cxx"
} // end kernel code

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

void OutputNode::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakeOutputNode(Out,EntityReqDescribeFull,*IntEntOutputNode, (ArithType::ArithCapabilities) TheArithType);
		Out.NewLine();
		Out.NextQuoteOut("FileName");
		Out.NextQuoteOut(GetFileName());
		Out.NextFillOut("specifies the name of the disk file");
		Out.NextFillOut("to be created. If no caption is specified");
		Out.NextFillOut("(default 0) then the node name will be used.");
		Out.NextFillOut("if bit 1 of");
		Out.NextQuoteOut("Flags");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetFlags()));
		Out.NextFillOut(")");
		Out.NextFillOut("is set then an existing file with");
		Out.NextFillOut("the same name is overwritten without comment.");
		Out.NextFillOut("If the overwrite option is");
		Out.NextFillOut("not set and a file with the same name exists");
		Out.NextFillOut("this node will not be initialized properly in non interactive");
		Out.NextFillOut("mode and network execution will fail. In interactive mode,");
		Out.NextFillOut("you will be asked to supply a new name.");
		Out.NextFillOut("if bit 8 is set (Flags&8) is true then the data will be");
		Out.NextFillOut("converted from whatever format the input channel is to");
		Out.NextFillOut("32 bit integer data and written in that format. The data");
		Out.NextFillOut("is hard limited.");
		Out.NextQuoteOut("OutputNode");
		Out.NextFillOut("writes");
		Out.NextQuoteOut("Channels");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetChannels()));
		Out.NextFillOut(")");
		Out.NextFillOut("of data to a disk file.");
		Out.NextQuoteOut("FileBlockSize");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetFileBlockSize()));
		Out.NextFillOut(")");
		Out.NextFillOut("determines the number of consecutive");
		Out.NextFillOut("samples written to each channel. Making this larger");
		Out.NextFillOut("reduces the number of disk accesses at the cost of");
		Out.NextFillOut("larger memory buffers.");
		Out.NextQuoteOut("Caption");
		Out.NextQuoteOut(GetCaption());
		Out.NextFillOut("is a one line description of the contents");
		Out.NextFillOut("of the file. It is displayed by executing a member");
		Out.NextFillOut("function of an input node that reads this file.");
		Out.NextFillOut("The node will read chunks of multiples of");
		Out.NextQuoteOut("DeltaIn");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetDeltaIn()));
		Out.NextFillOut(")");
		Out.NextFillOut("samples. Note for complex data there are two words in");
		Out.NextFillOut("each sample. The node will not be executed unless");
		Out.NextQuoteOut("DeltaIn");
		Out.NextFillOut("input samples are available.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntOutputNode->GetOneParameter("FileName")->
			StringP->CurrentValue = FileName_1;
		IntEntOutputNode->GetOneParameter("Flags")->
			IntP->CurrentValue = Flags_2;
		IntEntOutputNode->GetOneParameter("Channels")->
			IntP->CurrentValue = Channels_3;
		IntEntOutputNode->GetOneParameter("FileBlockSize")->
			IntP->CurrentValue = FileBlockSize_4;
		IntEntOutputNode->GetOneParameter("Caption")->
			StringP->CurrentValue = Caption_5;
		IntEntOutputNode->GetOneParameter("DeltaIn")->
			IntP->CurrentValue = DeltaIn_6;
		break;
	}
} // end  list entity switch

void OutputNodeNodesInit()
{
	if (OutputNodeNodeList)  return ;

	static StringParam OutputNodeNameParam =
		{"OutputNode", MakeNewEntityName, 0, LegalEntityName};
	static StringParam OutputNodeFileNameParam = {
		 0, 0, 0};
	static IntParam OutputNodeFlagsParam = {
		 1, 0, 0, -32767, 0, 32767};
	static IntParam OutputNodeChannelsParam = {
		 1, 0,  0,  1,  0,  32};
	static IntParam OutputNodeFileBlockSizeParam = {
		 128, 0,  0,  1,  0,  16384};
	static StringParam OutputNodeCaptionParam = {
		 0, 0, 0};
	static IntParam OutputNodeDeltaInParam = {
		 1, 0,  0,  1,  0,  16384};

	static OneParameter OutputNodeParArray[] = {
		{"Name", 0, "node name", 0, 0, &OutputNodeNameParam},
		{"FileName", 0, 
			"name of disk file to create",
			0, 0, &OutputNodeFileNameParam},
		{"Flags", 0, 
			"flags to overwrite exiting file and other options",
			&OutputNodeFlagsParam, 0, 0, 0, 0, 1},
		{"Channels", 0, 
			"number of input channels",
			&OutputNodeChannelsParam, 0, 0, 0, 0, 1},
		{"FileBlockSize", 0, 
			"number of consecutive samples from one channel",
			&OutputNodeFileBlockSizeParam, 0, 0, 0, 0, 1},
		{"Caption", 0, 
			"descriptive caption",
			0, 0, &OutputNodeCaptionParam, 0, 0, 1},
		{"DeltaIn", 0, 
			"minimum input chunk size",
			&OutputNodeDeltaInParam, 0, 0, 0, 0, 1},
		{0}
	};

	OutputNodeNodeList = new EntityList;
	IntEntOutputNode = new InteractiveEntity("OutputNode", OutputNodeNodeList,
		MakeOutputNode, InteractiveDisplay, "outnode.h",
		0, "DisplayNodeStr");
	IntEntOutputNode->SetParameters(new UserParameters(OutputNodeParArray));
	TheNodes->Append(IntEntOutputNode);
} // end initalization

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

case EntityReqDescribeFull:
		Out.NextQuoteOut("OutputNode");
		Out.NextFillOut("writes");
		Out.NextQuoteOut("Channels");
		Out.NextFillOut("of input to disk file");
		Out.NextQuoteOut("FileName");
		Out.NextFillOutConcat(".");
		Out.NextFillOut("Each channel");
		Out.NextFillOut("contains `ElementSize' multiplexed elements. The data is blocked in");
		Out.NextFillOut("as");
		Out.NextQuoteOut("FileBlockSize");
		Out.NextFillOut("consecutive samples from each channel. An");
		Out.NextQuoteOut("Caption");
		Out.NextFillOut("can be used to provide annotation of the file contents. If a reset");
		Out.NextFillOut("is done after the output file is opened the last character of the");
		Out.NextFillOut("file name is changed by adding 1 to it in the character sequence");
		Out.NextFillOut("0-9,A-Z,a-z. Once the last character `z' is reached the next character");
		Out.NextFillOut("is `0'. If the option is set not to overwrite a file then the open");
		Out.NextFillOut("will fail if a file with the new name already exists.");
		Out.NextFillOut("This cycling though file names allows testing of reset in a stand alone");
		Out.NextFillOut("program that may need to process some data and then be reset to process");
		Out.NextFillOut("the next input stream.");
		Out.NextFillOut("cycle through the sequence 0-9,A-Z,-a-z");
		Out.NextFillOut("or numeric that is the new file name. If not");
		Out.NewLine();
		break;

case EntityReqCreate:
	{
		const char * Name = IntNode.GetStringParameterValue("Name");
		const char * FileName =
			IntNode.GetStringParameterValue("FileName");
		int16 Flags =
			IntNode.GetIntParameterValue("Flags");
		int16 Channels =
			IntNode.GetIntParameterValue("Channels");
		int32 FileBlockSize =
			IntNode.GetIntParameterValue("FileBlockSize");
		const char * Caption =
			IntNode.GetStringParameterValue("Caption");
		int32 DeltaIn =
			IntNode.GetIntParameterValue("DeltaIn");
		return new OutputNode(Name, FileName, Flags, Channels, FileBlockSize, Caption, DeltaIn);

	}
	}
	return 0;
}

static InitObj LocalInit(OutputNodeNodesInit, "OutputNode", "DisplayNodeStr");

