/*
 *  execseq.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.
 */
/*  execseq.h   */
/*  Copyright 1991 Mountain Math Software  */
/*  All Rights Reserved                    */
#ifndef EXECSEQ_DOT_H
#define EXECSEQ_DOT_H
#include "ObjProDSP/portable.h"
#include "ObjProGui/nodenm.h"

struct TimingDescription ;
class DfNodeInLink ;
class DfNodeOutLink ;
class OutTokens ;
class DfNodeOut ;
class DfNode ;
class TargetNodeParameters ;
class TargetReaderParameters ;
class TargetBufferParameters ;
class Adjustment ;
class TraverseObject ;
class BufferStatus ;

const MaxSeqLength = 50 ;

class ExecutionSequence {
	int32 * Sequence ;
	int CurrentSize ;
	TargetNodeParameters* NodeParam  ;

	int& MaxLength ;
	int32 PreviousExecutionSequenceMultiple ;
	int32 ExecutionSequenceMultiple ;
	int32 FlushCount ;
	int FlushCountSet ;
	int InitCheckDone ;
	// The above three are only used for the execution sequence

	// Internal temporary values 
	static TraverseObject * Obj ;
	static DfNodeInLink * ConsumerInLink  ;
	static DfNodeOutLink * DriverOutLink  ;
	static DfNodeOut * OneConsumer ;
	static TargetBufferParameters * TargetBuffer ;
	static TargetReaderParameters * TargetReader ;
	static ExecutionSequence * ConsumerSequence ;
	static int32 DataConsumed ;
	static int32 DataAvailable ;
	static int32 DataNeeded ;
	static int32 ExcessData ;
	static int32 LeftOver ;
	static int32 OrigLeftOver ;
	static int32 OverlapWords ;
	static int32 OutBufSize ;
	static int32 InputPerExecution ;
	static int32 OutputPerExecution ;
	static TargetAdjustState StateOut ;
	static BufferStatus * BufStat ;
	// static int TempSeq[MaxSeqLength] ;

	static int ProviderCountNeeded ;
	static int ConsumerCountNeeded ;
	static int32 NeededBufSize ;
	static int32 MinBufSize ;
	static int32 SeqIndex ;
	static int32 SeqEnd ;
	TargetAdjustState DoInitInit(TraverseObject& obj);
public:
	ExecutionSequence(TargetNodeParameters& Param,int& Max_Length) ;
	ExecutionSequence(ExecutionSequence& ToCopy);
	~ExecutionSequence() {delete Sequence;}
	void Restore(ExecutionSequence& RestoreFrom);
	int32 * Get() const { return Sequence; }

	void InitLinks(); 
	TargetAdjustState SetSequence(int) ;
	TargetAdjustState SetSequence(int *);
	TargetAdjustState AdjustSequence(int32 InitData) ;

	TargetAdjustState ReconcileInit(DfNodeOut * one_consumer,
		TraverseObject& obj); 
	TargetAdjustState ReconcileExecute(DfNodeOut * one_consumer,
		TraverseObject& obj); 

	TargetAdjustState AdjustInit(DfNodeOut * one_consumer,
		TraverseObject& obj); 
	TargetAdjustState AdjustExecute(DfNodeOut * one_consumer,
		TraverseObject& obj); 
	TargetAdjustState ComputeInitSequence(DfNodeInLink * InLink) ;

	void SetValue(int32 Value, int index) ;

	int Size() const ;
	int GetSize() const {return CurrentSize;}
	int Count(int index) const;
	int CountPast(int index) const;
	int CountZero(int index) const;
	TargetAdjustState ChannelInit(TraverseObject &obj, DfNodeInLink& In);
	TargetAdjustState InitInit(TraverseObject& obj);
	TargetAdjustState ExecuteInit(TraverseObject& obj);

	TargetNodeParameters* GetParameters() const {return NodeParam;}
	DfNode& GetNode() const ;
	TargetAdjustState UpdateStateOut(TargetAdjustState Check) ;
	TargetAdjustState ComputeConsumption(int SeqIndex, int SeqEnd) ;
	TargetAdjustState ComputeConsumptionAndBuffer(int SeqIndex,
		int SeqEnd) ;
	TargetAdjustState CheckForExcess(int& SeqIndex, int& SeqEnd) ;
	TargetAdjustState CheckForUnderflow(int SeqIndex, int SeqEnd) ;
	TargetAdjustState EnlargeBuffer(int32 minimum, int32 maximum) ;
	void MakeSpace(int SeqIndex) ;
	void Emit(const char * Type, TraverseObject& obj);

	void ComputeUsage() ;
	int SelectBufferSize() ;
	void UpdateBufferType() ;
	TargetAdjustState CheckForNoChange(int ProviderCount,
		int ConsumerCount) ;
	TargetAdjustState UpdateSequenceList() ;
	
	TargetAdjustState CheckAdjustElement(int i) ;
	TargetAdjustState CheckAlignment() ;
	TargetAdjustState ComputeDataUsage(int32 InitData) ;
	TargetAdjustState TryToBorrow(int MissingCount, int Seq_Index) ;
	int& GetMaxLengthRef() {return MaxLength;}
	TargetAdjustState SlideProviderDataForward() ;
	TargetAdjustState EnlargeSequence(int Base, int Increment) ;
	TargetAdjustState EnlargeSequence(Adjustment& TheAdjustment);
	TargetAdjustState ZeroPadSequence(int& SeqIndex, int& SeqEnd) ;
	int OverlapHandled(int SeqIndex) ;
	TargetAdjustState SetSequenceLengthMultiplier(int32 NewMultiple) ;
	int32 GetPreviousExecutionSequenceMultiple() const
		{return PreviousExecutionSequenceMultiple;}
	int32 GetExecutionSequenceMultiple() const
		{return ExecutionSequenceMultiple ; }

	TargetAdjustState SetFlushCount(Adjustment& Adjust);
	TargetAdjustState SetFlushCount(int32 Flush_Count,
		DfNodeInLink * LocConsumerInLink);
	int32 GetFlushCount() const {return FlushCount;}
	int GetFlushCountSet() const {return FlushCountSet;}
	TargetAdjustState MakeEqualLength() ;
	TargetAdjustState FlushExcess(int32 ExtraData) ;
	TargetAdjustState CheckFlushSize() ;
	TargetAdjustState CheckMaxExec(TraverseObject &obj) ;
	int32 GetExecCount(DfNodeInLink& InLink) ;

	void Increment(int SaveExcessCount, int index) ;
	int Decrement(int ExcessCount, int index) ;
	int InitCheck();
	int GetInitCheckDone() const {return InitCheckDone;}
	void Clear() ;
	void dump();
};

#endif /* #ifdef EXECSEQ_DOT_H */
