/* See WalkData.doc for explanation of this module */
 
/* Here are some implementation details :
- there is a main class WalkDataMgr which derives from WalkData
- the main class defines an array of 512 WDElement. This array is
quadrupled linked. The first double link corresponds to the order 
in which the datas were edited. The second one corresponds to the
order after several walks (back and forth). When there is a specific 
action the second order is written in the first.
Each element has a reference to a data, given by the editor, and
to its parent WalkData
- each walkdata is a simple manager of a set of elements. It 
corresponds to a DLL. It has the values Last, First, Current.
Current : current data edited in the list
First : latest data added to the list
Last : oldest data modified during walk.
LastUsed : oldest data used (to erase it if needed)
- the Mgr derives from walkdata because it maintains a specific set
of data : the editor themselves. Indeed, we can walk through the
editors. In this case, the Data in the elements is not the DLL itself
but a pointer to the WalkData managing it.*/
 
#ifdef ACTIVE_EDITOR
 
#ifndef __CPAWALKDATA__
#define __CPAWALKDATA__
 
#include "ACP_Base.h"
#include "CPADLLB.hpp"
 
#define MAX_WALKDATA_ELEMENT	512
#define NO_ID -1
 
#define CHECK			/* to check for double occurences in lists*/
/* put this in commentary if you want to speed up the process.*/
 
class WalkData;
class CPA_WalkDataMgr;
 
struct WalkDataElement {
	void			*ItsData;
	int				next;		/* ALink*/
	int				prev;
	int				backnext;	/* BLink*/
	int				backprev;
	WalkData		*aWalkData;		/* its father*/
	};
 
class WalkData : public CObject {
friend CPA_WalkDataMgr;
private :
	int				iCurrent; 
	int				iLast;
	int				iFirst;
	int				iLastUsed;
	CPA_WalkDataMgr		*MyWDM;
	WalkDataElement *aWD;
	CPA_DLLBase	*MyDLL;
 
	WalkData(CPA_WalkDataMgr *aWDM, CPA_DLLBase *pDLL);
 
	inline void ABLink (int a, int b);	/* set Alink and BLink */
	inline void BLink (int a, int b);	/* set Blink */
	virtual void UpdateList();			/* set BLink in ALink */
	int CheckAndGoElement (void *ItsData);	/* check if Itsdata element already exists, go to it if it's the cas*/
	void InsertVoidElement (void *ItsData);	/* add a new element in the list*/
	int Backward ();					
	int Forward ();
	void Go(int iNew);					/* go directly to an element*/
	void BackActive ();					/* activate back a DLL*/
	};
 
 
class CPA_WalkDataMgr:public WalkData {
friend WalkData;
public:
	CPA_WalkDataMgr ();
	~CPA_WalkDataMgr(); 
	void ActiveElement (CPA_DLLBase *pDLL);	/* activate a specific DLL*/
	void InsertElement (CPA_DLLBase *pDLL, void *ItsData);	/* insert an element of given dLL type*/
	void DBackward ();				/* Backward one data*/
	void DForward ();
	void EBackward ();				/* Backward one editor*/
	void EForward ();
 
private :
	struct	WalkDataElement aWD[MAX_WALKDATA_ELEMENT];	/* 12 Ko*/
	int		iVoid;	/* index of next free entry*/
	int		iCount;	/* number of entries in the array*/
 
	inline void ActiveCurrent ();	/* active DLL of current element*/
	void UpdateAll ();				/* update order in each DLL list*/
	void UpdateIVoid();				/* find next entry*/
	int FindOrCreateWalkData (CPA_DLLBase *pDLL);	/* find WD of given dLL, or create a new WD if none are found*/
	void GoElement (CPA_DLLBase *pDLL);	/* Go to given dLL*/
	};
 
#endif /*__CPAWALKDATA__*/
 
#endif /*ACTIVE_EDITOR*/
