
// Title:	SystemModel.h
// Date:	28-8-08 (start), 13-11-08 (updated)

#include "Block.h"
#include "Signal.h"
#include "Annotation.h"

#ifndef SYSTEM_MODEL_H
	#define SYSTEM_MODEL_H					// inclusion guard

	#include <list>							// rqd. for list (below)
	using namespace std;

	// User defined consts/vars.

	// User defined types

	// SystemModel			
	class CSystemModel
	{
	public:
		bool CheckStopButtonPressed(void);
		void SetDrawAnnotationFlag(int draw);
		int GetDrawAnnotationFlag(void) const;
		void DeleteAnnotationList(void);
		const list<CAnnotation*> *GetAnnotationListCopy(void) const;
		list<CAnnotation*> &GetAnnotationList(void);
		CSystemModel &operator=(const CSystemModel &sm);
		const list<int*> *GetSourceOutputTourListCopy(void) const;
		const list<int*> *GetSourceLoopTourListCopy(void) const;
		const list<CConnection*> *GetConnectionListCopy(void) const;
		const list<CBlock*> *GetBlockListCopy(void) const;
		CString GetWarning(void) const;
		CString GetTimeStepType(void) const;
		double GetTimeStop(void) const;
		double GetTimeStepSize(void) const;
		double GetTimeStart(void) const;
		double GetRTOL(void) const;
		double GetATOL(void) const;
		int GetNSourceOutputTours(void) const;
		int GetNSourceLoopTours(void) const;
		int GetNSourceBlocks(void) const;
		int GetNOutputBlocks(void) const;
		CSystemModel(const CSystemModel &sm);
		CPoint DetermineDiagramCoordinateMinima(void);
		void ScaleSystemModel(double scale_factor);
		int NullifyNegativeCoordinates(void);
		CPoint DetermineDiagramCoordinateExtrema(void);
		void DeleteConnectionList();
		void DeleteBlockList();
		void ReadSystemModelDataFromFile(ifstream &fin);
		void WriteSystemModelDataToFile(ofstream &fout);
		void SetModelName(CString name);
		void ResetMemoryBasedBlockData(void);
		int AssignSystemEquationsSignalVector(double *x_vec);
		int NewtonSolver(int nrows, double *x_vec, int t_cnt, double t,  double delta_t);
		int DetermineSystemEquationsFunctionOperationVector(int t_cnt, double t, double delta_t, double *x_vec, double *f_vec);
		int DetermineSystemEquationsSignalVector(double *x_vec);
		void DetermineSystemEquationsBlockList(list<CBlock*> &equ_blk_list);
		int DetermineSystemEquationsDataDimensions(int &nrows_total, int &ncols_total);
		int TransferSignalDataToAnotherConnection(CBlock *ptr_blk1, CBlock *ptr_blk2);
		int PreliminarySignalPropagation(void);
		int CheckSystemSignalValidity(void);
		void ConvertIntegerTourToBlockList(int *tour_vec, list<CBlock*> &tour_blk_list);
		int* GetTourVector(int tour_type, int i);
		void DeleteSourceOutputLoopLists();
		void OrderBlockList(void);
		void GetTimeParameters(double &t_init, double &t_final, double &delta_t) const;
		CString GetIntegrationMethod() const;
		void SignalPropagationSystemOfEquations(void);
		int DetermineNTimeSteps(void);
		void SignalPropagationDirect(void);
		int GetNFeedbackLoops(void) const;
		void SaveTourVector(int *tour_vec, int ncols);
		void ResetTourVector(int *tour_vec, int *in_tour_vec, int ncols);
		int CheckRepeatedEntries(int *tour_vec, int ncols);
		int NumberOfOnesOnMatrixRow(int **A, int row, int ncols);
		int FindBranchNodes(int **A, int i, int ncols, int *branch_node_vec, int &n_nodes);
		int FindCurrentTourPosition(int *tour_vec, int ncols);
		void BuildTour(int **A, int nrows, int ncols, int *node_vec, int n_nodes, int *in_tour_vec);
		int DetermineInitialNodeVector(int **A, int nrows, int ncols, int *node_vec, int &n_nodes);
		void DetermineLoopsFromConnectivityMatrix(int **A, int nrows, int ncols);
		void AssignBlockConnectivityMatrixValues(CBlock *from_block, CBlock *to_block, int **BlockConMatrix);
		void SetRefFromPortOfConnectionFromBendPoint(void);
		void DetermineModelFeedbackLoops(void);
		void SetModelStatusFlag(int status);
		void ModelErrorPenColor(int *pen_color);
		int ValidateModelConnections(void);
		int GetModelStatusFlag(void) const;
		int ValidateModelBlockPorts(void);
		int ValidateModelBlocks(void);
		int ValidateModel(void);
		void DlgWndParameterInput(void);
		void UpdateConnectionPointTailToBendPoint(CPoint *bend_pt);
		void UpdateConnectionPointTail(CPort *port);
		void UpdateConnectionPointHead(CPort *port);
		list<CConnection*> &GetConnectionList(void);
		list<CConnection*> &GetConnectionListError(void);
		int AddConnection(CPoint ptFrom, CPoint ptTo);
		void DrawSystemModel(CDC *pDC);
		list<CBlock*> &GetBlockList(void);
		CSystemModel(void);	
		~CSystemModel(void);
		CString GetModelName(void) const; 			

	private:
		int m_iDrawAnnotationFlag;				// flag to control the drawing of annotations
		int m_iModelStatusFlag;					// model status flag
		int m_iNOutputBlocks;					// no. of output blocks in the model
		int m_iNSourceBlocks;					// no. of source blocks in the model
		int m_iNSourceOutputTours;				// no. of tours from a source blk that end at an output blk
		int m_iNSourceLoopTours;				// no. of tours from a source blk that end in a feedback loop
		double	m_dATOL;						// absolute error tolerance parameter
		double	m_dRTOL;						// relative error tolerance parameter
		double	m_dTimeStart;					// simulation start time
		double	m_dTimeStop;					// simulation stop time
		double	m_dTimeStepSize;				// time step size
		CString m_strModelName;					// name of the current SystemModel
		CString m_strIntegrationMethod;			// integration method: Euler, Runge-Kutta.
		CString m_strTimeStepType;				// time step type: fixed-step or variable-step.
		CString m_strWarning;					// diagnostic warning messages
		list<int*> m_lstSourceLoopTour;			// list of integer arrays recording block numbers of a source-to-loop-repeated block tour
		list<int*> m_lstSourceOutputTour;		// list of integer arrays recording block numbers of a source-to-output block tour
		list<CAnnotation*> m_lstAnnotation;		// list of ptrs to annotations of the current SystemModel
		list<CBlock*> m_lstBlock;				// list of ptrs to the Blocks of the current SystemModel
		list<CConnection*> m_lstConnection;		// list of ptrs to the Connections of the current SystemModel
		list<CConnection*> m_lstConnectionError;// list of ptrs to disconnected connections
	};

#endif

// eof