#pragma once

#include "blobx.h"

#define CDD_CLOSED    1
#define CDD_HOLE      (1<<1)
 
typedef struct __cd_contour_descriptor
{
	int     type;
	int     flags;
	//BOOL    bClosed;
	//BOOL    bHole;
	float   posError;  //位置误差,半径
	float   lenError;  //长度误差
	RvPoint center;
	int     perimeter;  

	union{
		struct {
			int     innerSize;    
			RvPoint* pInnerArray;  
			int     outerSize;    
			RvPoint* pOuterArray;  
		}cntr;
		struct{
			int resample; //重新采样
			int sigma;    //smooth sigma
			int posCount;
			RvPoint* pPosArray;
		}kappa; //曲率方式检测边缘缺陷点
	};
}CD_CNTR_DESCRIPTOR;

#define CD_MAX_CONTOUR_COUNT    127


//检测边缘是否平滑，用于边缘缺陷检测
class BLOBX_API CContourDefect :	public CBlobExtractor
{
public:
	CContourDefect(void);
	virtual  ~CContourDefect(void);

	enum DETECT_TYPE{
		CD_DEFAULT =0,  //默认
	    CD_KAPPA,       //高级   		
	};
	 
	virtual BOOL Serialize(HANDLE device, BOOL bIn ) ;
    virtual CUCObj* Clone(  CUCObj *twin) ;
	 virtual void Show(CDelegate* pDelegate,int mode, BOOL bForce) ;

	virtual RV_BOOL Inspect(int* pErrCode=NULL);
	 
	virtual void Reset();
	 
	//外部编辑和学习接口
	void RemoveAllContours();
	int  GetContourCount();
	int AddContour(RvPoint center, float   posError, int perimeter, float   lenError, const RvPoint* pOuterArray, int outerCount, const RvPoint* pInnerArray, int innerCount, int flags);
	int AddContour(RvPoint center, float   posError, int perimeter, float   lenError, int resample, int sigma, int cssCount, const RvPoint* pPosArray, int flags);

	int RemoveContour(RvPoint center, int perimeter);
	CD_CNTR_DESCRIPTOR* GetContourAt(int index);
	  
	//检测后结果函数
	int GetDefectCount() ;
	RvPoint GetDefectPos(int index);
	
	int  GetDetectMethod();
	void SetDetectMethod(int method);

	BOOL IsResultValid(){ return m_bDefectDetected; };
	int  GetCheckedCount(){ return m_nCheckedCount; };
	
	int Learn(int maxCount, int innerDist, int outerDist, float   posError, float   lenError);
	int LearnE1(int maxCount, int resample, int sigma, float   posError, float   lenError);
	 

public:
	int m_nEdgeCount;
	int m_nMinLength;
	float m_nLenError;  //像素为单位
    float m_nPosError;  //像素为单位
	int   m_nInnerDist; //resample
	int   m_nOuterDist; //sigma

public:
	//下面的函数可以绘制到外部的DC
	//bIgnoreAlign为保留参数，用于对齐的情况
	RV_HANDLE DrawDefects(HGDC dc, int offsetx, int offsety,  BOOL bIgnoreAlign, RV_HANDLE hStroke);
	RV_HANDLE DrawCheckZones(HGDC dc, int offsetx, int offsety,BOOL bIgnoreAlign, RV_HANDLE hStroke);


protected :
    void RemoveAllDefects();
	 
	RvPoint* FindDefect(RvPoint* pEdgeArr ,int nArrSize, int* pDefectCount);
	RvPoint* FindDefect(CD_CNTR_DESCRIPTOR* pCdArr ,int nArrSize, int* pDefectCount);
	 
	//RV_HANDLE DrawDefect(HGDC dc, RV_HANDLE hStroke);
	 
	DETECT_TYPE m_nDetectType;

	int   m_nContourCount;
	void* m_ppCntrDescArray[CD_MAX_CONTOUR_COUNT];

	//检查结果相关,不保存
	int      m_nDefectCount;  //缺陷点数量
	RvPoint* m_pDefectArray;  //缺陷点位置
	int      m_nCheckedCount;  //检测过的轮廓数
	BOOL     m_bDefectDetected;
	 

	//CRITICAL_SECTION m_cs;

};

