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

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

#include "DbmReadThreadF.h"
#include "CDSProcessF.h"
#include "CDSManagerF.h"
#include "CDSImageF.h"
#include "CDSFormF.h"
#include "CDSIfscF.h"

#pragma package(smart_init)

TDbmReadThread *DbmReadThread = NULL;
//---------------------------------------------------------------------------
TDbmReadThread::TDbmReadThread()
{
    FPnlState = NULL;
    FTmrDb = NULL;
}
//---------------------------------------------------------------------------
TDbmReadThread::~TDbmReadThread()
{
}
//---------------------------------------------------------------------------

int __fastcall TDbmReadThread::CloseDb()
{
    try
    {
        if (FDb)
        {
            FDb->Close();
        }
    }
    catch(Exception &e)
    {
    }
    return 0;
}
//---------------------------------------------------------------------------

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

DWORD __fastcall TDbmReadThread::Process(LPVOID AParam)
{
    IPC_DBM_MESSAGE *pDbm;
    DWORD            dwJob;
    AnsiString       sSysTime;
    bool             isDbOk;

	CoInitialize(NULL);

    FDb = new TDMAdoDb(NULL);
    if (g_AppCfg.IsDbConnectPerJob == false)
    {
        FDb->Connect(g_AppCfg.db.sConnectStr);
    }

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

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

        updateLedColor(clLime);

        pDbm = (IPC_DBM_MESSAGE*)dwJob;

        int nRes = 0;
        try
        {
            if (g_AppCfg.IsDbConnectPerJob == true)
            {
                FDb->Connect(g_AppCfg.db.sConnectStr);
            }

            if (FDb->IsDbConnected() == false)
            {
                if (!FDb->Connect(g_AppCfg.db.sConnectStr))
                {
                    nRes = -1;
                    FDb->SetDbState(false);
                    MERROR("Database connect failed...");
                }
            }

            AnsiString dbJobName = APP_GetDbJobName(pDbm->Command);
            DWORD starDbJobTick = GetTickCount();

            if (pDbm->Command != dbm_save_ctlr_stts) {
                MINFO("=======================> DBMS JOB START: %s", dbJobName.c_str());
            }

            if (nRes == 0)
            {
                if (FTmrDb) {
                    FTmrDb->Tag = (int)pDbm->Command;
                }
                SendMessage((HWND)g_AppCfg.lMainWinHandle, WM_DB_THREAD, dbm_job_start, 0);

                switch(pDbm->Command)
                {
                case dbm_save_unit_stts:
                    nRes = CDSProcessManager->SaveUnitStts(FDb->GetConnection());
                    break;
                //case dbm_save_unit_stts_hs:
                //    nRes = CDSProcessManager->SaveUnitSttsHs(FDb->GetConnection());
                //    break;

                case dbm_save_ctlr_stts:
                    nRes = CDSCtlrManager->SaveCtlrStts(FDb->GetConnection(), pDbm->U.Data);
                    break;

                case dbm_param_res:
                    nRes = CDSCtlrManager->SaveCtlrParam(FDb->GetConnection(), pDbm->U.Data);
                    break;

                case dbm_save_ctlr_stts_all:
                    nRes = CDSCtlrManager->SaveCtlrSttsAll(FDb->GetConnection());
                    break;

                case dbm_load_onoff_time:
                    nRes = CDSManager->LoadVmsOnOffTime(FDb->GetConnection());
                    break;

                case dbm_load_download_job:
                    nRes = CDSManager->LoadVmsDownLoadJob(FDb->GetConnection());
                    break;

                case dbm_save_form_download:
                    nRes = CDSManager->SaveVmsDownloadForm(FDb->GetConnection());
                    break;

                case dbm_dnld_form_init:
                case dbm_dnld_form_cycle:
                case dbm_dnld_form_mode:
                case dbm_dnld_form_eveh:
                    /*
                    *  VMS 정보제공구간 교통정보를 생성한 후 VMS 메세지를 생성하는 경우
                    */
                    if (CDSVmsIfscTrafManager)
                    {
                        nRes = CDSVmsIfscTrafManager->CreateVmsIfscTraffic(FDb->GetConnection());
                    }
                    nRes = CDSManager->DownloadVmsForm(FDb->GetConnection(), pDbm->Command);
                    break;  // static_cycle, mode_change

                case dbm_provide_result:
                    nRes = CDSManager->SaveProvideResult(FDb->GetConnection(), pDbm->U.Data);
                    break;

                case dbm_master_symbol_image:
                case dbm_master_symbol_traffic:
                    nRes = CDSImageManager->LoadVmsSymbolInfo(FDb->GetConnection());
                    break;

                case dbm_master_form:
                    nRes = CDSFormManager->LoadVmsFormInfo(FDb->GetConnection());
                    break;

                case dbm_master_vms_ifsc:
                    /*
                    *  VMS 정보제공구간 교통정보를 생성한 후 VMS 메세지를 생성하는 경우
                    */
                    if (CDSVmsIfscTrafManager)
                    {
                        nRes = CDSVmsIfscTrafManager->InitVmsIfscTraffic(FDb->GetConnection());
                    }

                    nRes = CDSIfscManager->LoadVmsIfscInfo(FDb->GetConnection());
                    break;

                case dbm_check_db_alive:
                    nRes = FDb->IsDbAlive(sSysTime);
                    break;

                case dbm_initialize:
                    nRes = app_initialize();
                    break;

                case dbm_check_evehicle_alarm:
                    //nRes = CDSManager->CheckVmsEVehicleInf(FDb->GetConnection());
                    nRes = CDSManager->LoadVmsEVehicleInf(FDb->GetConnection(), dbm_check_evehicle_alarm);
                    //MINFO("Database job EVehicleAlarm");
                    break;

                default:
                    MERROR("Unknown DBMS Job Type: %d", pDbm->Command);
                    break;
                }
                if (nRes < 0)
                {
                    FDb->SetDbState(false);
                    FDb->Close();
                    MERROR("Database job error: %d", pDbm->Command);
                }
                else
                {
                    FDb->SetDbState(true);
                }
            }
            if (pDbm->Command != dbm_save_ctlr_stts) {
                MINFO("=======================> DBMS JOB ..END: %s, %d, Elapsed: %u ms.", dbJobName.c_str(), nRes, GetTickCount() - starDbJobTick);
            }
        }
        __finally
        {
            if (g_AppCfg.IsDbConnectPerJob == true)
            {
                FDb->Close();
            }
            SendMessage((HWND)g_AppCfg.lMainWinHandle, WM_DB_THREAD, pDbm->Command, nRes);

            //SAFE_DELETE(pDbm);
        }
    }

    if (g_AppCfg.IsDbConnectPerJob == false)
    {
        FDb->Close();
    }
    SAFE_DELETE(FDb);

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

int __fastcall TDbmReadThread::app_initialize()
{
#if 0
    MINFO("DCOM Process Information initialize...");
    if (DMManager->GetProcessInfo() != VERR_NONE)
    {
        MERROR("DCOM Process Information initialize failed. Program abnormal terminate.");
        return -1;
    }

    MINFO("DCOM VMS Information initialize...");
    if (DMManager->GeTCDSCtlrInfo() != VERR_NONE)
    {
        MERROR("DCOM VMS Information initialize failed. Program abnormal terminate.");
        return -2;
    }

    MINFO("DCOM VMS Scetion Information initialize...");
    if (DMManager->GetVmsIfscInfo() != VERR_NONE)
    {
        MERROR("DCOM VMS Scetion Information initialize failed. Program abnormal terminate.");
        return -3;
    }

    MINFO("DCOM VMS Form Information initialize...");
    if (DMManager->GetVmsImage() != VERR_NONE)
    {
        MERROR("DCOM VMS Form Information initialize failed. Program abnormal terminate.");
        return -4;
    }

    MINFO("DCOM VMS Form Information initialize...");
    if (DMManager->LoadVmsForm() != VERR_NONE)
    {
        MERROR("DCOM VMS Form Information initialize failed. Program abnormal terminate.");
        return -5;
    }
#endif
    return 0;
}
//---------------------------------------------------------------------------

