#if !defined(__RV_EASY_OCR_H_INCLUDED_)
#define      __RV_EASY_OCR_H_INCLUDED_

#include "acute.h"

#define EO_MAX_TEXT_LINES     127

typedef struct __eo_char_rect_
{
    int        lineNum;  
	RvImage    imChar;
	RvRect     charRect;  //在整图中的位置
}EO_CHAR_RECT;


 typedef struct _eo_text_rows_
 {
	 int        index;  //行号 
	 RvPoint_f  center;
	 float      angle;  //角度用于绘制区域的时候用
	 float      width;
	 float      height;
	 RvImage    imBin;    //二值化以后的图像 ,已经矫正好，尺寸与原图相同
	 RvSequence lstCharRect; 
 }EO_TEXT_ROWS;

typedef struct __eo_candi_blob_
{
	int      charIdx;//所属TCHAR rect的index
	float    width;  
	float    height;
	RvBlob   blob;   
}EO_CANDI_BLOB;
 

 //
 //typedef struct _eo_clust_
 //{
	//
	// int    left,top;
	// int    width, height;
	// //int        lineCnt;  //行数量  
	// //RvPoint_f  center;
	// //float      angle;
	// //float      width;
	// //float      height;
	// //RvImage    imBin;    //二值化以后的图像

	// //int        offx, offy; //矫正图像的位置 （左上角）
	// //RvImage    imUntilt;    //矫正后的局部图像,   没有多少用 

	//// RvSequence _lstRawBox; //原始块:EO_CANDI， 保留
	// RvSequence lstCharRect;  //分割的结果:EO_CHAR_RECT
 //}EO_CLUST;

 typedef struct __eo_result
{
	int       nClass;      //分类,外部定义
	int       lineNum;     //行号,从0开始
	int       colIdx;     //字符位置，保留
	short     charCode;  
	RvRect    charBox;     //字符位置
	float     score;                  
}EO_RESULT;

 //build stage
#define EO_BS_PROCESS_ONLY       0
#define EO_BS_DETECT_ROWS        1
#define EO_BS_SEG_CHARS          2   



class ACUTE_OCR_API CEasyOcr :	public CAreaCal
{
public:
	CEasyOcr(void);
	virtual ~CEasyOcr(void);
	 
	//文本颜色
	enum
	{
		EO_WHITE_ON_BLACK =0,
		EO_BLACK_ON_WHITE ,
	};

	//垂直印刷
	enum
	{
		EO_VP_NONE = 0,
		EO_VP_B2T ,    //从底到上
		EO_VP_T2B ,    //从上到下
	};

	//display style
	enum
	{
		EO_DEFAULT =RS_DEFAULT ,//默认，仅显示ROI
		EO_PREVIEW  ,   //预览
		EO_ALLCHARS,  //显示所有符号
		EO_SELCHAR,   //选择的BLOB  
	};

	enum{
	    EO_DIGITS  = 1,          //数字
		EO_LETTERS = 1<<1,       //小写字母
		EO_CAPITALS = 1<<2,      //大小字母
		EO_INTERPUNCTION = 1<<3, //标点符号
		EO_CHINESE = 1<<4,       //中文,保留
	};
	 
	virtual BOOL Serialize(HANDLE device, BOOL bIn ) ;
	virtual CUCObj* Clone(  CUCObj *twin) ;

	
	virtual void  Show(CDelegate* pDelegate, int mode, BOOL bForce) ;
	virtual void  SetDisplayStyle(int style);
 
	virtual void Preprocess(RvImage image, int rotateType, BOOL bLocateOnly );

	//获取分割的字符块
	// 这个函数废弃
	//int        Build(const RvImage image, EO_TEXT_ROWS* pTextRow, EO_CLUST* pClust);
	//Build新接口
	//STAGE : EO_BS_PROCESS_ONLY
	int        Build(const RvImage image, int stage);

	
	 
	//EO_CLUST*     GetCandiClust(int index); //每行对应一个EO_CLUST
	EO_TEXT_ROWS* GetTextRowAt(int index);  //文字行信息
	int           GetTextRowCount();
	int GetCharBoxCount(int rowIndex) ;                       //每行分割后的字符数
	EO_CHAR_RECT* GetCharBoxAt(int rowIndex, int boxIndex) ;  //指定行的字符数据



	//最多支持4个字节的长度
	BOOL Learn(int rowIndex, int boxIndex, int nClass, short charCode) ;
	BOOL Learn(const RvImage image, int nClass, short charCode) ;

	int  Recognize(int nClass=-1, int* pErrCode=NULL );

	void Reset();

	//获取结果
	int    GetTotalChars(); //识别的总字符数量
	int    GetLineCount();

	int    GetCharCount(int row); //行的字符总数
	short  GetCharAt(int index) ;
	float  GetScoreAt(int index) ;
	int    GetClassAt(int index) ;

	short  GetCharAt(int row, int col) ;
	float  GetScoreAt(int row, int col) ;
	int    GetClassAt(int row, int col) ;

	EO_RESULT* GetResultAt(int index);
	EO_RESULT* GetResultAt(int row, int col);
	CUtString  GetResultText();  //获得结果文字
	

	//已学习的字符管理；
	int  GetPatternCount();
	void GetPatternAt(int index, int* pClass, short* pCharcode);

	//外部程序不要释放image
	const RvImage GetPatternAt(int index);

	//移除已经学习的模板
	void RemoveAllPatterns();
	void RemovePatternAt(int index);

	//外部程序不要释放image
	const RvImage GetBinary(){ return m_imBin; };

	 
	

	//该值在分割字符以后有效
	float GetMipScale(){ return m_nMipScale;} ;


public:
	int GetPatternWidth() {return m_nPatternWidth; };
	void SetPatternWidth(int width);

	int GetPatternHeight() {return m_nPatternHeight; };
	void SetPatternHeight(int height);

	//int  GetCurSel() { return m_nCurSelIndex;};
	//void SetCurSel(int index);

	//void DumpPatterns(int index, const TCHAR* strFilePath);
	
public:
	int m_nMinCharWidth, m_nMaxCharWidth ;    //最大字符宽度和最小字符宽度
	int m_nMinCharHeight, m_nMaxCharHeight ;  //最大字符高度和最小字符高度

	int m_nMinCharSpace, m_nMaxCharSpace;    //字符间隔	
	int m_nMinLineSpace, m_nMaxLineSpace;    //行间距 
	  
	int m_nMinStrokeThick, m_nMaxStrokeThick; //笔画粗细

	int  m_nCharColor;
	//在字符定位过程中，会发现字符倒立，因此，允许倒立情况发生
	int  m_nAllowFlip;  //RV_DIR_VERT so far

	BOOL m_bRemoveIntrusion;  //移除干扰物
	int  m_nMinIntrusionSize; //移除最小干扰物,面积大小

 
	int  m_nLineCount;     //行数
	int  m_nRotateType;  //垂直文字
		
	int m_nCharClass;

	//范围：0-1.
	float m_nMinScore;
 
protected:
	 
	float   m_nMipScale;//临时变量，缩小比例
	RvImage m_imBin;
	 
	//临时变量,分割后的blob和box
	//EO_CLUST*     m_pCandiClust;
	EO_TEXT_ROWS* m_pTextRowArr; 
	int           m_nRowsDetected; //总行数

	//临时变量,读取结果
	RvSequence m_lstResult;
	int        m_nResultLines;
	 
protected:

		//探测行
	int DetectTextRows(RvImage image, EO_TEXT_ROWS* pRowArray, int nRowSize);


	//获得初始blob， 根据m_nStrokeThick，CharWidth， CharHeight
	//筛选合适的blob，过时
	//BOOL SegmentRaw(RvImage imBin,  EO_TEXT_ROWS* pTextRow, EO_CLUST*  pClust );

	

	//原始blob后处理 ，过时
	//BOOL PostSegment(RvImage imBin,  EO_TEXT_ROWS* pTextRow, EO_CLUST*  pClust );

	//分割字符
	BOOL SegmentChar(RvImage imBin,  EO_TEXT_ROWS* pTextRow/*, EO_CLUST*  pClust*/ );

	
	float FindInPatternList(const RvImage image, int nClass, EO_RESULT* pResult);

	void ReleaseCandiClust(EO_TEXT_ROWS* pTextRow /*EO_CLUST*  pClust, int rowCount*/);
	void ReleaseAllCandis();
	//void ShowSelChar(BOOL bForce);
	//void ShowAllChars(BOOL bForce);

	//float CalcRms(void* pCharPatt0, void* pCharPatt1, UINT base);
	float  CalcSimilar(const RvImage scene, const RvImage patt);

	//void* GeneratePattern(const RvImage image, int nClass, short charCode );
	//void* GeneratePatternEx(const RvBlob blob );
	RvImage  GenerateNormalImage(EO_TEXT_ROWS* pTextRow,/*EO_CLUST* pClust,*/ int boxIndex);
	RvImage  GenerateNormalImage(const RvImage image);

	//RvImage  GenerateImage(EO_TEXT_ROWS* pTextRow,/*EO_CLUST* pClust, */const EO_CHAR_RECT* pCharBox);



	int  m_nPatternWidth, m_nPatternHeight;
	//学习的字符数据
	RvSequence m_lstCharDescript;


	
};



#endif