#pragma once
#include <vector>
#include <list>
#include <map>
#include <string>
#include <iostream>

#include "SecsPortExport.h"

struct RcResult;

// SECS基础，与DLL对接

class CSecsBase
{
public:
	CSecsBase();
	~CSecsBase();

public:

	// 开始连接      
	RcResult Start(std::string pServerAddr = "local", int nPort = 7000);
	void SecsEnable(bool bEnable);		// 启用/禁用 SECS功能

	// 终止连接
	void Abort();
		
	// 通信控制     
	RcResult CommEnable();					// 启用通信  
	RcResult CommDisable();					// 关闭通信
	RcResult CommIsEnable(bool& bEnable);	// 通讯是否开启
	RcResult GetCommState(int& nState);		// 获取通信状态

	// 设置控制状态
	RcResult SetControlMode(int state);
	RcResult SetControlModeForce(int state);
	RcResult GetControlState(int& state);		// 获取控制状态	
	RcResult ActiveRequestOnline();	// 主动请求在线，在线状态通过GetControlState设置

	// 设置超时
	RcResult SetTn(std::string Tn, int nTimeout);	
		
	// 设置参数
	RcResult SetParament(std::string type, std::string param);				// 单个	
	RcResult SetParament(const char* type[], const char* param[], int nCount);	// 多个

	// 处理指定返回的消息
 	RcResult WheneverAdd(const char* receiveMailbox, WhenProc* whenmsgProc, void* clientData = NULL);	// // 添加处理
	void WheneverRemove(const char* receiveMailbox);		// 移除处理

	// 答复同步消息 
	// when需要同步的消息
	void Reply(std::string receiveMailbox, std::string data);

	// 加载数据	
	RcResult LoadDataByCsvFile(std::string pDir);		// 加载Csv数据		
	RcResult LoadSecsConfig(std::string pDir);			// 加载SECS配置

	// 获取句柄
	IMCHandle GetIMCHandle();

	// 授权
	RcResult GetLicenseLevel(__int32& nLevel);			// 获取许可授权级别
	RcResult GetMaxRunCount(__int32& nCount);			// 获取允许运行个数
	RcResult GetMaxRunDataPoint(__int32& nCount);		// 获取允许运行数据点(变量、事件、警报分别计算)
		 
public:
// 特定内容操作

	// 报警操作
	RcResult AlarmGetList(std::string& pData);				// 报警列表
	RcResult AlarmAdd(int nALID, std::string pALTX);		// 增加报警	
	RcResult AlarmAdd(int nALID, std::string pALTX, int nAlarmSetCEID, int nAlarmClearCEID, bool bEnable, int nCategory, bool bAddEvent);	// 添加报警
	RcResult AlarmEnable(int nALID, bool bEnable);	// 启用报警	
	RcResult AlarmSet(int nALID, bool bSet);		// 设置报警	
	RcResult AlarmSetAll(bool bSet);				// 设置触发所有的报警
	RcResult AlarmNotifyEventMode(int nMode);		// 警报发生后，事件通知方式	


	// 事件操作	
	RcResult EventPos(int nCEID, bool bWaitReply = false);								// 事件发送: CEID 
	RcResult EventPos(std::string EventName, bool bWaitReply = false);						// 事件发送: 事件名称 		
	RcResult EventAdd(int nCEID, std::string pDescription, std::string pEventName, bool bEnable);			// 增加事件列表	
	RcResult EventGetList(std::string& pData);
	RcResult EventEnable(int nCEID, bool bEnable);										// 事件启用/禁用
	RcResult EventIsEnable(int nCEID, bool& bEnable);									// 事件是否启用/禁用
	RcResult EventDvvals(std::string eventName, std::string &dvvalNameList);			// 事件DVVAL绑定
	RcResult EventDvvals(int nECID, std::string& dvvalList);							// 事件DVVAL绑定
	RcResult EventDiscreteVarPos(int nCEID, bool bWaitSendFinish = true);				// 事件S6,F3发送: CEID
	
	//报告
	RcResult EventReportLink(int nECID, std::string& report);				// 事件-报表关联
	RcResult EventReportUnlink(int nECID);									// 事件-报表取消关联
	RcResult ReportDefine(int rptID, std::string& varID);					// 报表定义
	RcResult ReportDefineGet(int rptID, std::string& varID);				// 获取报表定义
	RcResult ReportDelete(int rptID);										// 删除报表
	RcResult ReportUnlink(int rptID);										// 清除报表所有与之相关的事件
	RcResult ReportClear();													// 清除所有报告定义，并且清除所有事件与报告之间的并联
	RcResult ReportStrictlyFollowStandard(bool bFollow);					// 报告严格按照标准规范处理：E5标准的处理及返回值	
	RcResult ReportAutoSaveHostLinkConfig(bool bEnable);					// 报告保存服务器配置到本地

	// 变量操作	
	RcResult VariableAdd(int varID, std::string varName, std::string description, 
		std::string valueType, std::string initValue, std::string units, std::string varClass); // 变量增加  
	RcResult VariableSet(int varID, std::string newValue);					// 设置变量新值 	
	RcResult VariableGet(int varID, std::string& pValue);					// 获取变量的值  	
	RcResult VariableGetList(std::string& pData);							// 变量列表获取
	RcResult VariableSetMethod(int varID, bool enable);						// 设置处理方法
	
	// 常量
	RcResult ConstantsAdd(int nECID, std::string name, std::string description, std::string Type, 
		std::string Units, std::string MinValue, std::string MaxValue, std::string DefValue); // 添加常量      

	RcResult ConstantsGet(int nECID, std::string& pValue);		// 常量获取
	RcResult ConstantsSet(int nECID, std::string newValue);		// 设置变量新值  
	RcResult ConstantsInfoGet(std::string& pInfoList);			// 常量信息获取
	RcResult ConstantsSetMethod(int nECID, bool bEnable);		// 设置处理方法	       
	RcResult ConstantChangeSendEventEnable(bool bEnable);		// 启用/禁用常量改变发送事件  

	// 主动请求主机时间进行同步
	RcResult ActiveTimeSynchronizeRequest();				// 主动请求时间同步
	
	// 发送终端服务
	RcResult SendSingleTerminal(std::string pContent);
	RcResult SendMultipleTerminal(std::vector<std::string> svContent);

	// PP 处理
	RcResult PPAllowHostDowmload(bool bAllow);		// 允许主机下载
	RcResult PPHandleMode(int nMode);				// PP处理模式

	// PP 内置处理程序
	void SetRecipeDirectory(std::string dir);				// 设置程式目录
	RcResult ProcessProgramUpload(std::string ppid);			// 设置程式目录	
	RcResult ProcessProgramDownload(std::string ppid);		// 设置程式目录	
	RcResult PPIsFolderDir(bool bFolder);				// 设置PP是文件夹目录	
	RcResult SetWinrarPath(std::string path);				// 设置winrar目录
	RcResult PPSetFilenameExtension(std::string pFileExten);	// 设置扩展名
		
	RcResult PPFormatAdd(std::string pCmdCode, std::string pName, std::string pValueType);	// 参数对象添加 
	RcResult PPFormatSend(std::string ppid);					// PP序列化上传
	RcResult PPFormatRequest(std::string ppid);					// PP序列化下载	
	RcResult PPFormatSetCodeMode(int nMode);					// PP序列化设置模式

	// wafer map
	RcResult WaferMapUpload(std::string pWaferMap);		// 晶圆图上传
	RcResult WaferMapDownload(std::string pWaferInfo, std::string& pWaferMap);	// 晶圆图下传请求	
	RcResult StripMapDownload(std::string pStripInfo, std::string& pStripMap);	// 条带图下传请求

	// 扩展操作
	RcResult SendSecsMsgAsync(int64 nStream, int64 nFunction, bool bReply, std::string pData, int64& nMsgID);
	RcResult SendSecsMsgSync(int nStream, int nFunction, bool bReply, std::string pData, std::string& pReplyData);
	RcResult SendReply(int nStream, int nFunction, int nTransactionID, std::string pData);
	
	RcResult MessageTypeAdd(int nStream, int nFunction, SecsMessageReceiveProc pCallback, void* pClientData);
	RcResult MessageTypeRemove(int nStream, int nFunction);

	void EnableRuntimeTrace(bool bEnable);	// 启用运行过程中的LogTrace,追查BUG等

private:
	// 连接回调，默认函数
	virtual void OnConnected() { std::cout << "CONNECTED to the SECS Server\n"; }

	void CloseProcess(std::string pName);

public:
	// 设置响应连接回调函数
	void ConnectedProcSet(IMCConnectedProc p) { imc_setConnectedProc(m_ih, p); }
	static void OnConnectedCallback(IMCHandle ic);		// 响应连接回调


private:
	// 响应断开连接，默认函数
	virtual void OnDisconnected() { std::cerr << "DISCONNECTED from the SECS Server\n"; }
public:
	// 设置断开连接函数
	void DisconnectedProcSet(IMCDisconnectedProc p) {imc_setDisconnectedProc(m_ih, p); }

	// 响应断开连接回调
	static void OnDisconnectedCallback(IMCHandle dc);

	// 追溯log
	static void OnTraceLog(IMCHandle, int64 nCode, const char* pText); 
	void OnTraceLog(int64 nCode, const char* pText); 

private:
	IMCHandle m_ih;


};



#ifndef RCRESULT_DEFINED
// 在返回值中，包含错误代码与信息
struct RcResult {
	int rc;             // return code
	std::string result;
	RcResult(): rc(0), result("") {}
	RcResult(int i, const char *s) : rc(i), result(s) {}
	RcResult(int i, const std::string &s) : rc(i), result(s) {}
	RcResult(const char *rcResultString) {_parse(rcResultString);}
	RcResult(const std::string &rcResultString) {_parse(rcResultString.c_str());}
	std::string ToString(void);
	bool operator == (int nCode){ return (rc == nCode);}
	bool operator != (int nCode){ return (rc != nCode);}


private:
	void _parse(const char *string);
};
#define RCRESULT_DEFINED
#endif

// 授权
RcResult JngGetLicenseLevel(__int32& nLevel);			// 获取许可授权级别
RcResult JngGetMaxRunCount(__int32& nCount);			// 获取允许运行个数
RcResult JngGetMaxRunDataPoint(__int32& nCount);		// 获取允许运行数据点(变量、事件、警报分别计算)


// 将text链表分解成元素字符串，返回数值为0代表成功
RcResult listSplit(const char *srcList, std::list<std::string> &sv);
RcResult listSplit(const char *srcList, std::vector<std::string> &sv);
RcResult listSplit(const std::string &srcList, std::list<std::string> &sv);
RcResult listSplit(const std::string &srcList, std::vector<std::string> &sv);


// 加入字符串元素到一个链表
std::string listJoin(std::vector<std::string> &sv);
std::string listJoin(std::list<std::string> &sl);
std::string listJoin(int argc, const char *argv[]);

std::string listJoin(const char *e1, const char *e2 = NULL, const char *e3 = NULL,
	const char *e4 = NULL, const char *e5 = NULL, const char *e6=NULL);

std::string listJoin(int count, std::string s1, std::string s2 = "", std::string s3 = "", 
	std::string s4 = "", std::string s5 = "", std::string s6 = "");		// count：告知个数



// 附加一个或者多个元素到链表尾部
void listAppend(std::string &srcList, const char *e1, const char *e2 = NULL, const char *e3 = NULL,
	const char *e4 = NULL, const char *e5 = NULL, const char *e6=NULL);

void listAppend(std::string &srcList, int count, std::string s1, std::string s2 = "", std::string s3 = "",
	std::string s4 = "", std::string s5 = "", std::string s6 = "");


// 提取srcList中第index1 的 index2 的 index3元素
std::string listElement(std::string &srcList, int index1, int index2 = -1, int index3 = -1);


// 获取错误代码，通过code
RcResult GetErrorByCode(long nCode);

// 整形和符串互转
std::string IntToString(__int64 nValue);
__int64 StringToInt(std::string pValue);

// 16进制转10进制
unsigned char HexToDec(char pHigth, char pLow);

// 10进制转16进制
void DecToHex(const unsigned char nDec, char& cHightHex, char& cLowHex);

// 转字符串
std::string ToString(__int64 nValue);
std::string ToString(__int32 nValue);
std::string ToString(__int16 nValue);
std::string ToString(__int8  nValue);
std::string ToString(unsigned __int64 nValue);
std::string ToString(unsigned __int32 nValue);
std::string ToString(unsigned __int16 nValue);
std::string ToString(unsigned __int8  nValue);
std::string ToString(float nValue);
std::string ToString(double nValue);

#ifndef __VSYNCH_H__
#define __VSYNCH_H__

class vLockObject
{
public:
	vLockObject(int nLockType = eLocker)
	{
		m_nLockType = nLockType;
		m_pSection = imc_createLocker(eLocker);
	}
	virtual ~vLockObject()
	{
		imc_releaseLocker(m_pSection);
	}
	void Lock()
	{
		imc_locker(m_pSection);
	}
	void UnLock()
	{
		imc_unlocker(m_pSection);
	}

private:
	void* m_pSection;
	int m_nLockType;
};

/////////////////锁辅助类
class vLocker
{
public:
	vLocker(vLockObject* pLock=NULL){		
		m_pLock=pLock;
		if( m_pLock!=NULL )
			m_pLock->Lock();
	}
	~vLocker(){
		if( m_pLock!=NULL )
			m_pLock->UnLock();
	}

private:	
	vLockObject* m_pLock;
};


////临界区
class vCritical : public vLockObject
{
public:
	vCritical():
	  vLockObject(::eLocker)
	{		
	}	
};

#endif



