/*
 *  travparm.h from ObjectProDSP 0.1
 *  Copyright (C) 1994, 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.
 */
#ifndef TRAVPARM_DOT_H
#define TRAVPARM_DOT_H
/*  travparm.h   */
/*  Copyright 1991 Mountain Math Software  */
/*  All Rights Reserved                    */
#include "ObjProDSP/portable.h"
#include "ObjProDSPint/netlnk.h"

class TimingDescription ;
class DfNodeInLink ;
class DfNodeOutLink ;
class OutTokens ;
class DfNodeOut ;
class DfNode ;
class TargetNodeParameters ;
class TargetReaderParameters ;
class Adjustment ;
class BufferStatus ;
class EmitTargetCode ;
class SharedArray ;
class TransmitNetworkDescription ;
class NodeReplacementList ;

/*
 *	Initial Algorithm for Assigning Buffer Sizes
 *
 *  	1. Assign sizes as they currently are.
 *	   Compute the minimum available data block size and a corresponding
 *	   execution count for each node. (This is the only allowed
 *	   algorithm when feedback is present.)
 *
 *	2. Assign sizes for a uniform execution count. Try to make the
 *	   average buffer size be as close to a desired size as possible.
 *
 */

struct ReasonForFailure {
	const char * Reason ;
	const char * Node ;
	int Channel ;
	int32 NeededSpace ;
	enum ChannelType {Input,Output} Type;
	int FatalFlag ;
	ReasonForFailure(const char * reason, const char *node,
		int32 needed, int chan = 0, ChannelType type = Input,
		int fatal = 0);
	void Explain(ostream& Out, const char * Attempting) const ;
	int IsFatal() const {return FatalFlag;}
};

class TraverseParameters {
public:
	enum ParameterType {BufferStatusType,TransmitDescriptionType,
		ReplacementListType,DfNodeType, UndefinedType} TheType ;
private:
	EmitTargetCode*  TheTargetCode ;
	void * TheParameters ;
	DfNodeList the_checked_list ;
	int the_flag ;

	void init();
public:
	TraverseParameters(BufferStatus& buffer_status);
	TraverseParameters(EmitTargetCode& emit) ;
	TraverseParameters(TransmitNetworkDescription& trans);
	TraverseParameters(NodeReplacementList& list);
	TraverseParameters(DfNode& node);
	~TraverseParameters(){the_checked_list.Clear();}
	DfNode * node() ;
	BufferStatus* GetBufferStatus() ;
	EmitTargetCode* GetEmitTargetCode() ;
	void SetTheParameters(BufferStatus* status);
	SharedArray * GetSharedArray() ;
	TransmitNetworkDescription& network_description() ;
	NodeReplacementList& node_replacement_list() ;
	void append(DfNode * node) {the_checked_list.Append(node);}
	int is_checked(DfNode * node) {return the_checked_list.InList(node);}
	void clear_checked() {the_checked_list.Clear();}
	void flag(int set) {the_flag = set;}
	int flag() const {return the_flag;} 
};




class TargetWriterParameters {
	int32 MinimumDataToExecute ;
	int DivisorShift ;
	int DivisorFactor ;
public:
	TargetWriterParameters(DfNodeOutLink& Out, int32 BufSz);
	TargetWriterParameters(DfNodeInLink& In, int32 BufSz);
	void EmitParameters(OutTokens& Out) const ;
};

class TargetReaderParameters: public TargetWriterParameters{
	int32 Delay ;
	int32 LeftOver ;
public:
	TargetReaderParameters(DfNodeInLink& In, int32 BufSz);
	int32 GetLeftOver() const {return LeftOver;}
	void SetLeftOver(int32 left_over) {LeftOver = left_over;}
};


class TargetBufferParameters {
	int32 Size ;
	int32 LeastCommonMultiple ;
public:
	TargetBufferParameters(int32 size) ;
	int32 GetSize() const {return Size;}
	TargetAdjustState AdjustSize(int32 NewSize);

	int32 GetLeastCommonMultiple() const {return LeastCommonMultiple;}
	void SetLeastCommonMultiple(int32 val) {LeastCommonMultiple = val;}
	int32 AdjustMultiple(DfNodeOutLink * Link, int32 PrevExecCount,
		BufferStatus * Status );
	int32 ComputeCommonDivisor(int32 In, int32 Out, int32 Prev) ;
	TraverseResult CheckTargetBufferSize(TraverseObject& obj,
		int32 ExistingSize, int32 MinSize);
};

inline 	TraverseResult CheckTraverse(TraverseResult Check, TraverseResult Set)
	{if (Check>Set) Set=Check; return Check;}


#endif /* #ifdef TRAVPARM_DOT_H */
