// RSLaser.h: interface for the CRSLaser class.
//
//////////////////////////////////////////////////////////////////////
#pragma once

#include <string>

#include "VisionNW.h"
#include "Utility.h"

#ifdef BUILD_COMMDLL
#define COMMDLL_DLLCLASS __declspec(dllexport)
#else
#define COMMDLL_DLLCLASS __declspec(dllimport)
#endif

enum LOT_TYPE
{
    LOT,
    LOT2,
    LOT3
};

enum
{
    LASER_MARK_TIMEOUT,
    LASER_MARK_COMPLETE,
    LASER_MARK_IN_PROGRESS,
    LASER_MARK_ALARM,
};

class COMMDLL_DLLCLASS CRSLaser : public CVisionNW
{
public:
    // ctor
    CRSLaser();
    virtual ~CRSLaser();

    // methods
    HANDLE GetMarkingInProgressHandle();
    HANDLE GetAlarmHandle();
    int    WaitMarkInProgress(DWORD dwTimeout);
    int    IsAlarm(DWORD dwTimeout);
    int    WaitMarkComplete(DWORD dwTimeout);

    std::string GetReceiveData();
    bool        Send(const std::string& strMsg);

    bool MeasurePower(DWORD dwTimeout);
    void ReceiveComm(const char* cpcBuffer, int nSize) override;

    bool   SetSetting(const std::string& strSetting, int nRequired, DWORD dwTimeout);
    bool   SetDeviceID(int nOriginLocation, const std::string& strDeviceIDData, DWORD dwTimeout);
    bool   SetBin(int nOriginLocation, const std::string& strBinData, DWORD dwTimeout);
    bool   SetMatrixPosition(double dX, double dY, double dAngle, DWORD dwTimeout);
    bool   SetPositionAndOccupation(const std::string& strMsg, DWORD dwTimeout);
    bool   SetPart(int nPartNo, DWORD dwTimeout);
    bool   SetOccupation(const std::string& strMsg, DWORD dwTimeout);
    double GetPowerValue(DWORD dwTimeout);

    std::string GetLayoutFile(DWORD dwTimeout);
    std::string GetLotID(DWORD dwTimeout);
    bool        GetAlarm(int& nAlarmNo, std::string& csAlarmMsg, DWORD dwTimeout);

    int IsPowerAutoMode(DWORD dwTimeout);
    int IsPowerOK(DWORD dwTimeout);
    int IsMarkingEnd(DWORD dwTimeout);
    int IsJobEnd(DWORD dwTimeout);
    int IsSystemReady(DWORD dwTimeout);

    bool StopMark();
    bool StartMark();
    bool CancelJob();
    bool LoadJob();

    bool SetVariable(const std::string& strVariableName, const std::string& csData, DWORD dwTimeout);
    bool SetLotFile(const std::string& strLotFilename, DWORD dwTimeout);
    bool SetLayout(const std::string& csLotNo, long lLotQty, const std::string& csLayoutFilename, const std::string& csVariableData, int nLotType, DWORD dwTimeout);

    bool Connect(int nPortNo, const std::string& csIPAddress, bool bServer = true);
    void Disconnect();
    bool IsClientConnected();
    bool IsServerActive();
    bool IsConnectedToServer();

    HANDLE GetMarkingEndHandle();

protected:
    bool GetPowerStatus(DWORD dwTimeout);
    bool GetNextData(char* Token, char** context);
    bool SendMsg(const std::string& csMsg, DWORD dwTimeout);
    bool DecodeStatus(char* Token, char** context);
    bool GetStatus(const std::string& csStatusName, DWORD dwTimeout);

    HANDLE m_hAck;
    HANDLE m_hNack;
    HANDLE m_hStatusReady;
    HANDLE m_hSystemReady;
    HANDLE m_hJobEnd;
    HANDLE m_hMarkingEnd;
    HANDLE m_hMarkingInProgress;
    HANDLE m_hPowerStatusReady;
    HANDLE m_hAlarm;

    bool        m_bAlarm;
    std::string m_strAlarmMsg;
    int         m_nAlarmNo;

    std::string m_strLotID;
    std::string m_strLayoutFilename;
    double      m_dPower;
    bool        m_bPowerOK;
    bool        m_nPowerAutoMode;

    char m_cReceiveData[4096];
    bool m_bWaitForTerminator2;

private:
    int GetMsgCase(const std::string& csMsg);
};
