#pragma once

#include "serialcommhelper.h"


enum LKS_AXIS
{
	LKS_X=1,
	LKS_Y=(1<<1),
	LKS_Z=(1<<2),
	LKS_R=(1<<3),
};

enum LKS_DIR{
    LKS_FOREWARD=1,
	LKS_BACKWARD=0,
};

#define	LC_PIN0  1
#define LC_PIN1  (1<<1)
#define LC_PIN2  (1<<2)
#define LC_PIN3  (1<<3)
#define LC_PIN4  (1<<4)
#define LC_PIN5  (1<<5)
#define LC_PIN6  (1<<6)
#define LC_PIN7  (1<<7)

//固定位
#define LC_Y_LIMIT LC_PIN3
#define LC_X_LIMIT LC_PIN1
#define LC_Y_ORIG  LC_PIN2
#define LC_X_ORIG  LC_PIN7


#define LC_MAX_BUFFER_IN   512
#define LC_MAX_MSG_IN      128




typedef void   (*CURPOS_REPORT_FUNC) (int, double, double, double, double, void*);

#define LK_CMD_LEN   10
//void   OnPosReport(int axis, double x, double y, double z, double r, void* pUserData);

#define LC_POS_ACCURANCE     100

class CLksLock
{
public:
	CLksLock(CRITICAL_SECTION* pCs){
		m_pCs = pCs;
		::EnterCriticalSection(pCs);
	}
	~CLksLock(){
	    ::LeaveCriticalSection(m_pCs);
	}

private:
	CRITICAL_SECTION* m_pCs;
};

class ROBBASE_API CLksCard :	public CSerialCommHelper
{
public:
	CLksCard(void);
	virtual ~CLksCard(void);
	 
	virtual BOOL			Start();
	virtual void			Stop();
	 
	BOOL IsInOrgin(int axis);
	BOOL IsInLimit(int axis);

	BOOL IsAxisMoving(int axis, BOOL& result, double* pCurVal =NULL);

	BOOL StopAxis(int axis, int outs = -1);
	BOOL GoHome(int axis, int speed, int acc);

	BOOL GoX(double x, int dir, int speed, int acc);
	BOOL GoY(double y, int dir, int speed, int acc);
	BOOL GoXY(double x, double y, int dir, int speed, int acc);

	//获得当前位置
	BOOL ReadCurPos(double& x, double& y, double& z, double& r);
	BOOL ReadCurPos(int axis, double& result);

	BOOL ReadAbsPos(double& x, double& y, double& z, double& r);
	BOOL ReadAbsPos(int axis, double& result);

	BOOL ReadInput(int& result);
	BOOL WriteOutput(int bits);

	int  GetOutBits(){ return ~m_nOutput; }

	BOOL PauseAxis(int axis, int outs);
	BOOL ResumeAxis(int axis, int dir,int speed, int acc);

public:
	CURPOS_REPORT_FUNC m_pPosReportFunc;
	void*   m_pUserData;

	
	int m_nTimeout;

	int m_nPulsePerRound;//电机每转需要的脉冲
	int m_nMotionRate;    //传动比

public:
	void Receive(void);
private:

	BOOL ReadPos(BOOL bAbsPos, double& x, double& y, double& z, double& r);
	BOOL ReadPos(BOOL bAbsPos, int axis, double& result);


	//int m_nCurX, m_nCurY, m_nCurZ, m_nCurR; //当前位置，单位:脉冲


	int m_nOutput;
	//BOOL m_bXInMoving,m_bRInMoving,m_bYInMoving,m_bZInMoving;

	char m_bufferIn[LC_MAX_BUFFER_IN ];
	int  m_nCurLength;

	HANDLE m_hRecvInEvent;
	HANDLE m_hRecvThread;
	//BOOL   m_bStarted;

	CRITICAL_SECTION m_csRecv; //数据接收锁
	CRITICAL_SECTION m_csComm; //通信过程锁

	char m_recvIn[LC_MAX_MSG_IN* LK_CMD_LEN];
	int  m_recvCount;
	//char m_posIn[LK_CMD_LEN+1];
private:
	
 
	int Decode(char* buff, int size);
	
    void  EmptyRecv();

   //接受消息回复的时候，如果添加了新的指令，请
   //确认指令字母在is_normal_cmd已经支持，否则
   //将收不到回复。
	BOOL GetRecv(char* buff, int size);
public:
	
};

