//---------------------------------------------------------------------------

#include <vcl.h>
#include "VMSCommLibF.h"
#pragma hdrstop

#include "JobThreadF.h"
#include "ClientSessionF.h"
#include "ClientSessionManagerF.h"
#include "CDSCtlrF.h"
#include "VmsProtocolF.h"
//---------------------------------------------------------------------------

#pragma package(smart_init)


TJobThread *JobThread = NULL;
//---------------------------------------------------------------------------
TJobThread::TJobThread()
{
    FPnlState = NULL;
    FTmrDb = NULL;
}
//---------------------------------------------------------------------------
TJobThread::~TJobThread()
{
}
//---------------------------------------------------------------------------

void __fastcall TJobThread::updateLedColor(TColor AColor)
{
    try {
        if (FPnlState) {
            PostMessage((HWND)g_AppCfg.lMainWinHandle, WM_PANEL_REFRESH, 3, (LPARAM)AColor);
            //FPnlState->Color = AColor;
            //FPnlState->Refresh();
        }
    } catch(Exception &e) {}
}
//---------------------------------------------------------------------------

DWORD __fastcall TJobThread::Process(LPVOID AParam)
{
    TClientSession  *pSession;
    IPC_JOB_MESSAGE *pMsg;
    DWORD            dwJob;
    int              nRcvSize;
    char            *pRcvBuff;
    OverlappedIO     overlappedIO;

    while(!IsTerm() && !g_AppCfg.bThrExit)
    {
        updateLedColor(clGreen);

        if (!g_jobQ.PopBlocking(dwJob))
        {
            continue;
        }
        if (dwJob == Q_CLOSE)
        {
            break;
        }
        else
        if (dwJob == Q_TICK)
        {
            updateLedColor(clRed);

            ClientSessionManager->SendFlushAllClient();
            ClientSessionManager->CheckCommandTimeoutSessions();
#if USE_POOL
#else
            ClientSessionManager->CollectGarbageSessions();
#endif
            continue;
        }
        else
        if (dwJob == eTcpCloseAll)
        {
            updateLedColor(clLime);

            ClientSessionManager->CloseAll();
            continue;
        }
        else
        if (dwJob == eVmsFormDownload)
        {
            // 정주기 시나리오 다운로드
            updateLedColor(clLime);
            SendVmsFormDownload();
            continue;
        }
        else
        if (dwJob == eVmsStatusReqAll)
        {
            // 정주기 상태정보 요청
            updateLedColor(clLime);
            SendVmsStatusReq();
            continue;
        }

        updateLedColor(clLime);

        pMsg = (IPC_JOB_MESSAGE*)dwJob;

        try
        {
            pSession = (TClientSession*)pMsg->ObjPtr;
            if (pSession == NULL)
            {
                MERROR("JOBT Unknown Event Null session: %d", pMsg->Type);
            }
            else
            {
                switch(pMsg->Type)
                {
                case eTcpConnect:
                    if (pSession->OnConnect())
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eTcpErrorEvent:
                case eTcpErrorRecv:
                case eTcpErrorSend:
                case eTcpClose:
                    pSession->Disconnect();
                    break;
                case eTcpRecv:
                    nRcvSize = pSession->GetFreeSpaceSize();
                    pRcvBuff = pSession->GetBuffer();
                    if (nRcvSize >= pMsg->Len && pRcvBuff)
                    {
                        memcpy(pRcvBuff, pMsg->Buff, pMsg->Len);
                        overlappedIO.FSession = pSession;
                        RecvCompletion(0, pMsg->Len, (LPWSAOVERLAPPED)&overlappedIO, 0);
                    }
                    break;


                // 폼 다운로드 시작
                case eVmsScenarioDownload: // 개별 명령에 의한 시나리오 다운로드
                    if (pSession->download_form_schedule(false) > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;

                case eVmsStatusReq:
                    if (pSession->ReqStauts())
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsPowerModuleStautsReq:
                    if (pSession->ReqPowerModuleStatus())
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsDisplayModuleStatusReq:
                    if (pSession->ReqDisplayModuelStatus())
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsParamReq:
                    if (pSession->ReqParameter() > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsPixelImage:
                    if (pSession->ReqPixelImage(pMsg->Buff) > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsUploadCurrentForm:
                    if (pSession->ReqUploadCurrentForm() > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsDispalyDefaultForm:
                    if (pSession->ReqDisplayDefaultForm() > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsUploadScheduleForm:
                    if (pSession->ReqUploadScheduleForm() > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsDisplayFormId:
                    if (pSession->ReqDisplayFormId(pMsg->Buff) > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsStatusControl:
                    if (pSession->ReqStatusControl(pMsg->Buff, pMsg->Len) > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                case eVmsSendPacket:
                    if (pSession->ReqSendPacket(pMsg->Buff, pMsg->Len) > 0)
                    {
                        pSession->SendFlush();
                    }
                    break;
                }

                if (pSession->IsConnected)
                {
                    pSession->SendFlush();
                }
            }
        }
        __finally
        {
            //SAFE_DELETE(pMsg);
        }
    }

    Term();
    return 0;
}
//---------------------------------------------------------------------------

int __fastcall TJobThread::SendVmsFormDownload()
{
    CtlrItr it;
    for(it=CDSCtlrManager->FLists.FObjects.begin(); it != CDSCtlrManager->FLists.FObjects.end(); ++it)
    {
        TCDSCtlr *pObj = (TCDSCtlr*)it->second;

        if (!pObj->Used) continue;
        if (!pObj->FProvide) continue;

        try
        {
            TClientSession *pSession = pObj->FSession;
            if (pSession)
            {
                if (pSession->download_form_schedule(true) > 0)
                {
                    pSession->SendFlush();
                }
            }

            // 제어기로 전송 시퀀스를 호출한 후에 타임아웃을 체크하도록 한다.
		    pObj->CTRLMODE->SaveFlag = false;
			pObj->CTRLMODE->pTimer = Now();
        }
        catch(Exception &e)
        {
        }
    }
    return 0;
}
//---------------------------------------------------------------------------

int __fastcall TJobThread::SendVmsStatusReq()
{
    CtlrItr it;
    for(it=CDSCtlrManager->FLists.FObjects.begin(); it != CDSCtlrManager->FLists.FObjects.end(); ++it)
    {
        TCDSCtlr *pObj = (TCDSCtlr*)it->second;

        if (!pObj->Used) continue;

        try
        {
            TClientSession *pSession = pObj->FSession;
            if (pSession)
            {
                if (pSession->ReqStauts() > 0)
                {
                    pSession->SendFlush();
                }
            }
        }
        catch(Exception &e)
        {
        }
    }
    return 0;
}
//---------------------------------------------------------------------------

