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

#pragma hdrstop

#include "CDSIfscF.h"
#include "CDSLayerF.h"
#include "CDSLinkF.h"
#include "CDSLayerF.h"
#include "ITS_OPLibF.h"

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

#pragma package(smart_init)

TItsIfsc::TItsIfsc()
{
    Clear();
}
//---------------------------------------------------------------------------
void TItsIfsc::Clear()
{
}
//---------------------------------------------------------------------------
TItsIfsc::~TItsIfsc()
{
    FLinks.clear();
}
//---------------------------------------------------------------------------
void TItsIfsc::InitTraffic()
{
    TRAF->InitTraffic();
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
TItsIfscManager *ItsIfscManager = NULL;
//---------------------------------------------------------------------------

/*
* IFSC Manager
*/
TItsIfscManager::TItsIfscManager()
{
}
//---------------------------------------------------------------------------
TItsIfscManager::~TItsIfscManager()
{
}
//---------------------------------------------------------------------------
void TItsIfscManager::InitTraffic()
{
    try
    {
        FLists.Lock();

        FOR_STL(TItsIfsc*, pObj, FLists)
        {
            pObj->InitTraffic();
        }
    }
    __finally
    {
        FLists.UnLock();
    }
}
//---------------------------------------------------------------------------
bool TItsIfscManager::LoadFromDb(TADOConnection *ADbConn/*=NULL*/)
{
    FLists.RemoveAll();

    return (LoadIfsc(ADbConn) && LoadLinkList(ADbConn));
}
//---------------------------------------------------------------------------
bool TItsIfscManager::LoadIfsc(TADOConnection *ADbConn/*=NULL*/)
{
    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "SELECT IFSC_ID           ,                         \r\n"
           "       IFSC_NM           ,                         \r\n"
           "       DRCT_CD           ,                         \r\n"
           "       STRT_NM           ,                         \r\n"
           "       END_NM            ,                         \r\n"
           "       SECT_LNGT         ,                         \r\n"
           "       EXTR_CNCT_SECT_YN ,                         \r\n"
           "       DEL_YN            ,                         \r\n"
           "       RMRK              ,                         \r\n"
           "       F_NODE_ID         ,                         \r\n"
           "       T_NODE_ID         ,                         \r\n"
           "       SECT_GRAD_CD      ,                         \r\n"
           "       AREA_CD           ,                         \r\n"
           "       DECODE(AREA_CD, 'LAT001', 'Y', 'N') REGN_YN \r\n"
           "  FROM TB_IFSC                                     \r\n";

    FLists.Lock();
    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
            pADO->Close();
            pADO->Connection = (NULL != ADbConn) ? ADbConn : ITSDb_GetConnection();
            pADO->SQL->Clear();
            pADO->SQL->Text = sQry;

            pADO->Prepared = true;
            pADO->Open();
            //int nRows = pADO->RecordCount;
            for( ; !pADO->Eof; pADO->Next())
            {
                TItsIfsc *pIfsc = new TItsIfsc();

                pIfsc->IsVertex          = false;
                pIfsc->IFSC_ID           = pADO->FieldByName("IFSC_ID")->AsString;
                pIfsc->IFSC_NM           = pADO->FieldByName("IFSC_NM")->AsString.Trim();
                pIfsc->DRCT_CD           = pADO->FieldByName("DRCT_CD")->AsString;
                pIfsc->RMRK              = pADO->FieldByName("RMRK")->AsString.Trim();
                pIfsc->EXTR_CNCT_SECT_YN = pADO->FieldByName("EXTR_CNCT_SECT_YN")->AsString;
                pIfsc->DEL_YN            = pADO->FieldByName("DEL_YN")->AsString;
                pIfsc->SECT_LNGT         = pADO->FieldByName("SECT_LNGT")->AsString;
                pIfsc->SECT_GRAD_CD      = pADO->FieldByName("SECT_GRAD_CD")->AsString;
                pIfsc->F_NODE_ID         = pADO->FieldByName("F_NODE_ID")->AsString;
                pIfsc->T_NODE_ID         = pADO->FieldByName("T_NODE_ID")->AsString;
                pIfsc->STRT_NM           = pADO->FieldByName("STRT_NM")->AsString.Trim();
                pIfsc->END_NM            = pADO->FieldByName("END_NM")->AsString.Trim();
                pIfsc->REGN_YN           = pADO->FieldByName("REGN_YN")->AsString;
                pIfsc->AREA_CD           = pADO->FieldByName("AREA_CD")->AsString;
                //pIfsc->REGN_YN          = "Y";

                FLists.Push(pIfsc->IFSC_ID, pIfsc);
                pIfsc->Completed = true;

                pIfsc->TRAF = new TCDSTraffic();
            }
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsIfscManager::LoadIfsc", String(E.ClassName()), E.Message, sQry);
            return false;
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &exception)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsIfscManager::LoadIfsc", String(exception.ClassName()), exception.Message, sQry);
            return false;
            throw Exception(String(exception.ClassName()) + exception.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        FLists.UnLock();
    }

    return true;
}
//---------------------------------------------------------------------------

bool TItsIfscManager::LoadLinkList(TADOConnection *ADbConn/*=NULL*/)
{
    bool bResult = true;
    String sQry;
    TADOQuery *pADO = NULL;

#if 1
// POHANG
    sQry = "SELECT IFSC_ID, LINK_ID, ORD \r\n"
           "  FROM TB_IFSC_LINK_RLTN     \r\n";
#else
    sQry = "SELECT IFSC_ID, LINK_ID, ORD \r\n"
           "  FROM TB_IFSC_RLTN_LINK     \r\n";
#endif

    TItsIfsc *pIfsc = NULL;
    TItsLink *pLink;

    FLists.Lock();
    try
    {
        try
        {
            int nORD;

            pADO = new TADOQuery(NULL);
            pADO->Close();
            pADO->Connection = (NULL != ADbConn) ? ADbConn : ITSDb_GetConnection();
            pADO->SQL->Clear();
            pADO->SQL->Text = sQry;

            pADO->Prepared = true;
            pADO->Open();
            //int nRows = pADO->RecordCount;
            for( ; !pADO->Eof; pADO->Next())
            {
                String sIFSC_ID = pADO->FieldByName("IFSC_ID")->AsString;
                pIfsc = FLists.Find(sIFSC_ID);
                if (!pIfsc) continue;

                String sLINK_ID = pADO->FieldByName("LINK_ID")->AsString;
				nORD            = pADO->FieldByName("ORD")->AsInteger;
                pIfsc->FLinks.insert(std::make_pair<int, String>(nORD, sLINK_ID));

                pLink = ItsLinkManager->FLists.Find(sLINK_ID);
                if (pLink) pLink->IFSC_ID = sIFSC_ID;

#if 0
				String sORD     = pADO->FieldByName("ORD")->AsString;
                TSubLink *pSubLink = new TSubLink();
                pSubLink->FLinkId = sLINK_ID;
                pIfsc->FLinks.Push(sORD, pSubLink);
#endif
            }
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsIfscManager::LoadLinkList", String(E.ClassName()), E.Message, sQry);
            return false;
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &exception)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsIfscManager::LoadLinkList", String(exception.ClassName()), exception.Message, sQry);
            return false;
            throw Exception(String(exception.ClassName()) + exception.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        FLists.UnLock();
    }

    if (g_AppCfg.isLoadFromFile)
    {
        return LoadVrtxFromFile(ADbConn);
    }
    return LoadVrtxFromDb(ADbConn);
}
//---------------------------------------------------------------------------
bool TItsIfscManager::LoadVrtxFromFile(TADOConnection *ADbConn/*=NULL*/)
{
    String     sQry;
    AnsiString sAppDir = ExtractFilePath(Application->ExeName);
    AnsiString sFileName = sAppDir + "\\MAPDATA\\layers\\IFSC.dat";

    sQry = String(sFileName);

	FILE *fd;
	if ((fd = fopen(sFileName.c_str(), "r")) == NULL)
    {
        return false;
    }

    FLists.Lock();

    TStringList *sl = NULL;
    char         szBuff[8192];

    int nCnt = 0;
    try
    {
        sl = new TStringList;
        sl->Delimiter = ';';
        sl->StrictDelimiter = true;

        while (1)
        {
            nCnt++;
            memset(szBuff, 0x00, sizeof(szBuff));
            if (fgets(szBuff, sizeof(szBuff), fd) == NULL) break;

            sl->DelimitedText = String(szBuff);
            if (sl->Count != 3)
            {
                continue;
            }
            try {
                String IFSC_ID = sl->Strings[0];
				TItsIfsc *pObj = FLists.Find(IFSC_ID);
                if (pObj)
                {
                    pObj->IsVertex   = true;
                    pObj->X_CRDN_ARR = sl->Strings[1];
                    //pObj->Y_CRDN_ARR = sl->Strings[2];
                    pObj->Y_CRDN_ARR = StringReplace(sl->Strings[2], "\n", "", TReplaceFlags() << rfReplaceAll);
                }
            }
            catch(Exception &e)
            {
                DBERRORMSG("TIfscManager::LoadVertexFromDb", String(e.ClassName()), e.Message, sQry);
                throw Exception(String(e.ClassName()) + e.Message);
            }
        }
    }
    __finally
    {
        if (sl) delete sl;
        if (fd) fclose(fd);
        FLists.UnLock();
    }

    return true;
}
//---------------------------------------------------------------------------
bool TItsIfscManager::LoadVrtxFromDb(TADOConnection *ADbConn/*=NULL*/)
{
    String sQry;
    TADOQuery *pADO = NULL;

#if 0
    sQry = "SELECT A.IFSC_ID, A.LEVL,           \r\n"
           "       A.X_CRDN_ARR, A.Y_CRDN_ARR   \r\n"
           "  FROM TB_IFSC_VRTX_ARR A,          \r\n"
           "       TB_IFSC          B           \r\n"
           " WHERE B.DEL_YN  = 'N'              \r\n"
           "   AND B.IFSC_ID = A.IFSC_ID        \r\n"
           "   AND A.LEVL    = 3                \r\n";
#else
#if 0
    sQry = "SELECT *                 \r\n"
           "  FROM VW_IFSC_VRTX_ARR  \r\n";
#else
    sQry = "SELECT A.IFSC_ID AS IFSC_ID, A.LEVL AS LEVL,        \r\n"
           "       SUBSTR(A.X_CRDN_ARR,    1, 400) AS XMSG01,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR,  401, 400) AS XMSG02,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR,  801, 400) AS XMSG03,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 1201, 400) AS XMSG04,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 1601, 400) AS XMSG05,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 2001, 400) AS XMSG06,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 2401, 400) AS XMSG07,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 2801, 400) AS XMSG08,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 3201, 400) AS XMSG09,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 3601, 400) AS XMSG10,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 4001, 400) AS XMSG11,   \r\n"
           "       SUBSTR(A.X_CRDN_ARR, 4401, 400) AS XMSG12,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR,    1, 400) AS YMSG01,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR,  401, 400) AS YMSG02,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR,  801, 400) AS YMSG03,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 1201, 400) AS YMSG04,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 1601, 400) AS YMSG05,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 2001, 400) AS YMSG06,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 2401, 400) AS YMSG07,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 2801, 400) AS YMSG08,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 3201, 400) AS YMSG09,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 3601, 400) AS YMSG10,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 4001, 400) AS YMSG11,   \r\n"
           "       SUBSTR(A.Y_CRDN_ARR, 4401, 400) AS YMSG12    \r\n"
           "  FROM VW_IFSC_VRTX_ARR A                           \r\n";
#endif
#endif

    TItsIfsc* pObj;
//    int       LEVL;

    FLists.Lock();
    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = (NULL != ADbConn) ? ADbConn : ITSDb_GetConnection();
			pADO->SQL->Clear();
			pADO->SQL->Text = sQry;

            pADO->Prepared = true;
			pADO->Open();
            for( ; !pADO->Eof; pADO->Next())
            {
                String IFSC_ID = pADO->FieldByName("IFSC_ID")->AsString;
                pObj = FLists.Find(IFSC_ID);
                if (!pObj) continue;

#if 0
                LEVL = pADO->FieldByName("LEVL")->AsInteger;
                TItsVrtx* pVrtx = new TItsVrtx();
                pVrtx->X_CRDN_ARR = pADO->FieldByName("X_CRDN_ARR")->AsString;
                pVrtx->Y_CRDN_ARR = pADO->FieldByName("Y_CRDN_ARR")->AsString;

				pObj->Vrtxs.Push(LEVL, pVrtx);
#else
                pObj->IsVertex   = true;
#if 0
                pObj->X_CRDN_ARR = pADO->FieldByName("X_CRDN_ARR")->AsString;
                pObj->Y_CRDN_ARR = pADO->FieldByName("Y_CRDN_ARR")->AsString;
#else
                pObj->X_CRDN_ARR = "";
                pObj->Y_CRDN_ARR = "";
                String COLM;
                for (int ii = 1; ii < 13; ii++)
                {
                    COLM.printf(L"XMSG%02d", ii);
                    pObj->X_CRDN_ARR += pADO->FieldByName(COLM)->AsString;
                    COLM.printf(L"YMSG%02d", ii);
                    pObj->Y_CRDN_ARR += pADO->FieldByName(COLM)->AsString;
                }
#endif
#endif
            }
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsIfscManager::LoadVrtxFromDb", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &exception)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsIfscManager::LoadVrtxFromDb", String(exception.ClassName()), exception.Message, sQry);
            throw Exception(String(exception.ClassName()) + exception.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        FLists.UnLock();
    }

    return true;
}
//---------------------------------------------------------------------------
bool TItsIfscManager::LoadTraffic(TADOConnection *ADbConn/*=NULL*/)
{
    String sQry;
    TADOQuery *pADO = NULL;

    InitTraffic();

    sQry = "SELECT A.IFSC_ID, PRCN_DT, TFVL, SPED, OCPY_RATE, TRVL_HH, CMTR_GRAD_CD, PTRN_SPED, DATA_NUM, \r\n"
           "       (CASE WHEN PRCN_DT <= TO_CHAR(SYSDATE - 10/1440, 'YYYYMMDDHH24MISS')                   \r\n"
           "             THEN 'Y' ELSE 'N' END) AS MISSING,                                               \r\n"
           "       (CASE WHEN PRCN_DT >= TO_CHAR(SYSDATE - 15/1440, 'YYYYMMDDHH24MISS')                   \r\n"
           "             THEN 'Y' ELSE 'N' END) AS LASTANS,                                               \r\n"
           "       (SELECT MAX(PRCN_DT) FROM TB_LINK_TRAF) MPRCN_DT                                       \r\n"
           "  FROM TB_IFSC_TRAF A, TB_IFSC B                                                              \r\n"
           " WHERE A.IFSC_ID = B.IFSC_ID                                                                  \r\n";

    FLists.Lock();
    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = (NULL != ADbConn) ? ADbConn : ITSDb_GetConnection();
			pADO->SQL->Clear();
			pADO->SQL->Text = sQry;

            pADO->Prepared = true;
			pADO->Open();
            for( ; !pADO->Eof; pADO->Next())
            {
                String ID = pADO->FieldByName("IFSC_ID")->AsString;
                TItsIfsc *pObj = FLists.Find(ID);
                if (!pObj) continue;

                pObj->TRAF->PRCN_DT      = pADO->FieldByName("PRCN_DT")->AsString;
                pObj->TRAF->TFVL         = pADO->FieldByName("TFVL")->AsInteger;
                pObj->TRAF->SPED         = pADO->FieldByName("SPED")->AsInteger;
                pObj->TRAF->OCPY_RATE    = pADO->FieldByName("OCPY_RATE")->AsFloat;
                pObj->TRAF->TRVL_HH      = pADO->FieldByName("TRVL_HH")->AsInteger;
                pObj->TRAF->CMTR_GRAD_CD = pADO->FieldByName("CMTR_GRAD_CD")->AsString;
				pObj->TRAF->MISSING      = pADO->FieldByName("MISSING")->AsString;       // 결측여부
				pObj->TRAF->LASTANS      = pADO->FieldByName("LASTANS")->AsString;       // 최근 15분 이내 가공
				pObj->TRAF->MPRCN_DT     = pADO->FieldByName("MPRCN_DT")->AsString;      // 가공시각(최신)
                pObj->TRAF->DATA_NUM     = pADO->FieldByName("DATA_NUM")->AsInteger;
                pObj->TRAF->PTRN_SPED    = pADO->FieldByName("PTRN_SPED")->AsInteger;

                if (pObj->TRAF->CMTR_GRAD_CD == "LTC0") pObj->TRAF->MISSING = "Y";
                if (pObj->TRAF->MISSING == "Y") pObj->TRAF->CMTR_GRAD_CD = "LTC0";

                if      (pObj->TRAF->CMTR_GRAD_CD == "LTC1") pObj->TRAF->TRAF_GRAD = 1;
                else if (pObj->TRAF->CMTR_GRAD_CD == "LTC2") pObj->TRAF->TRAF_GRAD = 2;
                else if (pObj->TRAF->CMTR_GRAD_CD == "LTC3") pObj->TRAF->TRAF_GRAD = 3;
                else                                         pObj->TRAF->TRAF_GRAD = 0;
            }
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORLOG("TItsIfscManager::LoadTraffic", String(E.ClassName()), E.Message, sQry);
            return false;
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &exception)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORLOG("TItsIfscManager::LoadTraffic", String(exception.ClassName()), exception.Message, sQry);
            return false;
            throw Exception(String(exception.ClassName()) + exception.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        FLists.UnLock();
    }

    return true;
}
//---------------------------------------------------------------------------

