#pragma once

#include "robbase.h"
#include "device.h"
 

#define CSS_MAX_FULL_CMD_LEN   1024

#define CSC_MAX_CMD_MSG_LEN    31   
#define CSC_MAX_CMD_NAME_LEN   15   
#define CSC_MAX_DATA_LEN        64   

#define CSC_MAX_DATA_NAME_LEN  15   


#define CSC_READ   1
#define CSC_WRITE  (1<<1)


//标志
#define CP_FLAG_WANT_RETURN          1     //for类
#define CP_FLAG_FEED_LINE           (1<<1) //for类
#define CP_FLAG_SHARP_REQ_ONLY      (1<<2)   //for命令: 协议只有#符号,例如:    #sight1.blob1.cnt:123 ,后面至少一个空格
#define CP_FLAG_ASTERISK_REQ_ONLY   (1<<3)   //for命令: 协议只有*符号, 例如:   *sight1.blob1.cnt 
#define CP_FLAG_HAS_QUOTE           (1<<4)   //for命令: 文本加引号, 当是文本数据时，加引号
#define CP_FLAG_NO_ACK              (1<<5)   //for命令: 写指令不要回复
#define CP_FLAG_SHARP_ACK_ONLY      (1<<6)   //for命令:  
#define CP_FLAG_ASTERISK_ACK_ONLY   (1<<7)   //for命令:  
#define CP_FLAG_IGNORE_DATATYPE     (1<<8)   //for命令: 
#define CP_FLAG_IGNORE_ADDRESS      (1<<9)  //for命令: 




typedef struct __cust_scomm_cmd_
{
	int     id;
	int     mode; // 读，写
	int     minAddr;//最小地址
	int     maxAddr;//最大地址
	char    strName[CSC_MAX_CMD_NAME_LEN+1];
	int     dataType;
	int     decAccu;
	int     flags;             //高16位为相应消息长度
	//BOOL    bNoAckForWrite;  //写指令不需要回复
	char    strReq[CSC_MAX_CMD_MSG_LEN+1];
	char    strAck[CSC_MAX_CMD_MSG_LEN+1];
}CUST_SCOMM_CMD;


typedef struct __cust_scomm_data_
{
	 char name[CSC_MAX_DATA_NAME_LEN +1];
	 int  dataType;
	 union {
		char   c;
		unsigned char bt;
		short  sn;
	    int    n;
		double ft;
		char*  text;
	 }value;
}CUST_SCOMM_DATA;



 
class ROBBASE_API CCustProtocol: public CDevice
{
public:
	CCustProtocol(void);
	virtual ~CCustProtocol(void);

	int GetCmdCount(int mode);
	CUST_SCOMM_CMD* GetCmdAt(int mode, int index);
	CUST_SCOMM_CMD* GetCmd(int id);

	//命令
	void Append(CUST_SCOMM_CMD* pCmd);
	void DeleteAt(int mode, int index);
	void Delete(int id);
	void ReleaseCmd();


	//用户数据
	void ReleaseUserData();
	BOOL AddUserData(const char* strName, int dataType, int val);
	BOOL AddUserData(const char* strName, double val);
	BOOL AddUserData(const char* strName, const char* text);
	BOOL DeleteUserData(const char* strName);
	BOOL DeleteUserData(int index);
	BOOL UpdateUserData(const char* strName, int val);
	BOOL UpdateUserData(const char* strName, double val);
	BOOL UpdateUserData(const char* strName, const char* text);

	int  GetUserDataCount();
	CUST_SCOMM_DATA* GetUserDataAt(int index);


	BOOL IsDuplicated(int id);
	BOOL IsReadable(int id, CUST_SCOMM_CMD** ppCmd);
	BOOL IsWritable(int id, CUST_SCOMM_CMD** ppCmd);

 
	BOOL Encode(CUST_SCOMM_CMD* pCmd, int addr, double data, char* strCmd, int* pCmdSize, char* strAck, int* pAckSize);
	
	 
	//BOOL Encode(CUST_SCOMM_CMD* pCmd, int addr, double data, char* strCmd, int* pSize);

	//BOOL Decode(char* strCmd, int nCmdSize, int addr, BOOL bCheckData = TRUE, double* pData=FALSE);

	

	
	BOOL SendCmd(CUST_SCOMM_CMD* pCmd, int address, double& data , CUtString& strError);
	BOOL SendCmdEx(CUST_SCOMM_CMD* pCmd, int address, double* pData, char* ackBuff , int& buffSize,  CUtString& strError);
	BOOL SendCmd2(int cmdId, int address, double& data , CUtString& strError);


	//文件存储
	BOOL Save(const char* strFileName);
	BOOL Read(const char* strFileName);

public:

	void SetFlags(int flags);
	int  GetFlags();
	void AddFlags(int flags) ;
	void DelFlags(int flags)  ;
	 
	BOOL CheckFlags(int flags) { return ((m_flags &  flags )  ==  flags ); };
	 
	void AddFlags(CUST_SCOMM_CMD* pCmd,int flags) ;
	void DelFlags(CUST_SCOMM_CMD* pCmd, int flags) ;
	BOOL  CheckFlags(CUST_SCOMM_CMD* pCmd, int flags) ;
	int   GetAckLen(CUST_SCOMM_CMD* pCmd) ;
	void  SetAckLen(CUST_SCOMM_CMD* pCmd, int size) ;

	//BOOL m_bAddReturnChar;  //回车符
	//BOOL m_bAddNewLineChar; //换行符 

public:
	int  m_nDelay ;//
private:
	//只发不接收
	BOOL Send(char* strCmd, int nCmdSize, char* strRecv, int* pRecvSize); 

	//接受固定长度
	BOOL Send2(char* strCmd, int nCmdSize, char* strRecv, int* pRecvSize); 

	//接受以指定字符结尾的
	BOOL Send3(char* strCmd, int nCmdSize, char* strRecv, int* pRecvSize, char* pTerminater); 

	//按照延迟接受数据
	BOOL Send4(char* strCmd, int nCmdSize, char* strRecv, int* pRecvSize, int timeout); 
	

	BOOL CheckRecv( char* strAck, int nAckSize,char* strRecv, int nRecvSize,  double& data, char* pRetBuff, int& nRetSize);

	RvSequence m_lstScommCmd;
	RvSequence m_lstUserData;

	int  m_flags;
	
	//CArray<CUST_SCOMM_CMD*, CUST_SCOMM_CMD* > m_arrScommCmd;
public:
	int AddMiscChar(char* strBuff, int buffSize);
	BOOL RemoveMiscChar(char* strBuff, int& buffSize);
};

