#ifndef __CONTAINER_H__
#define __CONTAINER_H__

#include "window.h"
#include "CObjBuffer.h"
#include "CObjectContainer.h"
#include "keydef.h"
#include "CObjTimer.h"


#define DEBUG_CONTAINER 0

// les flags de creation du container
#define CO_MENU							(1<<0)
#define CO_NOBORDER                     (1<<1)
#define CO_NOCAPTION					(1<<2)
#define CO_NOCLIPCHILDREN               (1<<3)
#define CO_CHILDINSIDE                  (1<<4)
#define CO_MINBOX                       (1<<5)
#define CO_MAXBOX                       (1<<6)
#define CO_SIZEBOX                      (1<<7)
#define CO_HIDE                         (1<<8)
#define CO_MINIMIZE                     (1<<9)
#define CO_MAXIMIZE                     (1<<10)
#define CO_DISABLE						(1<<11)
#define CO_3DBORDER						(1<<12)

 
#define NB_RFLCONTAINER			 18
#define RFLCONTAINER_DESTROY	 0
#define RFLCONTAINER_MOVE		 1
#define RFLCONTAINER_SIZE		 2
#define RFLCONTAINER_SETFOCUS	 3
#define RFLCONTAINER_KILLFOCUS	 4
#define RFLCONTAINER_PAINT		 5
#define RFLCONTAINER_KEYUP		 6
#define RFLCONTAINER_KEYDOWN	 7
#define RFLCONTAINER_CLICK		 8
#define RFLCONTAINER_UNCLICK	 9
#define RFLCONTAINER_DBLCLICK	 10
#define RFLCONTAINER_MOUSEWHEEL  11
#define RFLCONTAINER_MOUSEHOVER  12
#define RFLCONTAINER_MOUSELEAVE  13
#define RFLCONTAINER_CURSORMOVE  14
#define RFLCONTAINER_PREDESTROY  15
#define RFLCONTAINER_PRERENDER	 16
#define RFLCONTAINER_POSTRENDER	 17

#define LBUTTON 1
#define RBUTTON 2
#define MBUTTON 3
 
//conbstantes d'etat du container
#define CONTAINER_HIDDEN		0
#define CONTAINER_UNHIDDEN		1
#define CONTAINER_NORMAL		1
#define CONTAINER_MAXIMIZED		3
#define CONTAINER_MINIMIZED		6		
#define CONTAINER_RESTORED		9

#ifndef MK_SHIFT

// definition des constantes des boutons
#define MK_LBUTTON          0x0001
#define MK_RBUTTON          0x0002
#define MK_SHIFT            0x0004
#define MK_CONTROL          0x0008
#define MK_MBUTTON          0x0010

#endif


// Initialisation du container
BOOL	InitContainer(HINSTANCE hInst);
BOOL	UnLoadContainer();


// class container associé à une fenetre
class container  
{
private:

	int							CoCursorPosX;
	int							CoCursorPosY;
	
	int							CoTabStopSize;			// nb objets en tabstop
	PtrObjectBase               *CoTabStopObjects;		// liste des objets en tabstop
	
	// exec render scol reflex
	int							ExecuteReflexRender(mmachine,int,Rect2D);
	
	
	int							posTabStop(PtrObjectBase);			// renvoie la position d'un objet 
																    // dans la liste des tabstop
	PtrObjectBase				nextTabStop(PtrObjectBase);			// renvoie le tabstop suivant
	PtrObjectBase				prevTabStop(PtrObjectBase);			// renvoie le tabstop precedent
	int							testTabStop(int);					// test si tabstop ou pas

protected:
	
	Window						*CoWin;					// window

	int							CoEnabled;				// container enable
	int							CoXsize;				// taille du container
	int							CoYsize;
	
	PtrObjectBase				CoRoot;					// objet root
	PtrObjBuffer				CoBuffer;				// buffer de rendu
	int							CoBackgroundColor;		// couleur de fond

	CObjTimer					*CoTimerService;		// service de timer
	
public:

	// les boutons de la souris actuellement appuyées
	int							CoCurrentKeyFlags;


	PtrObjectBase				CoNewHandledObject;	  // objet prochainement handlé
	PtrObjectBase				CoHandledObject;	  // objet actuellement handlé
    PtrObjectBase				CoFocusedObject;	  // objet qui a le focus
	PtrObjectBase				CoActiveObject;		  // objet qui est actif
	PtrObjectBase				CoActiveToolTipObject;// objet qui a un tooltip actif 
	

	int							CoOutPushedAlreadySent;
	int							CoInPushedAlreadySent;
	int							CoUserMoveIsAllowed;
	
	// pour les evenements HOVER et LEAVE
	BOOL						CoTMEcursorInContainer;
	int							CoTMEtimer;
	int							CoTMEflags;

	/*--------------------------------------------------------------------------------------------*/
	
	// constructeur-destructeur
	container(Window *,int,int,int);
	virtual ~container();
	
	// fonctions de creation-destruction de l'ObjContainer dans la pile Scol
	// la fonction de creation doit etre appelée apres avoir fait un new
	// car un constructeur ne peut renvoyer d'erreurs!!!!
	virtual	int					ConstructScolContainer(mmachine m);
	virtual int					DestructScolContainer(mmachine m,int p_obj);

	// les differentes methodes du moteur
	int							HdlPreDestroy(int id);
	int							HdlDestroy(int id);
	int							HdlPaint(int id);
	int							HdlSize(int id,UINT state, int cx, int cy);
	int							HdlMove(int id,int x, int y);
	int							HdlSetFocus(int id);
	int							HdlKillFocus(int id);
	int							HdlKeyDown(int id,UINT vk, BOOL keysys, int cRepeat, UINT flags);
	int							HdlKeyUp(int id,UINT vk, int cRepeat, UINT flags);
	int							HdlClick(int id,int typebouton, int x, int y, UINT keyFlags);
	int							HdlUnClick(int id,int typebouton, int x, int y, UINT keyFlags);
	int							HdlDblClick(int id,int typebouton, int x, int y, UINT keyFlags);
	int							HdlMouseWheel(int id,int delta, int x, int y, UINT keyFlags);
	int							HdlMouseHover(int id);
	int							HdlMouseLeave(int id);
	int							HdlMouseMove(int id,int x, int y, UINT keyFlags);
	
	// fonctions de redraw du container
	void						Redraw(int RepaintFlag);
	void						RedrawArea(Rect2D area2redraw,int RepaintFlag);

	// recupere la taille du container
	int							GetSize(int*,int*,int*,int*,int); 
	// Enable or Disable container
	int							Enable(int etat);
	
	// Retrieve cursor Coordinates
	Point2D						GetCursorPosClient();	
	Point2D						GetCursorPosScreen();
	// service de timers
	int							Register( int delay, CObjectBase *object );
	int							Unregister( int id );

	// track mouse event
	int							StartTME(int Flags);
	
	// fonction verifiant si un objet appartient bien au container
	int							OwnsObject(CObjectBase *);
	
	// fonction changeant le focus sur un objet
	int							SetFocus(PtrObjectBase);

	// le tabstop
	int							addTabStopObjects(PtrObjectBase);	// ajout d'un objet en tabstop
	int							remTabStopObjects(PtrObjectBase);	// suppression d'un objet en tabstop
	int							resetTabStop();						// reset le tableau des tabstop

	// fonctions in-line
	inline Window				*GetPtrWindow(){return CoWin;}
	inline PtrObjectBase		Root(){return CoRoot;}
	inline BOOL					IsEnabled(){return CoEnabled;}
	inline void					SetRoot(PtrObjectBase root){CoRoot=root;}
	inline int					GetXSize(){return CoXsize;}
	inline int					GetYSize(){return CoYsize;}
};


container * RetrievePtrContainer(mmachine m,int pdesc);
container * RetrieveContainerFromHdlSys(int hdlsys);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                      FONCTIONS SCOL DU CONTAINER FENETRE										   //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int _CRcontainerFromObjCont(mmachine);
int _CRcontainerFromObjWin(mmachine);
int _SHOWcontainer(mmachine);
int _MOVEcontainer(mmachine);
int _SETcontainerName(mmachine);
int _SIZEcontainer(mmachine);
int _SIZEEXcontainer(mmachine);
int _TOPcontainer(mmachine);
int _ENcontainer(mmachine);
int _GETcontainerPositionSize(mmachine);
int _GETcontainerExPositionSize(mmachine);
int _SETfocusContainer(mmachine);

//$LB (11/11/2003)
int _SETcontainerCursor ( mmachine m );



// fonctions reflexes par defaut de la fenetre associée au container
int RFLwincontainerClick(mmachine);
int RFLwincontainerUnClick(mmachine);
int RFLwincontainerDblClick(mmachine);
int RFLwincontainerKeyDown(mmachine);
int RFLwincontainerKeyUp(mmachine);
int RFLwincontainerFocus(mmachine);
int RFLwincontainerKillFocus(mmachine);
int RFLwincontainerMove(mmachine);
int RFLwincontainerSize(mmachine);
int RFLwincontainerClose(mmachine);
int RFLwincontainerDestroy(mmachine);
int RFLwincontainerCursorMove(mmachine);
int RFLwincontainerMouseWheel(mmachine);
int RFLwincontainerPaint(mmachine);
 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                      FONCTIONS SCOL DU CONTAINER	VIRTUEL 									   //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////                           

// createur-destructeur
int _CRcontainer(mmachine);
int _DScontainer(mmachine);

// les differentes methodes associées au moteur du container
int _METHODcontainerPreDestroy(mmachine);
int _METHODcontainerDestroy(mmachine);
int _METHODcontainerPaint(mmachine);
int _METHODcontainerSize(mmachine);
int _METHODcontainerMove(mmachine);
int _METHODcontainerFocus(mmachine);
int _METHODcontainerKillFocus(mmachine);
int _METHODcontainerKeyDown(mmachine);
int _METHODcontainerKeyUp(mmachine);
int _METHODcontainerClick(mmachine);
int _METHODcontainerUnClick(mmachine);
int _METHODcontainerDblClick(mmachine);
int _METHODcontainerMouseHover(mmachine);
int _METHODcontainerMouseLeave(mmachine);
int _METHODcontainerMouseWheel(mmachine);
int _METHODcontainerMouseMove(mmachine);

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                      FONCTIONS SCOL COMMUNES AU DEUX CONTAINERS								   //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////                           
// le buffer OffScreen
int _GETcontainerMap(mmachine);

// le paint
int _PAINTcontainer(mmachine);
int _PAINTcontainerArea(mmachine);

// Les reflexes du container 
int rflPreDestroyContainer(mmachine);
int rflDestroyContainer(mmachine);
int rflMoveContainer(mmachine);
int rflSizeContainer(mmachine);
int rflSetFocusContainer(mmachine);
int rflKillFocusContainer(mmachine);
int rflPaintContainer(mmachine);
int rflKeyUpContainer(mmachine);
int rflKeyDownContainer(mmachine);
int rflClickContainer(mmachine);
int rflUnClickContainer(mmachine);
int rflDblClickContainer(mmachine);
int rflMouseWheelContainer(mmachine);
int rflMouseHoverContainer(mmachine);
int rflMouseLeaveContainer(mmachine);
int rflCursorMoveContainer(mmachine);
int rflPreRenderContainer(mmachine);
int rflPostRenderContainer(mmachine);

// destruction interne de l'OBJCONTAINER
int DsContainer2(mmachine,int,int);

#endif