#pragma once

#include <cali\MatchCal.h>

#include "PatMat.h" 


#define FM_LEVEL_1     1
#define FM_LEVEL_2     (1<<1)
#define FM_LEVEL_3     (1<<2)

#define FM_DEFAULT_TYPE  0


//第3级特征
#define FM_L3_ORB    1
#define FM_L3_FPR    (1<<1)

//第2级特征
#define FM_L2_DEF    (1<<8)

//第1级特征
#define FM_L1_DEF    (1<<16)

/////////////////////已经学习////////////////////////////////////////
#define FM_MAX_FEATRUE_LEVELS    3

typedef struct __fm_minutia_
{ 
	BOOL   bEnable; //保留，该参数未来用于其它参数
	int    type;     //特征类型类型	
	int    mipLevel; //学习时的mip级，在识别时进行验证。
	HANDLE hImg;   //原图,使用原图，可以生成不同类型的特征
	void*  pFd;    //特征数据,该特征不保存，每次使用时，根据原图动态生成
}FM_MINUTIA;

//feature id
#define FV_FID_LEN   31

typedef struct __fm_triple_
{  
	UINT        id;
	TCHAR        name[FV_FID_LEN+1];
	FM_MINUTIA  m[FM_MAX_FEATRUE_LEVELS];
}FM_TRIPLE;

////////////////////////////学习前//////////////////////////////////////////
//默认具体特征参数为了兼容，没有实际意义
typedef struct __fm_default_specific_paras
{
	TCHAR data[12*4];//总共12个参数，每个参数总用内存4字节
}FM_DEFAULT_SPECIFIC_PARAS;


//ORB特征： 解释见:opencv2.4.8
typedef struct __fm_orb_paras
{
	int   sampleCount;   //采集数量
	int   minCount ;    //最少特征数
	float innerCoeff ;   //内部可靠点的距离系数
}FM_ORB_PARAS;

typedef struct __fm_feature_paras
{
	int   subtype;   //0为默认类型，该参数与具体特征的参数有段
	int   mipLevel;  //金字塔级
	float minScore ; //最小分数
	BOOL  bEnabled;
	union{
	    FM_DEFAULT_SPECIFIC_PARAS def;
		FM_ORB_PARAS              orb;
	};
}FM_FEATURE_PARAS;




class PATMAT_API CFeatureMatch :	public CMatchCal
{
public:
	CFeatureMatch(void);
	virtual ~CFeatureMatch(void);

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


	virtual void Reset();

	BOOL  Create(/*CDelegate* pDelegate ,*/ const TCHAR* strName  , UINT id =-1 , int style =RV_UC_DEFAULT_STYLE  ) ;

	virtual BOOL    Learn(const RvImage image=NULL, int* pErrCode = NULL){ return LearnNew( image, -1,  NULL,pErrCode); };  
	virtual int     Recognize(const RvImage image=NULL, int* pErrCode = NULL);
	//BOOL            Learn(const RvImage image, const TCHAR* strId , int* pErrCode);	

	BOOL  LearnNew(  const RvImage image, UINT id, const TCHAR* strFeatureName ,  int* pErrCode);

	int  GetLearnedFeatureCount();
	FM_TRIPLE* GetLearnedFeatureAt(int index);
	void RemoveFeatureAt(int index);
	void RemoveFeature(const TCHAR* strName);
	void RemoveFeature(UINT id);


	void RemoveAllFeatures();

	BOOL IsResultValid(){ return m_bValidResult; };
	const TCHAR* GetFeatureName(){ return m_strFeatureName; };
	UINT   GetFeatureId() { return m_nId; };


public:
	//这些参数控制学习和识别
	FM_FEATURE_PARAS m_featureParasL1 ;
	FM_FEATURE_PARAS m_featureParasL2 ;
	FM_FEATURE_PARAS m_featureParasL3 ;
		  
	int        m_nFilterType;

public:
	void DumpPatterns(const TCHAR* strFilePath, int level);
	virtual RV_HANDLE DrawPatternInstances(HGDC dc, RV_HANDLE hStroke);

protected:

	BOOL UpdateFeatureDescriptors();

	void  CloneFeatureDescriptors(  RvSequence src, RvSequence dst);
	 
	BOOL  ReadFeatureDescriptors(HANDLE hFile, RvSequence seq);
	BOOL  WriteFeatureDescriptors(HANDLE hFile, RvSequence seq);
	 

	int CheckPatternSize(RvImage image,  int mipLevel, int maxsize, BOOL bCheckMax);

	RvImage*  GenSceneMips(const RvImage image);
	void RelScenceMips( RvImage* pImageArray, int  nImageCount );
	int DoFeatureMatch(RvImage* pSceneMip, int nImageCount  );

    RvSequence m_seqSamples;
	BOOL       m_bValidResult;
	CUtString  m_strFeatureName;
	UINT       m_nId;
	RvPoint    m_vtx[4]; 
};

