// DiskUtility.h: interface for the CDiskUtility class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(__RV_SMARTDISK_H_INCLUDED_)
#define __RV_SMARTDISK_H_INCLUDED_

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


//#ifdef SMARTDISK_EXPORTS
//#define SMARTDISK_API __declspec(dllexport)
//#else
//#define SMARTDISK_API __declspec(dllimport)
//#endif
#include "SmartDisk.h"

#include <rvb\rvtypes.h>
#include <rvb\imio.h>


#define DH_VERSION(m, s)       (((m)<<16) | (s))
#define DH_GET_MAIN(v)         (((v) >>16) & 0xFFFF) 
#define DH_GET_SUB(v)          ((v) & 0xFFFF) 

//检查是大于或等于指定的版本
#define DH_IS_EARLIER_VERSION(m, s, cur)  (DH_VERSION((m),(s)) < (cur))

//#define TAG_DEFECT           0x1000000
//#define TAG_SIGHT            0x2000000
// 


//#define MAX_TASK_NAME_LEN    63
//#define MAX_MODEL_LEN        63
//
//
//typedef struct __rv_code_file_header_{
//	 TCHAR  tag[4];
//     int   version;
//	 TCHAR  taskName[MAX_TASK_NAME_LEN+1];
//	 TCHAR  machineModel[MAX_MODEL_LEN+1];
//	 int   sightCount;      
//}RV_CF_HEADER;

//支持版本更新的接口
#define RV_DH_BEGIN_WRITE_UC_E1(hfile, tag, ver, curpos)     if (!CDiskHelper::BEGIN_OBJ_OUT_E1(hfile, tag, ver, &curpos)) return FALSE; 
#define RV_DH_END_WRITE_UC_E1(hfile, tag, prevpos)       if (!CDiskHelper::END_OBJ_OUT_E1(hfile, tag, prevpos)) return FALSE; 

#define RV_DH_BEGIN_READ_UC_E1(hfile, tag, ver, objsze)        if (!CDiskHelper::BEGIN_OBJ_IN_E1(hfile, tag , &ver, &objsze)) return FALSE; 
#define RV_DH_END_READ_UC_E1(hfile, tag)          if (!CDiskHelper::END_OBJ_IN_E1(hfile, tag)) return FALSE; 
///////////////////////////

#define RV_DH_BEGIN_WRITE_UC(hfile, tag)     if (!CDiskHelper::BEGIN_OBJ_OUT(hfile, tag)) return FALSE; 
#define RV_DH_END_WRITE_UC(hfile, tag)       if (!CDiskHelper::END_OBJ_OUT(hfile, tag)) return FALSE; 


#define RV_DH_WRITE_VAR(hfile, v)         if (!CDiskHelper::Write(hfile, v)) return FALSE;

#define RV_DH_WRITE_TEXT(hfile, text )    if (!CDiskHelper::Write(hfile, (const TCHAR*)text)) return FALSE;
#define RV_DH_WRITE_OBJ(hfile, obj, size) if (!CDiskHelper::Write(hfile, (void*)(obj), size)) return FALSE;

#define RV_DH_ENCODE_IMAGE(hfile, img, fmt) if (!CDiskHelper::EncodeImage(hfile, img , fmt )) return FALSE;



#define RV_DH_BEGIN_READ_UC(hfile, tag)        if (!CDiskHelper::BEGIN_OBJ_IN(hfile, tag )) return FALSE; 
#define RV_DH_END_READ_UC(hfile, tag)          if (!CDiskHelper::END_OBJ_IN(hfile, tag)) return FALSE; 

#define RV_DH_READ_VAR(hfile, v)                if (!CDiskHelper::Read(hfile, v)) return FALSE;
#define RV_DH_READ_TEXT(hfile, text, max_size ) if (!CDiskHelper::Read(hfile, (TCHAR*)text, (int)max_size)) return FALSE;
#define RV_DH_READ_OBJ(hfile, obj, size)        if (!CDiskHelper::Read(hfile, (void*)(obj), size)) return FALSE;

#define RV_DH_DECODE_IMAGE(hfile, img)           if (!CDiskHelper::DecodeImage(hfile, img)) return FALSE;

/*****************************************************************
*
*新版本更新的内容
*
* 1  增加一个static BOOL Read(HANDLE hFile,  void* pData, int size);  //读自定义类型数据
* 2  增加一个static  BOOL Write (HANDLE hFile,void* pData, size_t size); //写自定义类型数据
* 3  增加一个static  BOOL Write (HANDLE hFile, const TCHAR* pData, int size); //写字符串类型数据（可以不带NULL）
*
*****************************************************************/

class SMARTDISK_API CDiskHelper  
{
public:
	enum SEEK_TYPE{
		ST_BEGIN,
		ST_CURRENT,
		ST_END,
	};

	CDiskHelper();
	virtual ~CDiskHelper();

public:

	static HANDLE CreateFile(const TCHAR* strFilePath, BOOL bInMomery = FALSE, BOOL bOverWrite=FALSE, int* pErrCode=NULL );
 	static void   DestroyFile(HANDLE hFile);

	static HANDLE GetEntrance(HANDLE hFile);

	//static HANDLE CreateFromHandle(HANDLE  hFile );

	static HANDLE OpenFile(const TCHAR* strFilePath, int* pErrCode=NULL );

	//忽略文件头信息检测
	//static HANDLE OpenFileE1(const TCHAR* strFilePath, int* pErrCode=NULL );
	//仅支持磁盘文件
	//v1.1
	static HANDLE OpenFile(const TCHAR* strFilePath, BOOL  bNocheck, int* pErrCode=NULL );
	//endof v1.1

	static HANDLE OpenFileInMemory(void* pFileData, UINT nSize, int* pErrCode=NULL);
 	static void   CloseFile(HANDLE hFile);

	static BOOL   Seek(HANDLE hFile, CDiskHelper::SEEK_TYPE type, int offset);
	static size_t   GetFileSize(HANDLE hFile);
	static size_t   GetCursorPos(HANDLE hFile);

	//v1.1
	static BOOL   JumpFileHeader(HANDLE hFile/*, const char* strTag = NULL*/);
	static int   GetFileVersion(HANDLE hFile);
	static const TCHAR*   GetFileTag(HANDLE hFile);
	//end of v1.1

	static BOOL  LoadBitmap(RvImage image, const TCHAR *strFileName );
    static BOOL  SaveBitmap(const RvImage image, const TCHAR *strFileName );
	
	//mask and blob are both saved as bitmap
    static BOOL  SaveMask(const RvMask mask, const TCHAR *strFileName);
    static BOOL  SaveBlob(const RvBlob blob, const TCHAR *strFileName);

 
public:
	//v1.1
	//文件内部头信息
	//写
	static BOOL BEGIN_FILE_OUT(HANDLE hFile, int version, const TCHAR* strTag);
	static BOOL BEGIN_FILE_OUT(HANDLE hFile );
	static BOOL END_FILE_OUT(HANDLE hFile);

	//读
	static BOOL BEGIN_FILE_IN(HANDLE hFile, int* pVersion , TCHAR* strFileTag  , int tagSize );
	static BOOL BEGIN_FILE_IN(HANDLE hFile );
	static BOOL END_FILE_IN(HANDLE hFile);
  
	//对象
	static BOOL BEGIN_OBJ_OUT (HANDLE hFile, DWORD tag);
	static BOOL END_OBJ_OUT   (HANDLE hFile, DWORD tag);
	//end of v1.1

	//获取当前游标位置的TAG标记，同时保证游标位置不变。
	static BOOL PICK_OBJ_TAG(HANDLE hFile,DWORD* pTag );
	
	static BOOL  BEGIN_OBJ_IN (HANDLE hFile,  DWORD tag);
	static BOOL  END_OBJ_IN    (HANDLE hFile, DWORD tag);

	//E1 支持版本和数据块大小
	static BOOL BEGIN_OBJ_OUT_E1 (HANDLE hFile, DWORD tag, int version,  UINT* pCurPos);
	static BOOL END_OBJ_OUT_E1   (HANDLE hFile, DWORD tag, UINT nPrevPos);

	static BOOL  BEGIN_OBJ_IN_E1 (HANDLE hFile,  DWORD tag, int* pVersion,  UINT* pObjSize);
	static BOOL  END_OBJ_IN_E1   (HANDLE hFile,  DWORD tag);

	//获取当前游标位置的TAG标记，同时保证游标位置不变。
	static BOOL PICK_OBJ_TAG_E1(HANDLE hFile, DWORD* pTag, int* pVersion,  UINT* pObjSize);

public:
	
	//图像格式支持RVB平台中imio模块的格式
	//注意: jpeg格式的图象只能支持24或8位图象（即RIT_RGB或RIT_GRAY）
	//     不同的格式支持的位数可能不同。
	//     RV_IMF_PNG格式支持32位。
	static BOOL  EncodeImage(HANDLE hFile, const RvImage image, int nFormat =RV_IMF_PNG);
    
	//image不能为空.否则产生断言错误.
	static BOOL  DecodeImage(HANDLE hFile,  RvImage image );

	//返回NULL,表示读图像数据失败
	static RvImage  DecodeImage(HANDLE hFile );

	static BOOL  EncodeMask(HANDLE hFile, const RvMask mask);
	//如果bRestrictSize，表示不能修改输入mask的大小，否则可以修改
	static BOOL  DecodeMask(HANDLE hFile, RvMask mask, BOOL bRestrictSize = TRUE);

	//保存blob，然后读取的时候，contour编码可能会发生变形
	//即不能保证所有编码的blob经过保存和读取操作后，保持数据不变
	static BOOL  EncodeBlob(HANDLE hFile, const RvBlob obj);
	static BOOL  DecodeBlob(HANDLE hFile, RvBlob obj);

	//写字符串
	static  BOOL Write (HANDLE hFile, bool val);

	static  BOOL Write (HANDLE hFile, const TCHAR* strVal);

	static  BOOL Write (HANDLE hFile, char val);
	static  BOOL Write (HANDLE hFile, unsigned char val);

	static  BOOL Write (HANDLE hFile, short val);
	static  BOOL Write (HANDLE hFile, unsigned short val);

	static  BOOL Write (HANDLE hFile, int val);
	static  BOOL Write (HANDLE hFile, unsigned int val);
	 
	static  BOOL Write (HANDLE hFile, long val);
	static  BOOL Write (HANDLE hFile, unsigned long val);
	 
	//static  BOOL Write (HANDLE hFile, DWORD val);
	static  BOOL Write (HANDLE hFile, float val);
	static  BOOL Write (HANDLE hFile, double val);
	static  BOOL Write (HANDLE hFile, RvPoint val);
	static  BOOL Write (HANDLE hFile, RvPoint_f val);
	static  BOOL Write (HANDLE hFile, RvPoint_f64 val);
	 
	static  BOOL Write (HANDLE hFile, __int64 val);
	static  BOOL Write (HANDLE hFile, unsigned __int64 val);

	static  BOOL Write (HANDLE hFile,void* pData, size_t size);
	
	//read out
	static  BOOL Read (HANDLE hFile, bool* pV);
	
	static BOOL Read(HANDLE hFile,  char* pV);
	static BOOL Read(HANDLE hFile,  unsigned char* pV);

	static BOOL Read(HANDLE hFile,  short* pV);
	static BOOL Read(HANDLE hFile,  unsigned short* pV);

	static BOOL Read(HANDLE hFile,  int*  pV);
	static BOOL Read(HANDLE hFile,  unsigned int*  pV);
	 
	
	static  BOOL Read (HANDLE hFile, long* pV);
	static  BOOL Read (HANDLE hFile, unsigned long* pV);

	static BOOL Read(HANDLE hFile,  __int64* pV);
	static BOOL Read(HANDLE hFile,  unsigned __int64* pV);
	 
	static BOOL Read(HANDLE hFile,  TCHAR* pV, int size);  //读取字符串
	static BOOL Read(HANDLE hFile,  float* pV);
	static BOOL Read(HANDLE hFile,  double* pV);
	//static BOOL Read(HANDLE hFile,  UINT* pV);
	//static BOOL Read(HANDLE hFile,  DWORD* pV);
	 
	static BOOL Read(HANDLE hFile,  RvPoint*  pV);
	static BOOL Read(HANDLE hFile,  RvPoint_f*  pV);
	static BOOL Read(HANDLE hFile,  RvPoint_f64*  pV);
	 

	static BOOL Read(HANDLE hFile,  void* pData, size_t size);

	static BOOL ReadE1(HANDLE hFile,  void* pData, size_t& size);

	static int GetErrorCode() ; //目前错误信息还没完全开放出来
	
protected:
    static int m_nLastError;

};



#endif // !defined(__RV_SMARTDISK_H_INCLUDED_)
