// AreaCal.h: interface for the CAreaCal class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(__RV_AREACAL_H_INCLUDED_)
#define __RV_AREACAL_H_INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "CaliX.h"
#include <rvb\pick.h>
 
//
//#define RV_SAS_SOLID        1
//#define RV_SAS_GRID         2
//#define RV_SAS_DIAG         3
//#define RV_SAS_CROSS        4
//#define RV_SAS_OUTLINE      5

//
//
//CAreaCal支持的属性名称,大小写不敏感
// Avg - "求平均"
// Var - "求方差"
// PixSum - "象素和"
// PixCount - "非零象素的数量" 
// Area     - "非零象素的数量"  
// MinPos - "最大灰度值像素的位置"
// MaxPos - "最小灰度值像素的位置" 
// MaxPix - "最大的像素灰度值"
// MinPix - "最小的像素灰度值"
//
//
//

class CALIX_API CAreaCal : public CCaliber  
{
public:
	CAreaCal();
	virtual ~CAreaCal();
		
	enum BINZ_METHOD{
	    BM_USER   =   -1,
        BM_SIMPLE =   0, 
		BM_INNER_RANGE ,
		BM_OUTER_RANGE,
		BM_MAX_ENTROPY,   //MAX ENTROPY
		BM_RESIDUAL_P,  //MIN ERRORV  Poinssen residual
		BM_RESIDUAL_G,  //Gaussian residual
		BM_EDGE_H,  //edge horizontal
		BM_EDGE_V,  //edge vertical 
		BM_EDGE_HV,  //edge both horizontal and vertical
		BM_CANNY, 
	};

	enum GREY_METHOD{
		GM_USER   =   -1,
		GM_DEFAULT =0,
		GM_HSV,
		GM_RED , 
		GM_GREEN ,
		GM_BLUE,
		GM_MAX,
		GM_MIN,
		GM_AVG,
		GM_MIN_RG,
		GM_MIN_RB,
		GM_MIN_BG,
		GM_AVG_RG,
		GM_AVG_RB,
		GM_AVG_BG,
		GM_MAX_RG,
		GM_MAX_RB,
		GM_MAX_BG,
	};

	//REGION APPEARANCE STYLE
	enum STYLE{
		RS_UNKOWN  = -1, //未知
		RS_DEFAULT  = 0,   //默认                 
		RS_SOLID = RV_PFS_SOLID,
		RS_GRID = RV_PFS_GRID,
		RS_DIAG = RV_PFS_DIAG,
		RS_CROSS = RV_PFS_CROSS,
		RS_OUTLINE,
		RS_PREVIEW,  //pick的ROI形状中对应的图像
	};

	enum SHAPE{
		CS_UNKNOWN =-1,
		CS_RECT    =  RPS_RECT, 
		CS_CIRCLE  = RPS_CIRCLE   ,
		CS_ANNULUS = RPS_ANNULUS,   
		CS_RING    = RPS_TORUS   , 		
		CS_ADAPT   = RPS_POLYGON,
		CS_ELLIPSE = RPS_ELLIPSE,
		CS_SECTOR  = RPS_SECTOR,
		CS_CUSTOM  = RPS_CUSTOM,
	};

	 

	//these shapes is for customized pick only.
	//1  horizontal strap
	// ..  ..
	// ..  ..
	// ..  ..
	//
	//2  vertical strap
	//  ::::: 
	//
	//  :::::
	//  
	//
	//3 strap in both
	//   :::::
	// ..     ..
	// ..     ..
	// ..     ..
	//   :::::
	//
	//4  enclosure
	//:::::::::
	//..     ..
	//..     ..
	//..     ..
	//:::::::::
	//
	//
	enum SHAPE_EX{
		CS_EX_STRAP_HORI = CS_CUSTOM + 1,   //从CUSTOM派生的，ID必须大于CS_CUSTOM
		CS_EX_STRAP_VERT = CS_CUSTOM + 2,
		CS_EX_STRAP_BOTH = CS_CUSTOM + 3,
		CS_EX_ENCLOSURE  = CS_CUSTOM + 4,   //closed strap
	};         

	virtual BOOL Serialize(HANDLE device, BOOL bIn ) ;
    virtual CUCObj* Clone( CUCObj* twin) ;

	virtual void Reset();
 
	virtual BOOL  Create(/*CDelegate* pDelegate ,*/ const TCHAR* strName, UINT id = -1, int style= RV_UC_DEFAULT_STYLE) ;
	virtual void  Destroy(/*BOOL bEraseStroke =FALSE*/) ;
	 
	 
	virtual void  SetStyle(int style);

	
	 
	//灰度或RGB转成二值图.
	//APP不能删除该图像
	const RvImage  Binarize();

	//RGB转成灰度图.
	 //APP不能删除该图像
	const RvImage  Greyout();

	
	virtual void Shot(int mode ,const RvImage image )   ;
	virtual void ShotEx(int mode , const RvImage image , int left, int top)  ;
	
	static void ToGray(RvImage image, int method, RvMask mask = NULL);
	static void ToBin(RvImage image, int method, int lower, int upper, BOOL bReverse, RvMask mask = NULL);
	
	//根据mipLevel,缩小的合适的比例图像,返回缩小的比例,同时缩小图像
	//mipLevel必须大于等于0
	static float ShrinkToProperScale(RvImage image, int minWid, int minHei, int mipLevel,   int method = RV_FM_BILINEAR);
	//void ToBin(RvImage image, int method,   RvMask mask = NULL);

public:
		
	virtual void  Show(CDelegate* pDelegate, int mode, BOOL bForce);
	virtual void  ShowExtender(CDelegate* pDelegate, CLeadMark* pMark/*, BOOL bGrabber*/); 
	virtual void  ShowGrabber(CDelegate* pDelegate, CLeadMark* pMark );

	BOOL  IsBodyHit(CDelegate* pDelegate,RvPick pick, GPoint point);
	GRect GetCompactRect(RvPick pick);

	//void ShowSketch(CSketchMark* pMark,  int dx, int dy);


	int  GetStrapWidth( ){return m_nStrapWidth;};
	void SetStrapWidth(int val);



	//SetShape函数会引起PICK HANDLE改变，需要重新
	//调用GetHandle();
	virtual void SetShape(int shape);
	int  GetShape(){return m_nShape;};
	RvPick GetHandle(){ return m_pikZone; };

	//
	virtual void  SetDisplayStyle(int style);
	int GetDisplayStyle() {return m_nDisplayStyle; } 

	

	//应用程序不可删除GetImage返回的图象指针。
	 const  RvImage GetImage();

	//应用程序不可删除GetMask返回的模板指针。
	const RvMask  GetMask();

	virtual void SetGeometryAt(int index, RvFloat32 value, BOOL bUpdate=FALSE) ;
	virtual RvFloat32  GetGeometryAt(int index) ;
	virtual int  GetGeometryCount();

	void UpdateMask();

	//设置自适应和自定义CALIBER
	void SetAdaptVertex  (RvPoint_f* pVertexArray, int nVertexCount);
	void SetCustomMask( RvMask mask);

	//仅对RECT形状的AREACAL有效。
	//virtual void  SetClientRect(int x, int y, int w, int h);
	virtual void  SetCtrlRect(int left, int top, UINT width, UINT height);


	//virtual void   SetCtrlRect(int left, int top, int right, int bottom) ; 
	//virtual RvRect GetCtrlRect();
	//virtual void   SetCtrlPos(int x, int y);
	//virtual RvPoint GetCtrlPos();

//for delegate only
public:
	//返回实际画布坐标的矩形,非旋转
	virtual GRect GetCurRect() ;

	//在GetCurRect基础上旋转一个角度 
	RvRect_f GetCurRectR(float angle);


	virtual GRect GetGrabberRect(CDelegate* pDelegate,RvSize size);
	virtual GRect GetExtenderRect(CDelegate* pDelegate,int index, RvSize size);
	//virtual GRect GetRotaterRect(CDelegate* pDelegate,GPoint& center, double angle, RvSize size) ;

	virtual int  HitTest(CDelegate* pDelegate,GPoint point);


	 
	virtual void Move(double dx, double dy) ;
	virtual void EndAlign(BOOL bUpdate);
	//virtual void MoveEx(double dx, double dy, double cx, double cy, double angle);

	virtual BOOL  OnPositionChange(HGPD hOri,HGPD hCur,HGPD hNew, GPoint grabPos, RvOffset &offset) ;
	virtual BOOL OnExtenderChange(HGPD hCur, HGPD hNew,int index, GPoint &point) ;

	virtual BOOL OnRotationChange(HGPD hCur, HGPD hNew, GPoint &curPos);

	virtual void OnBeginTrack(CDelegate* pDelegate,HGPD hCur, GPoint point, int type)  ;
	virtual void OnEndTrack(CDelegate* pDelegate,HGPD hCur,  GPoint point, int type)  ;

	virtual void ShowSketch(CDelegate* pDelegate, CSketchMark* pMark,  HGPD hGpd, int grabType, GPoint grabPos);   
	//virtual void ShowSketch(RvPoint leftTop, RvPoint rightBottom);

	virtual void UpdateShape(CDelegate* pDelegate, HGPD hGpd, BOOL bMove)  ;


	//下面三个函数一般仅与当前的类图形描述符有关，
	//一般不用调用父类的同名虚拟函数。
	virtual HGPD CreateGraphicDescriptor(CDelegate* pDelegate) ;
	virtual void DestroyGraphicDescriptor(HGPD hGpd);
	virtual void CopyGraphicDescriptor(const HGPD src, HGPD dest);



public:
	
	BINZ_METHOD   m_nBinzType;
	GREY_METHOD   m_nGreyType;

	int           m_nThresLower, m_nThresUpper;
	BOOL          m_bReverseBin;

	int           m_nMipLevel ; //

	//当二值化为BM_EDGE_H，BM_EDGE_V，BM_EDGE_HV的时候 
	//m_nEdgeSense有效,范围0->5.0,或更大
	float         m_nEdgeSense; 
 	
protected:
	typedef struct _caliber_graphic_descriptor{
		int shape;

		union{
			//for rect, circle, custom, extended strap
			struct _rect{
				GPoint p1,p2,p3,p4,p5, p6, p7, p8;    
			}rect;	    

			//for ring
			struct _ring
			{  
				GPoint pi,po,c;
			}ring;

			//For annulus
			struct _annulus
			{
				GPoint s,e,i,o;
			}annul;

			//for adapt
			struct _adapt{				
				int     nVertexCount;
				GPoint* pVertexArray;
			}adapt;
		};

		RvPoint rotcent;
		double  angle;

	}GdCaliber;

	static void draw_annulus_sketch(CSketchMark* pMark, GdCaliber  * pGc);
	static BOOL validate_annulus_descriptor(GdCaliber* pGc, float& cx, float& cy, float& r1, float& r2, double& sa, double& ea);
  
	void DuplicateRegion(RvPick src, RvPick dest);



	RvPick  m_pikZone; 
	int     m_nShape;

	int  m_nDisplayStyle;

protected:

	int   m_nStrapWidth;
	
private:


	BOOL  IsRectExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point);
	BOOL  IsCircleExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point);
	BOOL  IsRingExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point) ;
	BOOL  IsCustExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point) ;
	BOOL  IsAnnulusExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point) ;
	BOOL  IsAdaptExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point) ;
	BOOL  IsStrapExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point) ;

	
	void ResetRegionShape(int shape);


};



#endif // !defined(__RV_AREACAL_H_INCLUDED_)
