// GPVision.h: interface for the CGPVision class.
//
//////////////////////////////////////////////////////////////////////

#pragma once

#include <vector>
#include <string>

#include "VisionNW.h"
#include "utility.h"

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

namespace VISION_BASE
{

    constexpr size_t MAX_VISION_STATION = 20;

    enum NEXT_SOT
    {
        REF_AUTO_CALIBRATION = 2,
        RESOLUTION_AUTO_CALIBRATION,
        MANUAL_TEACH,
        INSPECTION,
    };

    enum TYPE_ID
    {
        TYPE1 = 1,
        TYPE2,
        TYPE3,
        TYPE4,
        TYPE5,
        TYPE6,
        TYPE7,
    };

    struct stGPDoubleDataResult
    {
        double dResult1{ 0. };
        double dResult2{ 0. };
        double dResult3{ 0. };
        double dResult4{ 0. };
    };

    class CScanner;

    class COMMDLL_DLLCLASS CVisionBase : public CVisionNW
    {
    public:
        enum class TWO_TYPE_INSPECTION
        {
            DISABLED = 0,
            INDEPENDENT_INSP,
            ONE_TRIGGER_INSP,
        };

        CVisionBase(std::string csMutexName = _T("vision_mutex"), size_t nMaxStation = MAX_VISION_STATION);
        virtual ~CVisionBase();

        // feature to enable/disable multiple app display. Used along with SwitchAppWindow
        virtual bool MultipleAppWindow(bool bEnable, DWORD dwTimeout = 5000) = 0;

        virtual bool SwitchAppWindow(int nStationNo, DWORD dwTimeout = 5000) = 0;
        bool         IsLotOpen() const;
        bool         WaitInTeach(int nStationNo, DWORD dwTimeout);
        bool         WaitResultReady(int nStationNo, DWORD dwTimeout);
        virtual bool WaitImageTaken(int nStationNo, DWORD dwTimeout = 0);
        bool         GetResult(int nStationNo, std::string& csResult);
        std::string  GetReceiveData();

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

        virtual bool CameraLiveCapture(int nStationNo, bool bOn = true, int nType = 1) = 0;
        virtual bool IsTeachingValid(int nStationNo, int nTypeID)                      = 0;
        virtual bool SetShiftID(const std::string& csShiftID)                          = 0;
        virtual bool SetNetUPH(long lNetUPH)                                           = 0;
        virtual bool SetGrossUPH(long lGrossUPH)                                       = 0;
        virtual bool SetMachineName(const std::string& csName)                         = 0;
        virtual bool SetOperatorID(const std::string& csOperatorID)                    = 0;
        virtual bool SetLotNumber(const std::string& strLotNumber)                     = 0;
        virtual bool SetLotSize(long lLotSize)                                         = 0;
        virtual bool IsTeach(int nStationNo)                                           = 0;
        virtual bool IsRun()                                                           = 0;
        virtual bool IsAck()                                                           = 0;
        virtual bool Stop()                                                            = 0;
        virtual bool Run()                                                             = 0;
        virtual bool DataEnd()                                                         = 0;
        virtual bool DataStart()                                                       = 0;
        virtual bool SetPackageID(long lPackageID)                                     = 0;
        virtual bool GetResult(int nStationNo, stGPDoubleDataResult& st_dResult)       = 0;
        virtual bool CheckResultReady(int nStationNo)                                  = 0;
        virtual bool CloseLot(DWORD dwTimeout = 5000)                                  = 0;
        virtual bool OpenLot(int nPackageID, DWORD dwTimeout = 5000)                   = 0;
        virtual bool OpenLot(const std::string& strPackageName, DWORD dwTimeout = 5000) = 0;
        virtual bool CheckImageTaken(int nStationNo)                                   = 0;
        virtual bool StartInspect(int nStationNo, int nNextSOT = 0, int nEdge = 1, TWO_TYPE_INSPECTION nTypeID = TWO_TYPE_INSPECTION::DISABLED) = 0;

        virtual void ReceiveComm(const char* cpcBuffer, int nSize) = 0;

        HANDLE GetResultReadyHandle(int nStationNo);
        HANDLE GetImageTakenHandle(int nStationNo);

    protected:
        virtual bool SendCommand(const std::string& strCommand, bool bWaitAck = false, DWORD dwTimeout = 5000);
        virtual bool GetStatus() = 0;
        virtual bool SendMsg(const std::string& strMsg, DWORD dwTimeout, bool bWaitAck = false);

        CMutex m_VisionMutex;

        size_t m_nMaxStation{ MAX_VISION_STATION };
        HANDLE m_hAck;
        HANDLE m_hStatusReady;

        std::vector<HANDLE> m_hImageTaken;
        std::vector<HANDLE> m_hInTeach;
        std::vector<HANDLE> m_hResultReady;
        std::vector<HANDLE> m_hTeachValidReady;

        std::vector<stGPDoubleDataResult> m_stResult;
        std::vector<std::string>          m_vecResult;

        bool m_bRunMode{ false };
        char m_cReceiveData[MAXSOCKBUF]{};
        bool m_bTeachingValid{ false };
        bool m_bLotOpened{ false };
        char m_cRcvData[MAXSOCKBUF]{};

        static bool m_bInitBefore;
    };
}