#include "drvintfc.h"
#include <stream.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include "innode.h"
#include "cgidbg.h"
#include "sysconst.h"
#include "yacintfc.h"
#include "infile.h"
#include "shared.h"
#include "netlnk.h"
// #include "bufcnt.h"
#include "dfnode.h"
#include "drvintfc.h"

void InputNode::Ctor()
{
	SampleRateRatio = 0 ;
	ElementSize = 0 ;
	CumulativeSamples = 0 ;
	TheDriverInterface = &DefaultDriverInputInterface ;
	int cannot_read = 1 ;
	if (TheInputFile) if (TheInputFile->GetTheFile() > 0) cannot_read = 0 ;
	if (cannot_read) {
		if (State.IsInteractive()) State.Error("cannot read binary data file `",
			GetFileName(), "' in node `", GetName(), "'") ;
		Channels = 0 ;
		ElementSize = 0 ;
		TheInputFile =  0 ;
		return ;
	}
	
#ifdef INTERACTIVE
	ArithType::ArithTypes SetType = TheArithType ;
	// 	(ArithType::ArithTypes) TheInputFile->GetDataType();
	if (GetFlags() &2) SetType = ArithType::ArithFloat ;
	InitArithType(SetType) ;
	// StreamStr * OutStr = GetOutStream();
	// if (OutStr) GetOutStream()->SetArithType(SetType);
#endif
	Channels = TheInputFile->GetChannels();
	ElementSize = new int32[Channels] ;
	for (int i = 0 ; i < Channels ; i ++) {
		ElementSize[i]=TheInputFile->GetElementSize(i) ;
#ifdef INTERACTIVE
		SetFromDisk(TheInputFile->GetChannelHeader(i),i);
#endif
	}
	if (Channels > 1) {
		SampleRateRatio = new double[Channels-1];
		CumulativeSamples = new double [Channels];
		for (int j = 0 ; j < Channels ; j++) {
			if (j) SampleRateRatio[j-1] = 
				TheInputFile->GetTimingRatio(j) /
				TheInputFile->GetTimingRatio(0) ;
			CumulativeSamples[j] = 0.0 ;
		}
	} else {
		SampleRateRatio = 0 ;
		CumulativeSamples = 0 ;
	}
	FileName_1= TheInputFile->GetFileName();
}

ErrCode InputNode::NodeReset()
{
	ErrCode Ret = OK ;
	if (TheDriverInterface) if ((*TheDriverInterface)(this,
		ResetReaderSystemInterface,0,0) <0) Ret = FatalError ;
	ErrCode LocRet ;
	if (TheInputFile) LocRet = TheInputFile->Reset();
	if (LocRet > Ret) Ret = LocRet ;
	if (Channels > 1) if (CumulativeSamples)
		for (int i = 0 ; i < Channels ; i++)
			CumulativeSamples[i] = 0;
	return Ret ;
}


#ifdef INTERACTIVE
void InputNode::DisplayHeader()
{
	if (!TheInputFile) {
		BadFile();
		return ;
	}
	TheInputFile->DisplayHeader();
}

void InputNode::IgnoreHeaderCount() 
{
	if (!TheInputFile) {
		BadFile();
		return ;
	}
	TheInputFile->SetIgnoreHeaderCount();
}

TimingDescription * InputNode::GetInitTiming(int InChannel)
{
	if (!TheInputFile) {
		BadFile();
		return 0 ;
	}
	return TheInputFile->GetInitTiming(InChannel);
}
#endif

void InputNode::BadFile()
{
#ifdef INTERACTIVE
		State.Error("node `", GetName(),
			"' not initialized. It may be a dummy default");
#else
		DbgError("InputNode::BadFile","not initialized");
#endif
}


ErrCode InputNode::TheKernel(int k)
{
/*
 *	LogOut << "InputNode::TheKernel(" << k << ") for  `" <<
 *		GetName() << "'\n" ;
 */

	if (!TheInputFile) {
		State.Error("node `",
			GetName(),
		"' not initialize. This may be a dummy default");
		return FatalError ;
	}
	ErrCode ErrState = OK ;
	int32 DataSpace ;
	for (int Chan = 0 ; Chan < GetOut(); Chan++) {
	    int AnyProgress = 0 ;
	    while(DataSpace = GetContiguousSpace(Chan)) {
			MachWord * Ptr  = GetWritePtr(Chan);
			int32 WordsRead = TheDriverInterface(this,Chan,
				DataSpace,Ptr);
/*
 *			int display = 12 ;
 *			LogOut << GetName() << " rd " << WordsRead << "\n" ;
 *			if (WordsRead < display) display = WordsRead ;
 *			for (int i = 0 ; i < display; i++) LogOut << (MachWordCast)
 *				Ptr[i] << "\n" ;
 */
			if (WordsRead < 1) {
				ErrState = EndOfData ;
				break ;
			} else {
				UpdateWrite(WordsRead,Chan);
				AnyProgress = 1 ;
			}
		}
	}
	return ErrState ;
}

void InputNode::Dtor()
{
	delete TheInputFile ;
	delete SampleRateRatio  ;
	delete ElementSize  ;
	delete CumulativeSamples ;
}

