#if !defined(__RV_PAT_MAT_H_INCLUDED_)
#define      __RV_PAT_MAT_H_INCLUDED_


#include <cali\CaliX.h>
#include <cali\MatchCal.h>
 
#include <rvb\pmat.h>
//#include <cali\areacal.h>
#include <rvb\rvtypes.h>

#include <rvb\cvfs.h>
//#include <rvb\img.h>
//#include <rvb\pprs.h>
//#include <sst\diskhelper.h>
 
#ifdef PATMAT_EXPORTS
#define PATMAT_API __declspec(dllexport)
#else
#define PATMAT_API __declspec(dllimport)
#endif


#define  RV_UC_PIXEL_MATCH          (RV_UC_PATTERN_MATCH + 3)
#define  RV_UC_DUAL_DETECT          (RV_UC_PATTERN_MATCH + 4)
#define  RV_UC_PATTERN_LOCATER      (RV_UC_PATTERN_MATCH + 5)
#define  RV_UC_MULTI_DETECT         (RV_UC_PATTERN_MATCH + 6)
#define  RV_UC_FEATURE_DETECT       (RV_UC_PATTERN_MATCH + 7)
#define  RV_UC_PIXEL_MATCH_E1       (RV_UC_PATTERN_MATCH + 8)

#define  RV_UC_SHAPE_MATCH          (RV_UC_PATTERN_MATCH + 10) //轮廓匹配opencv
#define  RV_UC_EDGE_FIT             (RV_UC_PATTERN_MATCH + 11) //边缘点india,但继承pixelmatch框架
#define  RV_UC_COMPONENT_LOCATER    (RV_UC_PATTERN_MATCH + 12) //

 

#define MAX_MIP_LEVEL       10
 
#define PM_MIN_SCALE        (0.5f) //缩放，最小一般
#define PM_MAX_SCALE        (2.f)  //缩放，最大一倍

#define MIN_SUB_TRANS_RESO   (1/40.f)  //1/40 subpixel
#define MIN_SUB_ROTATE_RESO  (1/50.f)  //1/50 degree
#define MAX_ROTATE_RESO      (180/8.f)  




//单边长度
#define PM_MAX_PATT_IMG_SIZE    1300
#define PM_MIN_PATT_IMG_SIZE    22   

#define PM_MIN_DEGREE_RESO      0.001f


typedef struct __pme1_edge_{
     int        size;
	 RvPoint_f* pVertex;
}PME1_EDGE;


typedef struct __pm_pattern
{
	float  scaleX;
	float  scaleY;

	int width;
	int height;
	  
	//旋转的实例（如果不旋转，仅一个实例）
	int       nFineSize;  //fine
	RvMask*   maskArray;
	RvImage*  imageArray;
	
	//糙实例（如果不旋转，仅一个实例）
	int       nCoarseSize;
	RvMask*   coarseMaskArray;
	RvImage*  coarseImageArray;

}PM_PATTERN;

typedef struct __rv_edge_fit_result_
{
	//上面部分需与MpResult一致
	double    x, y;  //坐标
	double    score; //分数
	//////////////////
	int       edgeIndex;
	int       mipLevel;
}RvEdgeFitResult;

typedef struct __pm_spd_edge
{
	float     scaleX;
	float     scaleY;
	RvPoint_f center;
	
	int           nFineSize;   //旋转样本
	RvSpkEdges**  ppSdgFineEdgeArr; //

	int           nCoarseSize;   //旋转样本
	RvSpkEdges**  ppCoarseEdgeArr;  //

}PM_SPD_EDGE;

#define ECD_LEVEL  3  //原，精，糙


typedef struct __rv_ecd_result_
{
	//上面部分需与MpResult一致
	float      x, y;  //坐标
	float    score; //分数
	//float    angle; //
	//////////////////
	int       pattIndex;
	int       angleIndex;
	//int       mipLevel;
}RvEcdResult;

  
typedef struct __pm_ecd_x_
{
	float     scaleX, scaleY; //缩放
	float     tiltX, tiltY; //倾斜（变形）  
	int       polar;        //极性
	   
	//带旋转的实例
	//如果不旋转，为第1个实例
	//不旋转时为1
	int  nRotCnt ;//旋转实例数量。
//	int       nCoarseSize; 
	iRvEcdCntrE1**   ppCoarseArr;  //糙模板

//	int       nFineSize;
	iRvEcdCntrE1**   ppFineArr;    //精模板
	 
//	int       nRawSize;
	iRvEcdCntrE1**   ppRawArr;    //原始模板
	
}PM_ECDX;

//内存页面大小
#define DEF_MEM_PAGE_SIZE   3000000



#define PM_SCALED_PATT_CNT(maxs, mins, reso)   RV_MAX(int (((maxs) - (mins))/(RV_MAX(reso, MIN_SCALE_RESO))), 1)


typedef struct __pm_lms_params_{
   int    nnRadius;
   BOOL   bSwapXY;
   
   float tx, ty;
   float offsetReso, offsetExtent;
   float angleReso, angleExtent;

   int _upscale; //向上比例,保留
}PM_LMS_PARAMS_;

//BOOL  calc_lms_normal(iRvEcdCntrE1* pCurEcd, const RvImage image, PM_LMS_PARAMS_& lp , RvPoint_f*  pOffsetPos, double* pScore);

//double calc_total_distance(iRvEcdCntrE1* pEcd,  float x, float y, RvImage  image, int nnRadius, double& distance);
//double calc_total_distance_e1(iRvEcdCntrE1* pEcd,  float x, float y,    double angle, RvImage  image, int nnRadius, double& distance, BOOL bSwapXY );
//BOOL  search_lms_offset(iRvEcdCntrE1* pCurEcd, const RvImage image, PM_LMS_PARAMS_& lp,  double angle, int direct, int axis, double& curDist,  float& offset);
//BOOL  search_lms_offset(iRvEcdCntrE1* pCurEcd, const RvImage image, float tx, float ty, double angle, int direct, int axis, float reso, float extent, int nnRadius,  double& curDist,  float& offset, BOOL bSwapXY);
//BOOL  calc_lms_rotated(iRvEcdCntrE1* pCurEcd, const RvImage image, float tx, float ty,  double angle, float angleReso, float angleExtent, float offsetReso, float offsetExtent, int nnRadius, RvPoint_f& offsetPos, double& angleDiff);
//BOOL  calc_lms_rotated(iRvEcdCntrE1* pCurEcd, const RvImage image,  PM_LMS_PARAMS_& lp, double angle,  RvPoint_f* pOffsetPos, double* pAngleDiff, double* pScore);


//BOOL  write_single_ecd(HANDLE device, iRvEcdCntrE1* pEcd);
//BOOL  write_ecd_contour(HANDLE device, iRvEcdCntr* pEc);
//iRvEcdCntrE1*  read_single_ecd(HANDLE device ) ;
//iRvEcdCntr*  read_ecd_contour(HANDLE device);


//inline int GetMipUpScale(int level)
//{
//    int n=1;
//
//	for (int i=0; i<level; i++){
//	   n *= 2;
//	}
//
//	return n;
//}
//
//inline float GetMipDownScale(int level)
//{
//    int n=1;
//
//	for (int i=0; i<level; i++){
//	   n *= 2;
//	}
//
//	return (1.f/n);
//}

#define CIE_ANGLE_RESO  0.0001f


RvImage CloneImageEx(const  RvImage image, float scaleX, float scaleY, float angle, BOOL bInterpolate) ;

// void exclude_edge_on_ecd_by_mask(iRvEcdCntrE1* pEcd, const RvMask mask, int distance , BOOL bSwapXY);

//匹配结果相关
void clear_result_items(PM_MATCH_RESULT* pArr, int& cnt);
int add_result_items(PM_PATTERN* pPatt, int pattIdx, int angIdx, int mipLevel, MpResult* pSrcArr, int nSrcCnt, PM_MATCH_RESULT* pDstArr, int nDstCnt, int maxDstCnt);
int add_result_items(PM_SPD_EDGE* pPatt, int pattIdx, int angIdx, int mipLevel, MpResult* pSrcArr, int nSrcCnt, PM_MATCH_RESULT* pDstArr, int nDstCnt, int maxDstCnt);
int add_result_items(PM_MATCH_RESULT* pSrcArr, int nSrcCnt, PM_MATCH_RESULT* pDstArr, int nDstCnt, int maxDstCnt);


void TransformImage(RvImage image, float scaleX, float scaleY, float angle, BOOL bInterpolate) ;
RV_HANDLE draw_ecd_mark(HGDC dc,     iRvEcdCntrE1* pEcd, int cx,   int cy,  int dx, int dy,  float scale, float angle, BOOL  bSwapXY,RV_HANDLE hStroke );
 

int check_angle(int w, int h, double  start, double  end,   double& reso);

//根据最小比例和最大找到索引,支持模板缩放时使用
int check_scale(float minscale, float maxscale,  int&  low, int& upper );
double get_scale_by_index(int index);

//PCL库的pcd格式的头数据,版本0.7
//datetype: 0 -byte, 1- short, 2-int, 3- float, 4-double
//width ,height与标准定义不一样，表示图像宽度和高度
BOOL  write_pcd_header(HANDLE hFile,  int width, int height, int datatype, size_t datasize,BOOL bNormalPcd );
BOOL  write_ipcd_line(HANDLE hFile, const TCHAR* strData);


#endif //__RV_PAT_MAT_H_INCLUDED_