/*=============================================================================
 *
 *  Filename:			CoheMngr.hpp
 *  Version:            1.0
 *  Date:				16/01/97
 *  Author:             V.L.
 *
 *  Description:		class to manage a list of couple of object to try to 
 *						maintain coherence when an object is deleted
 *
 *===========================================================================*/
 
#ifndef __COHEMNGR_HPP__
#define __COHEMNGR_HPP__
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef ACTIVE_EDITOR
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <afxtempl.h>
#include "acp_base.h"
 
#include "CPABaseO.hpp"
#include "CPAEditB.hpp"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
class CCoherenceManagerDlg;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifndef CPA_EXPORT
#if defined(CPA_WANTS_IMPORT)
#define CPA_EXPORT __declspec(dllimport)
#elif defined(CPA_WANTS_EXPORT)
#define CPA_EXPORT __declspec(dllexport)
#else
#define CPA_EXPORT
#endif
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
 
/*
 =======================================================================================
  internal structures to store link information
 =======================================================================================
 */
 
struct tdstFather_;
 
/*
 *	structure that describe an object as a child 
 */
typedef struct tdstChild_
{
	CPA_BaseObject	*m_p_oChild;
	CList<struct tdstFather_ *, struct tdstFather_ *>	m_oFatherList;
}tdstChild;
 
/*
 * structure that describe a linked child (it's a child with a counter)
 */
typedef struct tdstLinkedChild_
{
	tdstChild		*m_p_stChild;
	unsigned long	m_ulLinkWeight;
}tdstLinkedChild;
 
/*
 *	structure that describe an object as a father
 */
typedef struct tdstFather_
{
	CPA_BaseObject *m_p_oFather;
	CList<tdstLinkedChild *, tdstLinkedChild *>		m_oChildList;
	CList<char *, char *>							m_oDestroyedChildList;
} tdstFather;
 
/*
 =======================================================================================
	TYPEDEF
 =======================================================================================
 */
 
/*
 * Maps
 */
typedef CMap<CPA_BaseObject *, CPA_BaseObject *, tdstChild *, tdstChild *>	CChildMap;
typedef CMap<CPA_BaseObject *, CPA_BaseObject *, tdstFather *, tdstFather *> CFatherMap;
 
/*
 * List
 */
typedef CList< tdstChild *, tdstChild *>				CChildList;
typedef CList< tdstFather *, tdstFather *>				CFatherList;
typedef CList< tdstLinkedChild *, tdstLinkedChild *>	CLinkedChildList;
 
/*
 =======================================================================================
	DEFINES
 =======================================================================================
 */
 
/*
 *	For child state when we call DetachFather function
 */
#define C_cChildIsRestored	0
#define C_cChildIsDeleted	1
#define C_cChildIsDestroyed	2
 
/*
 * for links type
 */
#define C_cLinkedAsValidChild			0x01
#define C_cLinkedAsDeletedChild			0x02
#define C_cLinkedAsChild				0x03 /*(C_cLinkedAsValidChild || C_cLinkedAsDeletedChild)*/
#define C_cLinkedAsValidFather			0x04
#define C_cLinkedAsIncoherentFather		0x08
#define C_cLinkedAsFather				0x0C /*(C_cLinkedAsValidFather || C_cLinkedAsIncoherentFather)*/
#define C_cLinkedAsChildAndFather		0x0F /*(C_cLinkedAsChild || C_cLinkedAsFather)*/
 
/*
 =======================================================================================
	coherence manager class
 =======================================================================================
 */
class CPA_EXPORT CCoherenceManager
{
  /*
   *	private data members
   */
  private:
	CChildMap				m_oChildMap;		/* map of all object who are child*/
	CFatherMap				m_oFatherMap;		/* map of all object who are father*/
	CChildMap				m_oDeletedChildMap;	/* map of all deleted child*/
	CFatherMap				m_oIncoherenceMap;	/* map of all object who are father and have a child that*/
												/* have been destroyed*/
 
	CCoherenceManagerDlg	*m_p_oCMDlg;	/* dialog box to show incoherence*/
	BOOL					m_bShowAlwaysDlg;
 
 
  /*
   *	private functions
   */
  private:
	/* ==> find object in a map as father or child */
	tdstFather		*m_fnp_stFindFather( CFatherMap *_p_oMap, CPA_BaseObject *_p_oFather );
	tdstChild		*m_fnp_stFindChild( CChildMap *_p_oMap, CPA_BaseObject *_p_oChild );
 
	/* ==> find object in a list as father or child */
	tdstFather		*m_fnp_stFindFather( CFatherList *_p_oList, CPA_BaseObject *_p_oFather );
	tdstChild		*m_fnp_stFindChild( CChildList *_p_oList, CPA_BaseObject *_p_oChild );
 
	/* ==> find child in a linked child list */
	tdstLinkedChild *m_fnp_stFindLinkedChild( CLinkedChildList *_p_oList, tdstChild *_p_stChild);
	tdstLinkedChild *m_fnp_stFindLinkedChild( CLinkedChildList *_p_oList, CPA_BaseObject *_p_oChild);
 
	/* ==> is object membership of a list */
	BOOL			m_fn_bIsFather( CFatherList *_p_oList, tdstFather *_p_stFather );
	BOOL			m_fn_bIsChild ( CChildList *_p_oList, tdstChild *_p_stChild );
	BOOL			m_fn_bIsChild ( CLinkedChildList *_p_oList, tdstChild *_p_stChild );
 
	/* ==> remove objects */
	void			m_fn_vRemoveAllFather( CFatherMap *_p_oMap );
	void			m_fn_vRemoveAllChild( CChildMap *_p_oMap );
 
	/* ==> remove links */
	void			m_fn_vDetachAllChild( tdstFather *_p_stFather, CChildMap *_p_oChildMap );
	BOOL			m_fn_bDetachAllFather( tdstChild *_p_stChild, char _cChildState );
 
  /*
   *	public functions
   */
  public:
	/* ==> constructor / destructor */
	CCoherenceManager();
	~CCoherenceManager();
 
	/* ==> option setting */
	void m_fn_vSetAutomaticCoherenceManagerDialog( BOOL bIsAuto ) { m_bShowAlwaysDlg = bIsAuto; }
	BOOL m_fn_bIsCoherenceManagerDialogAutomatic( void ) { return m_bShowAlwaysDlg; }
 
	/* ==> getting pointer on map */
	CChildMap	*m_fnp_oGetChildMap( void ) { return &m_oChildMap; }
	CFatherMap	*m_fnp_oGetFatherMap( void ) { return &m_oFatherMap; }
	CChildMap	*m_fnp_oGetDeletedChildMap( void ) { return &m_oDeletedChildMap; }
	CFatherMap	*m_fnp_oGetIncoherenceMap( void ) { return &m_oIncoherenceMap; }
	
	/* ==> getting pointer on internal structures */
	tdstFather  *m_fnp_stGetFather( CPA_BaseObject *_p_oFather ) { return m_fnp_stFindFather( &m_oFatherMap, _p_oFather ); }
	tdstChild	*m_fnp_stGetChild( CPA_BaseObject *_p_oChild ) { return m_fnp_stFindChild( &m_oChildMap, _p_oChild); }
 
	/* ==> dump a list */
	void m_fn_vDumpListsInFile( char *_szFile );
 
	/* ==> link management */
	void m_fn_vAddALink( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild );
	void m_fn_vRemoveLinks( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild, unsigned long _ulNbLinkRemoved );
	void m_fn_vRemoveALink( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild );
	void m_fn_vRemoveAllLinks( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild );
	void m_fn_vRemoveAllLinks( CPA_BaseObject *_p_oObject, char _cLinkType );
	unsigned long m_fn_ulGetLinkWeight( CPA_BaseObject *_p_oFather, CPA_BaseObject *_p_oChild);
 
	/* ==> object state */
	BOOL m_fn_bIsFather( CPA_BaseObject *_p_oFather );	
	BOOL m_fn_bIsChild( CPA_BaseObject *_p_oChild );
	BOOL m_fn_bIsIncoherent( CPA_BaseObject *_p_oFather );
 
	/* ==> getting list of father/child for an object */
	int	m_fn_iGetChildList( CPA_BaseObject *_p_oFather, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oChildList );
	int	m_fn_iGetChildCount( CPA_BaseObject *_p_oFather );
	int m_fn_iGetDeletedChildList( CPA_BaseObject *_p_oFather, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oDeletedChildList );
	int m_fn_iGetDestroyedChildNameList( CPA_BaseObject *_p_oFather, CList< char *, char *> *_p_oDestroyedChildNameList );
	int m_fn_iGetFatherCount( CPA_BaseObject *_p_oChild );
	int m_fn_iGetFatherList( CPA_BaseObject *_p_oChild, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oFatherList );
	int m_fn_iGetInvalidFatherList( CPA_BaseObject *_p_oChild, CList< CPA_BaseObject *, CPA_BaseObject *> *_p_oInvalidFatherList );
 
	/* ==> modification of an object */
	void m_fn_vDeleteObject( CPA_BaseObject *_p_oObject );
	void m_fn_vRestoreObject( CPA_BaseObject *_p_oObject );
	void m_fn_vDestroyObject( CPA_BaseObject *_p_oObject );
	void m_fn_vNotifyObjectModification( CPA_BaseObject *_p_oObject, unsigned long _ulData );
 
	/* ==> Incoherence list status */
	BOOL m_fn_bThereIsIncoherence( void );
 
	/* ==> Incoherence dialog */
	void m_fn_vShowIncoherence( void );
};
 
extern CPA_EXPORT CCoherenceManager g_oCoherenceManager;
 
#endif /* ACTIVE_EDITOR*/
 
#endif /*__COHEMNGR_HPP__*/
