#include <stream.h>
#include <fcntl.h>
#include "ObjProComGui/cgidbg.h"
#include "ObjProDSP/sysconst.h"
#include "ObjProDSP/sysintfc.h"
#include "ObjProGui/yacintfc.h"
#include "ObjProNet/dfnode.h"

#include "ObjProUsr/vocnode.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/vocfile.h"
static EntityList * VoiceNodeNodeList = 0 ;
static InteractiveEntity * IntEntVoiceNode ;
void VoiceNodeNodesInit();
VoiceNode::VoiceNode (const char * Name, const char * FileName, int16 NoHeader):
	Signal(Name, 1, 1, 1, 1, TimingTypeLinear, 
	(ArithType::ArithCapabilities)ArithType::ArithTypeUndefined)
,
	FileName_1(FileName),
	NoHeader_2(NoHeader)
{
	if (!VoiceNodeNodeList) VoiceNodeNodesInit() ;
	VoiceNodeNodeList->Append(MakeDeclaredEntity(this, IntEntVoiceNode)) ;
	InitArithType(TheArithType);
	NewMenuItem("VoiceNode",GetName());
#line 83 "../vocnode.usr"
 
	node_state = OK ;
	if (!GetFileName()) FileName_1 = GetName() ;
	TheInputFile = 0 ;
	TheInputFile = new CreativeVoiceFile(this,GetFileName(),GetNoHeader());
	if (!TheInputFile->OpenOK()) {
		TheInputFile = 0 ;
		delete TheInputFile ;
	}
#line 45 "../vocnode.cxx"
} // end constructor

VoiceNode::~VoiceNode()
{
	TheMenuServer->DeleteMenuItem("VoiceNode",GetName());
	VoiceNodeNodeList->Delete(GetName()) ;
#line 94 "../vocnode.usr"
 
#line 54 "../vocnode.cxx"
} // end destructor

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

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

VoiceNode * VoiceNodeDef;

ErrCode VoiceNode::DoNode(int32 k)
{
#line 122 "../vocnode.usr"
 
	if (node_state >= EndOfData) return node_state ;
	if (!TheInputFile) {
		TheInputFile = new CreativeVoiceFile(this,GetFileName(),GetNoHeader()) ;
		if (!TheInputFile->OpenOK()) {
			TheInputFile = 0 ;
			delete TheInputFile ;
			return FatalError ;
		}
	}
	for (int i = 0 ; i < k ; i++) {
		MachWord Temp = TheInputFile->ReadWord();
		if (TheInputFile->ReadOK()) WriteWord(Temp);
		else {
			if (TheInputFile->EndOfFile()) {
				State.Warning("end of file on node `",GetName(),"'");
				return node_state = EndOfData ;
			}
			// LogOut << "Bad read not EOF\n" ;
			return FatalError ;
		}
	}
	// LogOut << "Kernel exit.\n" ;
	return OK ;
#line 101 "../vocnode.cxx"
} // end kernel code

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

void VoiceNode::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakeVoiceNode(Out,EntityReqDescribeFull,*IntEntVoiceNode, (ArithType::ArithCapabilities) TheArithType);
		Out.NewLine();
		Out.NextQuoteOut("FileName");
		Out.NextQuoteOut(GetFileName());
		Out.NextFillOut("must be the name of an existing file");
		Out.NextFillOut("in the Creative Voice File Format.");
		Out.NextFillOut("Only uncompressed files of block type 1 (New Voice Block)");
		Out.NextFillOut("are supported.");
		Out.NextQuoteOut("NoHeader");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetNoHeader()));
		Out.NextFillOut(")");
		Out.NextFillOut("if set to 1 indicates the file does not contain");
		Out.NextFillOut("a header.");
		Out.NextFillOut("`VoiceStripOut'");
		Out.NextFillOut("writes files in Creative Voice format");
		Out.NextFillOut("files with no header.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntVoiceNode->GetOneParameter("FileName")->
			StringP->CurrentValue = FileName_1;
		IntEntVoiceNode->GetOneParameter("NoHeader")->
			IntP->CurrentValue = NoHeader_2;
		break;
	}
} // end  list entity switch

static ValueType * DisplayHeader(OutTokens& Out,EntityReq Request,
		UserParameters * Param,UserEntity *This) 
{
	switch (Request) {
case EntityReqDescribe:
case EntityReqDescribeFull:
		Out.NextQuoteOut("DisplayHeader");
		Out.NextFillOut("displays the information in the file header.");
		Out.NewLine();

	break ;
case EntityReqCall:
		{
		((VoiceNode * )This)->DisplayHeader(
		);		}
	}
	return 0;
}

void VoiceNodeNodesInit()
{
	if (VoiceNodeNodeList)  return ;

	static StringParam VoiceNodeNameParam =
		{"VoiceNode", MakeNewEntityName, 0, LegalEntityName};
	static StringParam VoiceNodeFileNameParam = {
		 0, 0, 0};
	static IntParam VoiceNodeNoHeaderParam = {
		 0, 0,  0,  0,  0,  1};

	static OneParameter VoiceNodeParArray[] = {
		{"Name", 0, "node name", 0, 0, &VoiceNodeNameParam},
		{"FileName", 0, 
			"input file in `Creative Voice' file format",
			0, 0, &VoiceNodeFileNameParam},
		{"NoHeader", 0, 
			"file does(0) or does not(1) contain a header",
			&VoiceNodeNoHeaderParam},
		{0}
	};

	static OneParameter DisplayHeaderVoiceNodeList[] = {
		{0}
	};
	UserParameters * DisplayHeaderMemberParam = new UserParameters
		(DisplayHeaderVoiceNodeList);

	Procedure * MemberProcDisplayHeader = new Procedure("DisplayHeader", DisplayHeader,
		DisplayHeaderMemberParam, "void", 0, "display file header");
static ValueType * VoiceNodeMembers[2] ;
	int ii = 0 ;
	VoiceNodeMembers[ii++] = new ValueType(DecProcedure, MemberProcDisplayHeader) ;
	VoiceNodeMembers[ii++] = 0 ;
	VoiceNodeNodeList = new EntityList;
	IntEntVoiceNode = new InteractiveEntity("VoiceNode", VoiceNodeNodeList,
		MakeVoiceNode, InteractiveNode, "vocnode.h",
		VoiceNodeMembers, "Signal");
	IntEntVoiceNode->SetParameters(new UserParameters(VoiceNodeParArray));
	TheNodes->Append(IntEntVoiceNode);
} // end initalization

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

case EntityReqDescribeFull:
		Out.NextQuoteOut("VoiceNode");
		Out.NextFillOut("reads `Creative Voice' format files.");
		Out.NextFillOut("Only files containing uncompressed sampled data");
		Out.NextFillOut("are supported. This format has one sample per");
		Out.NextFillOut("each byte in offset format, i. e. 128 is subtracted");
		Out.NextFillOut("from each unsigned byte to create a signed sample.");
		Out.NextFillOut("In the 16 bit integer simulator you will probably need");
		Out.NextFillOut("to rescale the data (most likely by dividing by 128)");
		Out.NextFillOut("before writing it in this format.");
		Out.NextFillOut("Member function");
		Out.NextQuoteOut("DisplayHeader");
		Out.NextFillOut("displays");
		Out.NextFillOut("the file header. If");
		Out.NextQuoteOut("NoHeader");
		Out.NextFillOut("is set then no header is");
		Out.NextFillOut("read. Node");
		Out.NextFillOut("`VoiceStripOut'");
		Out.NextFillOut("writes files in this format.");
		Out.NewLine();
		break;

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

	}
	}
	return 0;
}

static InitObj LocalInit(VoiceNodeNodesInit, "VoiceNode", "Signal");

