/*
 *  tarnod.h from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
/*  tarnod.h   */
/*  Copyright 1991 Mountain Math Software  */
/*  All Rights Reserved                    */
#ifndef TARNOD_DOT_H
#define TARNOD_DOT_H
#include <stdio.h>
#include "ObjProDSP/portable.h"
#include "ObjProGui/basic.h"
#include "ObjProNet/tarmac.h"
#include "ObjProGen/errcode.h"
#include "ObjProDSP/buftype.h"

#ifdef INTERACTIVE
#define VIRTUAL virtual
#else
#define VIRTUAL
#endif

typedef ErrCode (*EndOfNetwork) (void * ref);

class NetworkStateControl {
	void * NetworkReference ;
	EndOfNetwork CallAtEnd ;
public:
	NetworkStateControl(void * ref=0);
	ErrCode SetCallAtEnd(EndOfNetwork call);
	ErrCode DoCallAtEnd();
	void * GetReference() {return NetworkReference;}
	ErrCode SetReference(void * ref);
};
	
class DfNodeInLink;
class DfNodeOutLink ;
class NodeOutChannelHeader ;
class stream ;
class ofstream ;
class ifstream ;
struct TimingInfo ;

class TargetNode : public UserEntity {
protected:
	int In ;
	int Out ;
	DfNodeInLink * InLinks ;
	DfNodeOutLink * OutLinks ;

	NodeExecuteType ExecuteType ;
	int32 Delay ;		// number of times to execute with no input
	int32 History ;		// amount of delay used up
	ErrCode NodeState ;
	int ** ExecutionSequences ;

	// All of the above are initialized from tables
	// Next comes parameters of current node state
	
	int SequenceIndex ;
	int * ExecutionSequence ;
	int ExecutionIndex ;
	int FeedbackFlag ;
	TimingInfo * TheTimingInfo ; // used only if TimingCheckOn
	int CkIn(int in, const char * Routine) const ;
	int CkOut(int out, const char * Routine) const ;
private:
	void Init();
public :
	TargetNode(const char * name, int in, int out);

	TargetNode(const char * name, int in, int out, DfNodeInLink * in_links,
		DfNodeOutLink * out_links, int ** exec=0,
		NodeExecuteType type=NodeExecuteFixedBound, int32 delay=0);
	virtual ~TargetNode();

	virtual ErrCode DoNode(int32 k=0);
			// Parameter will be removed eventually
	 		// Node execution function
			// Parameters is the iteration multiple
	int GetIn() const {return In;}
	int GetOut() const {return Out;}
	virtual ErrCode NodeReset(); 
	ErrCode Reset() ;
	VIRTUAL DfNodeInLink * GetInLink(int Chan = 0) const ;
	VIRTUAL DfNodeOutLink * GetOutLink(int Chan = 0) const ;
	void SetNodeState(ErrCode new_state) ;
	VIRTUAL const char * GetCaption() const {return 0;}
	VIRTUAL NodeOutChannelHeader * GetDiskState(int Chan = 0);
	VIRTUAL void SetInputFromDisk(const NodeOutChannelHeader& DiskState,
		int Channel = 0);
		
	void ClearFeedbackFlag() {FeedbackFlag=0;}
	ErrCode ExecuteNode(int32& count); // only used in target code version
	ErrCode ExecuteDynamicNode(int32& count);
			// only used in target code version
	int32 GetDynamicCount()  ; // only used in target code version

	int32 GetEltSize(int out_channel=0) const ;
	int32 GetInEltSize(int in_channel=0) const ;
	int32 GetBlockSize(int chan=0) const ;
	int32 GetOutBlockSize(int chan=0) const ;
	NodeExecuteType GetExecuteType() const {return ExecuteType;}

	const int * const *  const GetExecutionSequences() const {return
		(const int *const * const) ExecutionSequences ;}

	// Buffer Interface code
	void UpdateRead(int32 size, int chan=0)
		IN_CX(UpdateRead(size))
	void UpdateWrite(int32 size, int chan=0)
		OUT_CX(UpdateWrite(size))

	const MachWord * GetReadPtr(int chan=0) const 
		IN_C(GetReadPtr())
	const MachWord * GetReadBase(int chan=0) const 
		IN_C(GetReadBase())
	const MachWord * GetReadEnd(int chan=0) const 
		IN_C(GetReadEnd())

	MachWord * GetWritePtr(int chan=0) const 
		OUT_C(GetWritePtr())
	MachWord * GetWriteBase(int chan=0) const
		OUT_C(GetWriteBase())
	MachWord * GetWriteEnd(int chan=0) const
		OUT_C(GetWriteEnd())

	const UnsignedIntegerMachWord * GetBinReadPtr(int chan=0) const 
		{return (const UnsignedIntegerMachWord *) GetReadPtr(chan);}
	const UnsignedIntegerMachWord * GetBinReadBase(int chan=0) const 
		{return (const UnsignedIntegerMachWord *) GetReadBase(chan);}
	const UnsignedIntegerMachWord * GetBinReadEnd(int chan=0) const 
		{return (const UnsignedIntegerMachWord *) GetReadEnd(chan);}

	UnsignedIntegerMachWord * GetBinWritePtr(int chan=0) const 
		{return (UnsignedIntegerMachWord *) GetWritePtr(chan);}
	UnsignedIntegerMachWord * GetBinWriteBase(int chan=0) const
		{return (UnsignedIntegerMachWord *) GetWriteBase(chan);}
	UnsignedIntegerMachWord * GetBinWriteEnd(int chan=0) const
		{return (UnsignedIntegerMachWord *) GetWriteEnd(chan);}


	// Obsolete use WriteInteger 
	void WriteBinary(UnsignedIntegerMachWord Data, int chan=0)
		OUT_CX(WriteBinary(Data))

	void WriteInteger(IntegerMachWord Data, int chan=0) 
		{WriteBinary(Data,chan);}

	void WriteWord(MachWord Data, int chan=0)
		OUT_CX(WriteWord(Data))


	// Obsolete use ReadInteger
	UnsignedIntegerMachWord ReadBinary(int chan=0) 
		IN_C(ReadBinary())
	IntegerMachWord ReadInteger(int chan=0) {return ReadBinary(chan);}

	MachWord ReadWord(int chan=0) 
		IN_C(ReadWord())

	int32 GetAvailableData(int chan=0) const
		IN_C(GetAvailableData())
	int32 GetSpace(int chan=0) const
		OUT_C(GetSpace())
	int32 GetContiguousAvailableData(int chan=0) const
		IN_C(GetContiguousAvailableData())
	int32 GetContiguousSpace(int chan=0) const
		OUT_C(GetContiguousSpace())

	void WriteCxWord(CxMachWord Data, int chan=0)
		OUT_CX(WriteCxWord(Data))
	CxMachWord ReadCxWord(int chan=0)
		IN_C(ReadCxWord())

	int32 GetIncrementIn(int chan=0) const ;
	int32 GetIncrementOut(int chan=0) const ;
	int32 GetNodeDelay() const { return Delay;}
	void SetSequence(int index);
	TargetNode * GetDriverNode(int chan=0) const ;

	int32 ReadInput(MachWord * Data, int32 SizeToRead, int chan=0);
	int32 WriteOutput(MachWord * Data, int32 Size, int chan=0);
		// These two functions are for short circuiting input and
		// output nodes. They allow direct transfer of data
		// to the first DSP node or from the last output node
		// to an external system interface

	static void expand_name(const char * name, const char * exp);
	static void open_error(const char * name, const char * exp,const char *msg=0);
	static void create_error(const char * name, const char * exp, int exists);
	static const char * open_r(const char * name,int * fd, FILE ** fl,
		ifstream ** str);
	static const char * open_w(const char * name, int flags, int& exists,
		int * fd, FILE ** fl, ofstream ** str) ;

	static const char * open_file(const char ** name, const char * prompt_file_type = 0,
		int force_error=0, int * fd=0, FILE ** fl=0, ifstream ** str=0);

	static const char * open_file(const char ** name,FILE *& fl,
		const char * prompt_file_type = 0, int force_error=0)
	{
		return open_file(name,prompt_file_type,force_error,0,&fl);
	}

	static const char * open_file(const char ** name,ifstream *& str,
	  const char * prompt_file_type = 0, int force_error=0)
	{
		return open_file(name,prompt_file_type,force_error,0,0,&str);
	}
	
	static const char * open_file(const char ** name,int& fd,
		const char * prompt_file_type= 0, int force_error=0)
	{
		return open_file(name,prompt_file_type,force_error,&fd);
	}

	static const char * create_file(const char ** name, const char * prompt_file_type = 0,
		int flags=0, int * fd=0, FILE ** fl=0, ofstream ** str=0);
		// flags&1 forces error, flags&2 checks if file exists and warns
		// flags&4 forces error if file exists

	static const char * create_file(const char ** name,FILE *& fl,
		const char * prompt_file_type = 0, int flags=0)
	{
		return create_file(name,prompt_file_type,flags,0,&fl);
	}

	static const char * create_file(const char ** name,ofstream *& str,
		const char * prompt_file_type = 0, int flags=0)
	{
		return create_file(name,prompt_file_type,flags,0,0,&str);
	}
	
	static const char * create_file(const char ** name,int& fd ,
		const char * prompt_file_type = 0, int flags=0)
	{
		return create_file(name,prompt_file_type,flags,&fd);
	}

	static int good_file(int * fd, FILE ** fl, ofstream ** str);
	static int good_file(int * fd, FILE ** fl, ifstream ** str);

	const char * def_name(const char * nm) ;
};


#undef IN_C
#undef OUT_C
#undef IN_CX
#undef OUT_CX

#include "ObjProNet/tarnod2.h" 
// above includes inline functions for "tarnod.h"

#endif /* #ifdef TARNOD_DOT_H */
