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

#pragma hdrstop

#include "CDSIfscF.h"
#include "CDSTrafficF.h"
#include "ITSUtilF.h"
#include "AppGlobalF.h"
#include "CDSLinkF.h"

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

#pragma package(smart_init)

TItsTrafficServiceLink::TItsTrafficServiceLink()
{
    TItsTrafficServiceLink("");
}
//---------------------------------------------------------------------------
TItsTrafficServiceLink::TItsTrafficServiceLink(String AId)
{
    FIFSC_ID   = AId;
    Clear();
    FModified = false;
    FCompleted= false;
}
//---------------------------------------------------------------------------
void TItsTrafficServiceLink::Clear()
{
}
//---------------------------------------------------------------------------
TItsTrafficServiceLink::~TItsTrafficServiceLink()
{
}
//---------------------------------------------------------------------------
void TItsTrafficServiceLink::SetValue(String &AOrgValue, String AValue)
{
    if (AOrgValue != AValue)
    {
        AOrgValue = AValue;
        if (FCompleted) FModified = true;
    }
}
//---------------------------------------------------------------------------
void TItsTrafficServiceLink::SetFIFSC_ID(String AValue)
{
    SetValue(FIFSC_ID, AValue);
}
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
TItsTrafficServiceLinkManager *ItsTrafficServiceLinkManager = NULL;
//---------------------------------------------------------------------------

/*
* TrafficLink Manager
*/
TItsTrafficServiceLinkManager::TItsTrafficServiceLinkManager()
{
    FFirst = true;
}
//---------------------------------------------------------------------------
TItsTrafficServiceLinkManager::~TItsTrafficServiceLinkManager()
{
}
//---------------------------------------------------------------------------
bool TItsTrafficServiceLinkManager::LoadFromDb(TADOConnection *ADbConn/*=NULL*/)
{
    String sQry;
    TADOQuery *pADO = NULL;

//ITSUtil_Trace("TItsTrafficServiceLinkManager::LoadFromDb - start");

    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";
    try
    {
        FLists.Lock();
        FLists.RemoveAll();
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = (NULL != ADbConn) ? ADbConn : ITSDb_GetConnection();
			pADO->SQL->Clear();
			pADO->SQL->Text = sQry;

			pADO->Open();
            //int nRows = pADO->RecordCount;
            for( ; !pADO->Eof; pADO->Next())
            {
				TItsTrafficServiceLink *pTrafficLink = new TItsTrafficServiceLink();

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

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

                if (FFirst)
                {
                    TItsTraffic *pTraffic = new TItsTraffic();

                    pTraffic->LEVL         = 2;
                    pTraffic->LINKID       = pTrafficLink->FIFSC_ID;
                    if (pTrafficLink->FMISSING == "N")
                    {
                        pTraffic->SPEED        = pTrafficLink->FSPED;
                        pTraffic->CMTR_GRAD_CD = pTrafficLink->FCMTR_GRAD_CD;
                        if      (pTraffic->CMTR_GRAD_CD == "LTC1") pTraffic->TRF_GRADE = "1";
                        else if (pTraffic->CMTR_GRAD_CD == "LTC2") pTraffic->TRF_GRADE = "2";
                        else if (pTraffic->CMTR_GRAD_CD == "LTC3") pTraffic->TRF_GRADE = "3";
                        else                                       pTraffic->TRF_GRADE = "0";

                        pTraffic->REGDATE      = pTrafficLink->FPRCN_DT;
                        pTraffic->DATACNT      = pTrafficLink->FDATA_NUM;
                        pTraffic->TRVTM        = pTrafficLink->FTRVL_HH;
                    }
                    else
                    {
                        pTraffic->SPEED        = 0;
                        pTraffic->CMTR_GRAD_CD = "LTC0";
                        pTraffic->TRF_GRADE    = "0";
                        pTraffic->REGDATE      = "19000101000000";
                        pTraffic->DATACNT      = 0;
                        pTraffic->TRVTM        = 0;
                    }

                    ItsTrafficManager->FLists.Push(pTraffic->LINKID, pTraffic);
                }
            }
            FFirst = false;
            ItsTrafficManager->FIfsc = true;
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORLOG("TItsTrafficServiceLinkManager::LoadFromDb", 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("TItsTrafficServiceLinkManager::LoadFromDb", String(exception.ClassName()), exception.Message, sQry);
            return false;
            throw Exception(String(exception.ClassName()) + exception.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        FLists.UnLock();
    }
//ITSUtil_Trace("TItsTrafficServiceLinkManager::LoadFromDb - end");

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

TItsServiceLink::TItsServiceLink()
{
    TItsServiceLink("");
}
//---------------------------------------------------------------------------
TItsServiceLink::TItsServiceLink(String AId)
{
    IFSC_ID   = AId;
    Clear();
    FModified = false;
    FCompleted= false;
    FPolyLine = NULL;
}
//---------------------------------------------------------------------------
void TItsServiceLink::Clear()
{
}
//---------------------------------------------------------------------------
TItsServiceLink::~TItsServiceLink()
{
    FSubLists.clear();
}
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
TItsServiceLinkManager *ItsServiceLinkManager = NULL;
//---------------------------------------------------------------------------

/*
* Link Manager
*/
TItsServiceLinkManager::TItsServiceLinkManager()
{
}
//---------------------------------------------------------------------------
TItsServiceLinkManager::~TItsServiceLinkManager()
{
}
//---------------------------------------------------------------------------
bool TItsServiceLinkManager::LoadFromDb(TADOConnection *ADbConn/*=NULL*/)
{
    FLists.RemoveAll();

    return (LoadLink(ADbConn) && LoadLinkList(ADbConn));
}
//---------------------------------------------------------------------------
bool TItsServiceLinkManager::LoadLink(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";
//           " ORDER BY IFSC_ID                                  \r\n";
    try
    {
        FLists.Lock();
        try
        {
            pADO = new TADOQuery(NULL);
            pADO->Close();
            pADO->Connection = (NULL != ADbConn) ? ADbConn : ITSDb_GetConnection();
            pADO->SQL->Clear();
            pADO->SQL->Text = sQry;

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

                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;

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

                pIfsc->TRAF = new TItsTraffic(2, pIfsc->IFSC_ID);
                ItsTrafficManager->FLists.Push(pIfsc->IFSC_ID, pIfsc->TRAF);
            }
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsServiceLinkManager::LoadLink", 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("TItsServiceLinkManager::LoadLink", 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 TItsServiceLinkManager::LoadLinkList(TADOConnection *ADbConn/*=NULL*/)
{
    bool bResult = true;
    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "SELECT IFSC_ID, LINK_ID, ORD \r\n"
           "  FROM TB_IFSC_LINK_RLTN     \r\n";
//           " ORDER BY IFSC_ID, ORD       \r\n";
    try
    {
        ItsServiceLinkManager->FLists.Lock();
        TItsServiceLink *pServiceLink = NULL;
        TItsLink *pLink;

        try
        {
            int nORD;

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

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

                String sLINK_ID = pADO->FieldByName("LINK_ID")->AsString;
				nORD            = pADO->FieldByName("ORD")->AsInteger;
                pServiceLink->FSubLists.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;
                pServiceLink->FSubLists.Push(sORD, pSubLink);
#endif
            }
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsServiceLinkManager::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("TItsServiceLinkManager::LoadLinkList", String(exception.ClassName()), exception.Message, sQry);
            return false;
            throw Exception(String(exception.ClassName()) + exception.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        ItsServiceLinkManager->FLists.UnLock();
    }

    return LoadCoordFromDb(ADbConn);
    //return bResult;
}
//---------------------------------------------------------------------------
bool TItsServiceLinkManager::LoadCoordFromDb(TADOConnection *ADbConn/*=NULL*/)
{
    String sQry;
    TADOQuery *pADO = NULL;

#if 0
    sQry = "SELECT IFSC_ID, LEVL, ORD, X_CRDN, Y_CRDN  \r\n"
           "  FROM TB_IFSC_VRTX                        \r\n"
           " WHERE LEVL = 4                            \r\n"
           " ORDER BY IFSC_ID, LEVL, ORD               \r\n";
#else
    sQry = "SELECT B.IFSC_ID, A.POINTCNT, A.VERTEX                   \r\n"
           "  FROM (SELECT ROWNUM AS ID, X.* FROM TB_IFSC_GIS X) A,  \r\n"
           "       (SELECT ROWNUM AS ID, X.* FROM TB_IFSC X) B       \r\n"
           " WHERE A.ID = B.ID                                       \r\n";
#endif

    TItsServiceLink* pObj;
    TStringList *sl = NULL;
    int ii;
    sl = new TStringList;
    sl->Delimiter = ',';
    sl->StrictDelimiter = true;
    try
    {
        FLists.Lock();
        try
        {
            pADO = new TADOQuery(NULL);
            pADO->Close();
            pADO->Connection = (NULL != ADbConn) ? ADbConn : ITSDb_GetConnection();
            pADO->SQL->Clear();
            pADO->SQL->Text = sQry;

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

                int    FPointCnt = pADO->FieldByName("POINTCNT")->AsInteger;
                String FVertex   = pADO->FieldByName("VERTEX")->AsString;

                sl->DelimitedText = FVertex;
                if (sl->Count != FPointCnt * 2)
                {
                    continue;
                }
                for (ii = 0; ii < sl->Count-1; )
                {
                    TItsCoord *pCoord = new TItsCoord();
                    pCoord->X = sl->Strings[ii].ToDouble();
                    pCoord->Y = sl->Strings[ii+1].ToDouble();
                    pObj->Coords.Push(pObj->Coords.Size(), pCoord);

                    if (pCoord->X < pObj->bounds.minX) pObj->bounds.minX = pCoord->X;
                    if (pCoord->Y < pObj->bounds.minY) pObj->bounds.minY = pCoord->Y;
                    if (pCoord->X > pObj->bounds.maxX) pObj->bounds.maxX = pCoord->X;
                    if (pCoord->Y > pObj->bounds.maxY) pObj->bounds.maxY = pCoord->Y;

                    ii += 2;
                }
                continue;

				TItsCoord *pCoord = new TItsCoord();

                pCoord->X = pADO->FieldByName("X_CRDN")->AsFloat;
                pCoord->Y = pADO->FieldByName("Y_CRDN")->AsFloat;

				pObj->Coords.Push(pObj->Coords.Size(), pCoord);
            }
        }
        catch(EDatabaseError &E)
        {
            ::PostMessage(Application->MainForm->Handle, (UINT)(WM_USER+0xF4), (WPARAM)0xB2, (LPARAM)0xB2);
            DBERRORMSG("TItsServiceLinkManager::LoadCoordFromDb", 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("TItsServiceLinkManager::LoadCoordFromDb", 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 (sl) delete sl;
    }

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

