#if !defined(__RV_CURVECAL_H_INCLUDED_)
#define      __RV_CURVECAL_H_INCLUDED_

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

#include "CaliX.h"
 
#include <rvb\cutt.h>


#define CC_CA_ANGLE_COUNT  3


class CALIX_API CCurveCal :	public CCaliber
{
public:
	CCurveCal(void);
	virtual ~CCurveCal(void);

	enum
	{
		CT_POINT=RCT_POINT, //点
		CT_LINE =RCT_LINE,  //直线
		CT_ARC    =RCT_ARC,   //圆弧
		CT_CIRCLE =RCT_CIRCLE, //圆
		CT_BULLEYE=RCT_BULLEYE, //牛眼
		CT_PARALLEL=RCT_RAKE,//平行线
		CT_RAY     =RCT_SPOKE,    //放射线				
		CT_POLYLINE=RCT_POLYLINE, //多段线
		CT_ELLIPSE = RCT_ELLIPSE, //椭圆
		CT_ANYTWO  = RCT_ANY_TWO, //任意两线段  
	    CT_POLYGON = RCT_POLYGON, //封闭多边形
	    CT_ANYSEG = RCT_ANY_SEG, //任意数量线段，一个线段两个点，线段之间不连续
	    CT_SQUARE = RCT_SQUARE, //方形
	};

 
	////线型
	//enum 
	//{
	//	LT_SOLID = RV_PS_SOLID,
	//	LT_HIDDEN = RV_PS_HIDDEN,
	//	LT_CENTER  =RV_PS_CENTER,
	//	LT_INCLUSION = RV_PS_INCLUSION,
	//};
	virtual void Show(CDelegate* pDelegate, int mode, BOOL bForce);

	//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();
	 

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

	virtual BOOL  Create(  const TCHAR* strName,  UINT id, int style = RV_UC_DEFAULT_STYLE); 
	virtual void  Destroy( ) ;
	
	virtual void Shot(int mode, const RvImage image );
	virtual void ShotEx(int mode, const RvImage image , int left, int top)  ;
	 
	//dx,dy分别为水平方向和垂直方向的偏移量
	virtual void Move(double dx, double dy) ;
	virtual void EndAlign(BOOL bUpdate);
	 


	//SetCurveType函数会引起CUT HANDLE改变，需要重新
	//调用GetHandle()获得新HANDLE;
	void SetCurveType(int type);
	int  GetCurveType(){ return m_nCurveType; };
	RvCut GetHandle(){ return m_curve; };

	//获得曲线路径，有些类型的曲线有多条路径
	int  GetPathCount();
	RvPath GetPathAt(int index);

	//仅对ray, bulleye, parallel, polyline，polygon有效
	//该函数与GetPathCount的值是一致的。
	//count表示线段的数量,或顶点数
	//但不是curve的几何值数量
	//该函数将过时，请使用SetSegmentCountV2
	void  SetSegmentCount(int count);

	//仅对ray, bulleye, parallel, polyline，polygon, anyseg有效
	//count仅表示线段数量
	//该函数将对count进行验证，符合要求的数值才能设置成功。
	BOOL  SetSegmentCountV2(int count);
	
//	void SetScale(float scaleX, float scaleY);
//	void GetScale(float* pScaleX, float* pScaleY);
	 
	int GetGeometryCount();
	double GetGeometryAt(int index);

	void   SetGeometryAt(int index, double value, BOOL bUpdate );
	void   UpdateMap(); 

//delegate relatives
public:

	virtual GRect GetGrabberRect(CDelegate* pDelegate,RvSize size);
	virtual GRect GetExtenderRect(CDelegate* pDelegate,int index, RvSize size);
	virtual GRect GetCurRect() ;

	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 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 HGPD CreateGraphicDescriptor(CDelegate* pDelegate) ;
	virtual void DestroyGraphicDescriptor(HGPD hGpd);
	virtual void CopyGraphicDescriptor(const HGPD src, HGPD dest);

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

protected:
	 
	typedef struct _curvecal_graphic_descriptor{
		int type;  

		//点: p0
		//直线,p0,p1
        //平行线: p0, p1,p2,p3   
		//圆弧: p0,p1, p2 - p0为起始点， p1为任意中间点，p2为结束点
		//圆:  p0,p1, p2  - p0,p1,p2为圆弧上任意点
		//ray, bulleye : p0为圆心, p1为内圆0度位置圆弧点，p2为外圆0度位置圆弧点
		//椭圆：p0为长轴左边点, ,p1为短轴上方点,p2为长轴右边点, p3为短轴下方点
		//方形：p0, p1,p2,p3为左上角，右上角，右下角，左下角。
	    GPoint p0,p1,p2,p3;   

		union{
		     double angle; //旋转角度, 椭圆短边长度
			 double shortLen;     //椭圆短边长度
			 int    nVtxCount; //多段线的点 //polyline
			 double width;     //方形宽度
		};

		union{
			 double longLen; ////椭圆长边长度
			 GPoint* pVtxArr;   //定点数组 //polyline
			 double  height;     //方形高度
		};
		 
	}GdCurveCal;

	BOOL IsRectExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point_in) ;

	RvCut  m_curve;
	int m_nCurveType;
	
	//appearance style
	//int  m_nLineType;
	//int  m_nLineWidth;

	double m_nExtenderAngles[CC_CA_ANGLE_COUNT];
	 
	void DuplicateCurve(RvCut src, RvCut dest);

	GRect GetCompactRect(const RvCut curve);

	//BOOL IsCircleExtenderChanged( HGPD hCur, HGPD hNew,int index, GPoint &point);
 
	//单位：度
	void  RotateVertex( int x0,  int y0, double angle, GPoint& point);

	//单位：度
	float GetNormalAngle(float y, float x);
	double GetNormalAngle(double y, double x);

	BOOL IsCurveHit(CDelegate* pDelegate, const RvCut curve, GPoint point);
};



#endif //__RV_CURVECAL_H_INCLUDED_
