// WindowDelegate.h: interface for the CWindowDelegate class.
//
//////////////////////////////////////////////////////////////////////

#if !defined( __RV_WINDOWDELEGATE_H_INCLUDED_)
#define       __RV_WINDOWDELEGATE_H_INCLUDED_
 

#ifdef WINDOWDELEGATE_EXPORTS
#define WINDOWDELEGATE_API __declspec(dllexport)
#else
#define WINDOWDELEGATE_API __declspec(dllimport)
#endif

#include <rvb\dsm.h>
#include <rvb\xgui.h>
#include <sst\ucb.h>

 

  

//UC 事件
#define RV_EID_UC_LM_CLICK           0x0020  //鼠标左键单击
#define RV_EID_UC_LM_DBLCLK          0x0021  //鼠标左键双击
#define RV_EID_UC_RM_CLICK           0x0022
#define RV_EID_UC_RM_DBLCLK          0x0023
#define RV_EID_UC_MOUSE_WHEEL        0x0024

//RV_EID_UC_POSCHANGED: WPARAM: hitresult(HP_MIDDLE or HP_GRABBER), LPARAM: 偏移（dx,dy）
//使用GET_X_LPARAM，GET_Y_LPARAM获得x,y的偏移量
#define RV_EID_UC_POSCHANGED         0x0025

//RV_EID_UC_POSCHANGED: WPARAM: hitresult(HP_EXTENDER ), LPARAM: 新位置
//使用GET_X_LPARAM，GET_Y_LPARAM获得x,y
#define RV_EID_UC_SIZECHANGED        0x0026


//RV_EID_UC_SELECTED: WPARAM: pObj, LPARAM: TRUE
#define RV_EID_UC_SELECTED        0x0010
#define RV_EID_UC_DELETED         0x0011
#define RV_EID_UC_APPENDED        0x0012

#define RV_EID_UC_BEFORE_DELETE   0x0015
#define RV_EID_UC_BEFORE_MOVE     0x0016
#define RV_EID_UC_BEFORE_RESIZE   0x0017

//	DELEGATE事件
//
//RV_EID_SELECT_CHANGED参数目前全为0，将来WPARAM(原来的 SEL数), LPARAM均为（最新的SEL数）
#define RV_EID_SELECT_CHANGED     0x0040 

#define RV_EID_LMOUSE_CLICK       0x0041
#define RV_EID_LMOUSE_DBLCLK      0x0042
#define RV_EID_RMOUSE_CLICK       0x0043
#define RV_EID_RMOUSE_DBLCLK      0x0044
#define RV_EID_MOUSE_WHEEL        0x0045//中间轮子滚动
#define RV_EID_KEY_UP             0x0046
#define RV_EID_KEY_DOWN           0x0047
#define RV_EID_CHAR_PRESS         0x0048
  
//画布或显示窗口大小改变
#define RV_EID_CANVASSIZE_CHANGED       0x0049
#define RV_EID_PIXELDEPTH_CHANGED       0x0050
#define RV_EID_DISPLAYSIZE_CHANGED      0x0051
#define RV_EID_DISPLAYPOS_CHANGED       0x0052


//销毁对象回调
typedef  void  ( *FN_DESTOY_OBJ) (void* pUcobj) ;
//事件处理回调
typedef  BOOL  ( *FN_EVENT_PROC) (RV_HANDLE hDelegate, RV_HANDLE hObj, UINT uEvent, WPARAM wParam, LPARAM lParam, void* pOwnerData);




class WINDOWDELEGATE_API CWindowDelegate : public CDelegate
{
public:
	
	enum LOGO_ALIGN{
		LA_LEFTTOP = 0,
		LA_RIGHTTOP,
		LA_LEFTBOTTOM,
		LA_RIGHTBOTTOM,
	};


	enum VIEW_MODE {
		VM_DEFAULT      =RV_VM_DEFAULT,
		VM_CENTER      = RV_VM_CENTER ,
        VM_STRETCH     = RV_VM_STRETCH ,
        VM_STRETCH_KR  = RV_VM_STRETCH_KR,
        VM_MULTI       = RV_VM_MULTI  ,
        VM_FULL3D      = RV_VM_FULL3D ,
		VM_STRETCH_4_3  ,
		VM_STRETCH_16_9 ,
		VM_CUSTOM   = RV_VM_CUSTOM,
	};

	enum BACKGOURND_STYLE{
		BS_DEFAULT = RV_BS_DEFAULT,
		BS_CHECK = RV_BS_CHECK,
		BS_HORIBAR = RV_BS_HORIBAR, //保留
		BS_VERTBAR = RV_BS_VERTBAR, //保留
		BS_GRID   = RV_BS_GRID,     //保留
	};

 
	//enum FLIP_TYPE{
	//   FT_NONE  = -1,
	//   FT_BOTH  = RV_DIR_BOTH,
	//   FT_HORI = RV_DIR_HORI,
	//   FT_VERT  = RV_DIR_VERT,
	//};
  
	//z order
	enum {
        ZO_TOP   =   0,
        ZO_UP     ,
        ZO_DOWN   ,
		ZO_BOTTOM , 
	};

	//paint image type
	enum PI_TYPE {
		 PI_DEFAULT  = RV_DI_DEFAULT,
		 PI_STRETCH  = RV_DI_STRETCH,
		 PI_CENTER  = RV_DI_CENTER  ,
		 PI_TILE    = RV_DI_TILE  ,
	     PI_ISOTROPY = RV_DI_ISOTROPY,
         PI_MIRROR_H = RV_DI_MIRROR_H   , 
         PI_MIRROR_V = RV_DI_MIRROR_V   ,
         PI_MIRROR_HV = RV_DI_MIRROR_HV  , 
         PI_FLIP_H = RV_DI_FLIP_H    ,
         PI_FLIP_V =RV_DI_FLIP_V     , 
         PI_FLIP_HV = RV_DI_FLIP_HV ,
	};

	//绘制图层
	enum{
	    LT_FRAME   = RV_LT_BACKGROUND,  //帧图像
	    LT_CANVAS  = RV_LT_CANVAS,      //画布层
	    LT_VIRTUAL = RV_LT_VIRTUAL,     //虚拟层
	    LT_DISPLAY = RV_LT_DISPLAY,     //窗口层
		LT_FOREGROUND  = RV_ALL_GRAPHICS,  //所有前景绘制层
		LT_ALL         = RV_ALL_LAYER,     //所有前景层
	};

 	CWindowDelegate();
	virtual  ~CWindowDelegate();


	virtual BOOL Create(HWND hWnd,  RV_CONTEXT_TYPE canvasType=RV_CT_GENERIC, int canvasWidth=-1, int canvasHeight=-1  );
	virtual void Destroy(); 

	virtual void SetViewMode(CWindowDelegate::VIEW_MODE mode, BOOL bRefresh=FALSE);
	CWindowDelegate::VIEW_MODE GetViewMode();

	//自定义风格的话，需要指定颜色GColor
	void  SetBackgroundStyle(int style, BOOL bRefresh=FALSE);
	DWORD  GetBackgroundStyle( );

	 
	void    SetCanvasColor(GColor color, BOOL bRefresh=FALSE);
	GColor  GetCanvasColor();

	void    SetBackgroundColor(GRgb color, BOOL bRefresh=FALSE);
	GRgb    GetBackgroundColor();

	 
	  
	void   SetBlankColor(GRgb color, BOOL bRefresh=FALSE);
	GRgb   GetBlankColor( );
	 
	 
	void  SetWindowTag(void* pTag);
	void* GetWindowTag();
	



	void SetRvbLogoVisible(BOOL flag, BOOL bRefresh=FALSE);
	BOOL  IsRvbLogoVisible();
	void  SetRvbLogoAlignment(CWindowDelegate::LOGO_ALIGN alignment, BOOL bRefresh=FALSE);
	CWindowDelegate::LOGO_ALIGN GetRvbLogoAlignment();

	void GetViewScale(float* pScaleX, float* pScaleY);
	void SetViewScale(float scaleX, float scaleY, BOOL bRefresh);

	//画布缩放后的大小，当比例为1时，该值与画布尺寸一致
	int GetViewWidth();
	int GetViewHeight();
	GSize GetViewSize();
	  
	//画布区域（相机图像区域）
	GRect GetClientRect();


	virtual GRect GetDisplayRect();

	//移动窗口
	virtual void SetDisplayRect(int left, int top, int width, int height,  BOOL bRefresh= FALSE);

	//不移动窗口
	virtual void SetDisplaySize( int width, int height,  BOOL bRefresh= FALSE);

	//移动窗口
	virtual void SetDisplayPos( int left, int top);


	//仍未实现全屏幕
	virtual void SetDisplayMaximized(BOOL bRestore,  BOOL bRefresh= FALSE);
	BOOL IsDisplayMaximized();

	virtual void ToppleFullScreen();


	GSize GetScrollBarRange();

	//该函数调用以后，需要使用Redraw(RT_REALIZE)进行窗口刷新。
	void  SetScrollBarPos(int pos, BOOL bVert);
	//该函数实际上获取viewpos
	void  GetScrollBarPos(GPoint* pPos);

	void    SetViewPos(int left, int top, BOOL bRefresh);
	RvPoint GetViewPos();



	BOOL IsWindowVisible();
	void ShowWindow(BOOL flag=TRUE);

	int  GetPictureSize();
	int  GetMaxPictureSize();
	void SetPictureSize(int size);

	void SetIndicaterOnTop(BOOL flag, BOOL bRefresh =FALSE);
	BOOL IsIndicaterOnTop();

public:
	void     AddUC(CUCObj* pObj, BOOL bSel=TRUE, BOOL bRefresh =FALSE);
	CUCObj*  GetUCAt( int index, BOOL bSelOnly=FALSE);
	int      GetUCCount( BOOL bSelOnly=FALSE);

	//调整order in z axis
	void  AdjustZorder(int type, CUCObj* pObj=NULL,   BOOL bRefresh=FALSE);


	void RemoveUC(CUCObj* pObj,  FN_DESTOY_OBJ fnDestroyObj=NULL, BOOL bRefresh =FALSE);
	void RemoveUC( const TCHAR* strName, FN_DESTOY_OBJ fnDestroyObj=NULL, BOOL bRefresh =FALSE);
	void RemoveUC( int index,  FN_DESTOY_OBJ fnDestroyObj=NULL, BOOL bRefresh =FALSE);
	void RemoveUC( UINT id,    FN_DESTOY_OBJ fnDestroyObj=NULL,BOOL bRefresh =FALSE);

	//by index
	void LockUC( int index, BOOL flag, BOOL bRefresh =FALSE);
	void DisableUC( int index, BOOL flag, BOOL bRefresh =FALSE);
	void HideUC( int index, BOOL flag, BOOL bRefresh =FALSE);
	void SelectUC( int index, int flag, BOOL bRefresh =FALSE);

	//by handle
	void LockUC(CUCObj* pObj, BOOL flag, BOOL bRefresh =FALSE);
	void DisableUC(CUCObj* pObj, BOOL flag, BOOL bRefresh =FALSE);
	void HideUC(CUCObj* pObj, BOOL flag, BOOL bRefresh =FALSE);
	void SelectUC(CUCObj* pObj, int flag, BOOL bRefresh =FALSE);

	//by name
	void LockUC( const TCHAR* name, BOOL flag, BOOL bRefresh =FALSE);
	void DisableUC( const TCHAR* name, BOOL flag, BOOL bRefresh =FALSE);
	void HideUC( const TCHAR* name, BOOL flag, BOOL bRefresh =FALSE);
	void SelectUC( const TCHAR* name, int flag, BOOL bRefresh =FALSE);


	//by id
	void LockUC( UINT id, BOOL flag, BOOL bRefresh =FALSE);
	void DisableUC( UINT id, BOOL flag, BOOL bRefresh =FALSE);
	void HideUC( UINT id, BOOL flag, BOOL bRefresh =FALSE);
	void SelectUC( UINT id, int flag, BOOL bRefresh =FALSE);


	//if release uc object ,the object should be allocated with NEW operator.
	// because we release it always with delete.
	void RemoveAll(FN_DESTOY_OBJ fnDestroyObj=NULL, BOOL bRefresh =FALSE);
	void LockAll(BOOL flag, BOOL bRefresh =FALSE);
	void DisableAll(  BOOL flag, BOOL bRefresh =FALSE);
	void HideAll(  BOOL flag, BOOL bRefresh =FALSE);
	void SelectAll(  BOOL flag, BOOL bRefresh =FALSE);


	virtual void Refresh(REFRESH_TYPE type);


public:

	//bRefresh仅在UI线程下有效，其他线程无效
	void ClearCanvas(int layer, BOOL bRefresh); //bRefresh仅在UI线程下有效，其他线程无效

	//该函数必须使用RT_REALIZE进行刷新，不可以使用RT_REDRAW。
	//效果清除使用ClearCanvas
	void PaintImage(const RvImage image, PI_TYPE type,  BOOL bRefresh=FALSE);//bRefresh仅在UI线程下有效，其他线程无效
	//void DrawObject( CUCObj* pObj, BOOL bRefresh= FALSE);//bRefresh仅在UI线程下有效，其他线程无效
	void DrawRect(int left, int top, int right, int bottom, float angle, BOOL bFill=FALSE,  BOOL bRefresh=FALSE);
	void DrawLine(int x0, int y0, int x1, int y1,  BOOL bRefresh=FALSE);
	void DrawEllipse(int cx, int cy, int rx, int ry, float angle, BOOL bFill=FALSE,  BOOL bRefresh=FALSE);

	GPen* Select(GPen* pPen);
	GBrush* Select(GBrush* pBrush );
	GMold* Select(GMold* pPost );



	BOOL SaveCanvas(RvImage image);

	//下面三个函数与SetSightFormat输入的值是对应的。
	int  GetCanvasWidth();
	int  GetCanvasHeight();
	RV_IMAGE_TYPE GetCanvasFormat();

	//读取当前视场图像属性
	RV_IMAGE_TYPE GetImageType();
	int  GetImageWidth();
	int  GetImageHeight();


	//FLIP_TYPE GetFlipType();
	//void SetFlipType(FLIP_TYPE type);


	


	//同一UI线程里面，可以将bRefresh设置为TRUE，进行刷新
	//不同线程里面进行刷新，可能发生错误。
	//该函数尝试获得UI锁，如果失败，不会往下执行
	virtual BOOL FeedFrame(const RvImage image, BOOL bRefresh=FALSE);
	BOOL FeedBuffer(void* pImgData, UINT nDataSize, BOOL bRefresh=FALSE);

	BOOL IsFrameFeeded()  ;
	//BOOL HasNewArrival();
	//void ResetArrival();

	//外部程序不可以删除GetCurFrame返回的图像
	//GetCurFrame是虚拟图像，需要使用GetCurFrame(RvImage image, BOOL bTry)
	//才能得到实际图像。
	//这个接口目前无法支持, del by hdy on 20210915
	//const RvImage GetCurFrame();
	//该函数会加锁
	BOOL   GetCurFrame(RvImage image, BOOL bTry=FALSE); 

	//如果返回成功，外部程序释放该图像。
	//该函数会加锁
	RvImage CopyCurFrame();

	void  RemoveCurFrame(BOOL bRefresh=FALSE);

	//应用程序(client)释放该图像对象。
	RvImage GetWindowPrint(void);

	//image  格式为rgb, 大小通过GetWindowPrintSize获得
	BOOL    GetWindowPrint(RvImage image);
	BOOL    GetWindowPrintSize(RvSize* pSize);

	//视场格式重新设置以后，当前的Feed状态	将设为FALSE。
	BOOL SetSightFormat(RV_IMAGE_TYPE type, int width, int height, BOOL bRefresh=FALSE );
	BOOL SetSightFormatE1(int pixelDepth, int width, int height, BOOL bRefresh=FALSE );




	//bRefresh仅在UI线程下有效，其他线程无效
	//SetDesignMode将影响：
	//1  DM_DESIGN: 编辑锁为FALSE， RVB标识不可见。
	//2  DM_RUNTIME: 编辑锁为TRUE, RVB标识可见,所有UC的选择状态为SS_NONE
	//在调用该函数以后，请重新调用相关的函数，对影响的参数进行恢复。
	virtual void SetDesignMode(int mode, BOOL bRefresh=FALSE) ;
	//CDelegate::DESIGN_MODE  GetDesignMode();



	//CUCObj* GetObjectAtPoint(  POINT pt );


public:
	//RealView的事件，非WINDOWS系统消息。
	//hObj为UC对象指针，如果为NULL，表示视场事件。
	//wParam， lParam根据不同的事件有不同的解释。
	//一般来说，如果是视场事件，而该事件又与每个UC有关的话，wParam一般为UC对象
	virtual BOOL EventProc(RV_HANDLE hObj, UINT uEvent, WPARAM wParam, LPARAM lParam) ;

	void  SetEventProcCallback(FN_EVENT_PROC fnEventProc, void* pOwnerData);
protected:


	BOOL TrackHandle( HWND hWnd, GPoint point, int nHitTest );
	void ClearSelFlags(RvList  pList, CUCObj* pCurSel );

	//清除当前为选定并为FOCUS状态的控件
	void ClearFocusSelFlags(RvList  pList, CUCObj* pCurSel );
	//设置从选择UC中的选择一个为FOCUS状态
	void SetFocusSelFlags(RvList  pList, CUCObj* pCurSel );

	//draw uc in run mode
	void DrawObjectInList(RvList  pList,  BOOL bForce);
	//draw uc in edit mode
	void DrawObjectInEditMode( );

	void DrawSingleObject(CUCObj* pObj, BOOL bForce, BOOL bIndicaterOnTop );


	RvSequence    m_lstZOrder;
	FN_EVENT_PROC m_fnEventProc;
	void*         m_pOwnerData;

protected:
	 
	//RvImage  m_imCurFrame ;

	//Del by HDY on 20210915 xguiv5.1已经支持帧图像
	//HANDLE m_hFrameStroke; //绘制图像帧的笔画 

	//del by HDY on 20211027, 翻转由应用程序控制
	//这里控制容易搞混
	//CWindowDelegate::FLIP_TYPE m_nFlipType;

	BOOL     m_bRvbLogoVisible;
	BOOL     m_bDrawIndicaterOnTop;
private:
	RvCluster PrepareDescriptor(CSketchMark* pMark, GPoint point, int nHitTest);
	void      TrackDescriptor(CSketchMark* pMark, RvCluster clsTrack, GPoint point, int nHitTest , GPoint& moustPoint);
	void      FinishDescriptor(CSketchMark* pMark, RvCluster clsTrack,  GPoint point, int nHitTest, BOOL bRollback);
	BOOL     InitMiscObject();

	void* m_pTag;  //windows tag

};



WINDOWDELEGATE_API  BOOL rwdAuthorize(const TCHAR* strFilePath, const TCHAR* strAppName , const TCHAR* strLicence );
WINDOWDELEGATE_API  BOOL rwdIsAuthorized();






#endif // !defined(__RV_WINDOWDELEGATE_H_INCLUDED_)
