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


#pragma hdrstop

//---------------------------------------------------------------------------
#include <vcl.h>
#include <assert.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <Systobj.h>
#include <time.h>

#include <Buttons.hpp>
#include <Classes.hpp>
#include <ComCtrls.hpp>
#include <Controls.hpp>
#include <Chart.hpp>
#include <DB.hpp>
#include <DBClient.hpp>
#include <DBGrids.hpp>
#include <DBXpress.hpp>
#include <Dialogs.hpp>
#include <ExtCtrls.hpp>
#include <FMTBcd.hpp>
#include <Forms.hpp>
#include <Graphics.hpp>
#include <Grids.hpp>
#include <jpeg.hpp>
#include <Mask.hpp>
#include <Menus.hpp>
#include <Messages.hpp>
#include <OleCtrls.hpp>
#include <Outline.hpp>
#include <Provider.hpp>
#include <SqlExpr.hpp>
#include <StdCtrls.hpp>
#include <System.hpp>
#include <SysUtils.hpp>
#include <Types.hpp>
//#include <Windows.hpp>
#include <inifiles.hpp>
//---------------------------------------------------------------------------
#include "AppGlobalF.h"
//---------------------------------------------------------------------------

#pragma package(smart_init)
//---------------------------------------------------------------------------

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

/*
 * 프로그램 환경설정 파일에서 설정 정보를 읽어온다.
 */
bool APP_LoadConfigInfo()
{
    String    sCfgFile;
    TIniFile *pIniFile = NULL;

    sCfgFile = g_sCfgDir + g_sAppName + ".ini";
    g_AppCfg.sConfigFile = sCfgFile;

    DATABASE_INFO *pDb;
    try
    {
        String sTmp;

        pIniFile = new TIniFile(sCfgFile);

        g_AppCfg.sTitle     = pIniFile->ReadString("APPLICATION", "TITLE",      "VMS Communication Server");
        g_AppCfg.sSystemId  = pIniFile->ReadString("APPLICATION", "SYSTEMID",   "VMS01");

        g_AppCfg.sProcessId = pIniFile->ReadString("APPLICATION", "PROCESSID",  "30101");
        g_AppCfg.nProcessId = g_AppCfg.sProcessId.ToIntDef(0);
        g_AppCfg.nProcessPort = pIniFile->ReadInteger("APPLICATION", "PROCESSPORT", 5301);;

        g_AppCfg.DownloadBitmap = pIniFile->ReadInteger("APPLICATION", "DOWNLOADBITMAP", 0) == 1 ? true : false;
        LOAD_DB = pIniFile->ReadInteger("APPLICATION", "LOADDB", 1) == 1 ? true: false;

        g_sFtpHomeDir = pIniFile->ReadString("APPLICATION", "FTPHOMEDIR", g_sFtpHomeDir);
        if (g_sFtpHomeDir.SubString(g_sFtpHomeDir.Length(), 1) != "\\")
            g_sFtpHomeDir += "\\";

        g_AppCfg.nTrafficCycleTime = pIniFile->ReadInteger("APPLICATION", "TrafficCycleTime",  300);
        if (g_AppCfg.nTrafficCycleTime < 60) g_AppCfg.nTrafficCycleTime = 60;

        g_AppCfg.nTrafficBasisTime = pIniFile->ReadInteger("APPLICATION", "TrafficBasisTime",  60);
        g_AppCfg.nSaveFormType     = pIniFile->ReadInteger("APPLICATION", "SaveFormType",      0);
        if (g_AppCfg.nSaveFormType < 0 || g_AppCfg.nSaveFormType > 2) g_AppCfg.nSaveFormType = 0;
        g_AppCfg.nDefaultFillColor = pIniFile->ReadInteger("APPLICATION", "DefaultFillColor",  0);

        //정체폼 판정 주기(즉, 주기값이상인 경우 정체폼생성 >= )
        g_AppCfg.CngsContCnt = pIniFile->ReadString("APPLICATION", "CngsContCnt", "2").ToIntDef(2);
        if (g_AppCfg.CngsContCnt < 1) g_AppCfg.CngsContCnt = 1;
        //1단 교통정보폼 중앙정렬 여부
        g_AppCfg.Traf1RowCenter = pIniFile->ReadString ("APPLICATION", "Traffic1RowCenter", "0").ToIntDef(0) == 1 ? true : false;
        g_AppCfg.IsImageSeqSave = pIniFile->ReadString ("APPLICATION", "IMAGESEQSAVE",      "0").ToIntDef(0) == 1 ? true : false;


        g_AppCfg.MaxMemory = pIniFile->ReadInteger("RESOURCE", "MAXMEMORY", 512);
        g_AppCfg.MaxHandle = pIniFile->ReadInteger("RESOURCE", "MAXHANDLE", 0);
        g_AppCfg.MaxThread = pIniFile->ReadInteger("RESOURCE", "MAXTHREAD", 4096);
        g_AppCfg.MaxGdi    = pIniFile->ReadInteger("RESOURCE", "MAXGDI",    0);
        g_AppCfg.RcRestart = (bool)pIniFile->ReadInteger("RESOURCE", "RESTART",   0);

        g_AppCfg.comm.nCenterPort  = pIniFile->ReadInteger("COMMUNICATION", "CENTERPORT",  6020);
        g_AppCfg.comm.nListenPort  = (short)pIniFile->ReadInteger("COMMUNICATION", "LISTENPORT",  6020);
        g_AppCfg.comm.sLocalDomain = pIniFile->ReadString ("COMMUNICATION", "LOCALDOMAIN", "VMS_SERVER");

        g_AppCfg.comm.nClientPort = pIniFile->ReadInteger("COMMUNICATION", "CLIENTPORT", 355);
        g_AppCfg.comm.sLoginUser  = pIniFile->ReadString ("COMMUNICATION", "LOGINUSER",  "ysvms");

        g_AppCfg.comm.nConnectWait  = pIniFile->ReadInteger("COMMUNICATION", "CONNECTWAIT",  60);
        g_AppCfg.comm.nCmdTimeOut   = pIniFile->ReadInteger("COMMUNICATION", "CMDTIMEOUT",   5);
        g_AppCfg.comm.nWatchDogTime = pIniFile->ReadInteger("COMMUNICATION", "WATCHDOGTIME", 30);
        g_AppCfg.comm.nPollingTime  = pIniFile->ReadInteger("COMMUNICATION", "POLLINGTIME",  20);
        g_AppCfg.IsIpChecking       = pIniFile->ReadString ("COMMUNICATION", "IPCHECKING",  "1").ToIntDef(0) == 1 ? true : false;

        if (g_AppCfg.comm.nPollingTime < 10) g_AppCfg.comm.nPollingTime = 10;
        if (g_AppCfg.comm.nPollingTime > 90) g_AppCfg.comm.nPollingTime = 90;

        if (g_AppCfg.comm.nConnectWait  < 30) g_AppCfg.comm.nConnectWait  = 30;
        if (g_AppCfg.comm.nConnectWait  > 60) g_AppCfg.comm.nConnectWait  = 60;
        if (g_AppCfg.comm.nCmdTimeOut   <  5) g_AppCfg.comm.nCmdTimeOut   =  5;
        if (g_AppCfg.comm.nWatchDogTime < 30) g_AppCfg.comm.nWatchDogTime = 30;
        g_AppCfg.comm.nWatchDogTime += 5;   // 5초정도를 더 추가해 준다(딜레이발생할 경우)


        g_AppCfg.BottomTrafficCycle  = pIniFile->ReadString("FIGURE", "TRAFFIC_CYCLE",  "0").ToIntDef(0);
        g_AppCfg.BottomTrafficMaxCnt = pIniFile->ReadString("FIGURE", "TRAFFIC_MAX",    "1").ToIntDef(0);
        g_AppCfg.BottomTrafficCenter = pIniFile->ReadString("FIGURE", "TRAFFIC_CENTER", "1").ToIntDef(0) == 1 ? true : false;
        if (g_AppCfg.BottomTrafficCycle != 0)
        {
            if (g_AppCfg.BottomTrafficCycle < 3)
            {
                g_AppCfg.BottomTrafficCycle = 3;    //하단소통정보 표출하는 경우 3초보다 작으면 최소 3초로 설정한다.
            }
        }

        FIGURE.GRADE0 = pIniFile->ReadString("FIGURE", "0", "-").Trim();
        FIGURE.GRADE1 = pIniFile->ReadString("FIGURE", "1", "월활").Trim();
        FIGURE.GRADE2 = pIniFile->ReadString("FIGURE", "2", "지체").Trim();
        FIGURE.GRADE3 = pIniFile->ReadString("FIGURE", "3", "정체").Trim();

        TEXT.GRADE0 = pIniFile->ReadString("TEXT", "0", "-").Trim();
        TEXT.GRADE1 = pIniFile->ReadString("TEXT", "1", "소통원활").Trim();
        TEXT.GRADE2 = pIniFile->ReadString("TEXT", "2", "지 체").Trim();
        TEXT.GRADE3 = pIniFile->ReadString("TEXT", "3", "정 체").Trim();

        pDb = &g_AppCfg.db;
        pDb->sConnectStr = pIniFile->ReadString("DATABASE", "CONNECTSTR", "");
        if (pDb->sConnectStr == "")
        {
            pDb->sProvider   = pIniFile->ReadString("DATABASE", "PROVIDER",   "");
            pDb->sServerName = pIniFile->ReadString("DATABASE", "SERVERNAME", "");
            pDb->sCatalog    = pIniFile->ReadString("DATABASE", "CATALOG",    "");
            pDb->sUserName   = pIniFile->ReadString("DATABASE", "USERNAME",   "");
            pDb->sPassword   = pIniFile->ReadString("DATABASE", "PASSWORD",   "");

            pDb->MakeConnString();
        }

        try
        {
            g_AppCfg.nMaxLogLines = pIniFile->ReadInteger("LOG", "LOGLINE", 200);
            if (g_AppCfg.nMaxLogLines > 1000) g_AppCfg.nMaxLogLines = 1000;
            if (g_AppCfg.nMaxLogLines < 0)    g_AppCfg.nMaxLogLines = 100;

            g_AppCfg.sLogDay      = pIniFile->ReadString ("LOG", "LOGDAY",  "");

            g_LogCfg.Info    = (bool)pIniFile->ReadInteger("LOG", "INFO",    1);
            g_LogCfg.Data    = (bool)pIniFile->ReadInteger("LOG", "DATA",    0);
            g_LogCfg.Error   = (bool)pIniFile->ReadInteger("LOG", "ERROR",   1);
            g_LogCfg.Warning = (bool)pIniFile->ReadInteger("LOG", "WARNING", 1);
            g_LogCfg.Debug   = (bool)pIniFile->ReadInteger("LOG", "DEBUG",   0);
            g_LogCfg.Detail  = (bool)pIniFile->ReadInteger("LOG", "DETAIL",  0);
            g_LogCfg.Detail  = 0;
        } catch(Exception &e) {}

        g_AppCfg.bThrExit = false;
        g_AppCfg.bThrJobExit = false;
        g_AppCfg.hFinishEvent = NULL;
    }
    __finally
    {
        if (pIniFile) delete pIniFile;
        pIniFile = NULL;
    }

    return true;
}
//---------------------------------------------------------------------------
bool APP_ReLoadConfigInfo()
{
    String    sCfgFile;
    TIniFile *pIniFile = NULL;

    sCfgFile = g_AppCfg.sConfigFile;

    try
    {
        String sTmp;

        pIniFile = new TIniFile(sCfgFile);


        //정체폼 판정 주기(즉, 주기값이상인 경우 정체폼생성 >= )
        g_AppCfg.CngsContCnt = pIniFile->ReadString("APPLICATION", "CngsContCnt", "2").ToIntDef(2);
        if (g_AppCfg.CngsContCnt < 1) g_AppCfg.CngsContCnt = 1;
        //1단 교통정보폼 중앙정렬 여부
        g_AppCfg.Traf1RowCenter = pIniFile->ReadString ("APPLICATION", "Traffic1RowCenter", "0").ToIntDef(0) == 1 ? true : false;
        g_AppCfg.IsImageSeqSave = pIniFile->ReadString ("APPLICATION", "IMAGESEQSAVE",      "0").ToIntDef(0) == 1 ? true : false;


        g_AppCfg.comm.nConnectWait  = pIniFile->ReadInteger("COMMUNICATION", "CONNECTWAIT",  60);
        g_AppCfg.comm.nCmdTimeOut   = pIniFile->ReadInteger("COMMUNICATION", "CMDTIMEOUT",   5);
        g_AppCfg.comm.nWatchDogTime = pIniFile->ReadInteger("COMMUNICATION", "WATCHDOGTIME", 30);
        g_AppCfg.comm.nPollingTime  = pIniFile->ReadInteger("COMMUNICATION", "POLLINGTIME",  20);
        g_AppCfg.IsIpChecking       = pIniFile->ReadString ("COMMUNICATION", "IPCHECKING",  "1").ToIntDef(0) == 1 ? true : false;

        if (g_AppCfg.comm.nPollingTime < 10) g_AppCfg.comm.nPollingTime = 10;
        if (g_AppCfg.comm.nPollingTime > 90) g_AppCfg.comm.nPollingTime = 90;

        if (g_AppCfg.comm.nConnectWait  < 30) g_AppCfg.comm.nConnectWait  = 30;
        if (g_AppCfg.comm.nConnectWait  > 60) g_AppCfg.comm.nConnectWait  = 60;
        if (g_AppCfg.comm.nCmdTimeOut   <  5) g_AppCfg.comm.nCmdTimeOut   =  5;
        if (g_AppCfg.comm.nWatchDogTime < 30) g_AppCfg.comm.nWatchDogTime = 30;
        g_AppCfg.comm.nWatchDogTime += 5;   // 5초정도를 더 추가해 준다(딜레이발생할 경우)


        g_AppCfg.BottomTrafficCycle  = pIniFile->ReadString("FIGURE", "TRAFFIC_CYCLE",  "0").ToIntDef(0);
        g_AppCfg.BottomTrafficMaxCnt = pIniFile->ReadString("FIGURE", "TRAFFIC_MAX",    "1").ToIntDef(0);
        g_AppCfg.BottomTrafficCenter = pIniFile->ReadString("FIGURE", "TRAFFIC_CENTER", "1").ToIntDef(0) == 1 ? true : false;
        if (g_AppCfg.BottomTrafficCycle != 0)
        {
            if (g_AppCfg.BottomTrafficCycle < 3)
            {
                g_AppCfg.BottomTrafficCycle = 3;    //하단소통정보 표출하는 경우 3초보다 작으면 최소 3초로 설정한다.
            }
        }

        FIGURE.GRADE0 = pIniFile->ReadString("FIGURE", "0", "-").Trim();
        FIGURE.GRADE1 = pIniFile->ReadString("FIGURE", "1", "월활").Trim();
        FIGURE.GRADE2 = pIniFile->ReadString("FIGURE", "2", "지체").Trim();
        FIGURE.GRADE3 = pIniFile->ReadString("FIGURE", "3", "정체").Trim();

        TEXT.GRADE0 = pIniFile->ReadString("TEXT", "0", "-").Trim();
        TEXT.GRADE1 = pIniFile->ReadString("TEXT", "1", "소통원활").Trim();
        TEXT.GRADE2 = pIniFile->ReadString("TEXT", "2", "지 체").Trim();
        TEXT.GRADE3 = pIniFile->ReadString("TEXT", "3", "정 체").Trim();
    }
    __finally
    {
        if (pIniFile) delete pIniFile;
        pIniFile = NULL;
    }

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

/*
 * 응용프로그램이 중복으로 실행되는 것을 막기위해 뮤텍스를 생성한다.
 */
bool APP_ApplicationSingleInstance(AnsiString AProgName, AnsiString APidFile)
{
    bool       isRunning = false;
    HANDLE     hMutex = 0;
	AnsiString sMutexName;

	sMutexName = "Global\\" + AProgName;

	hMutex = CreateMutex(NULL, TRUE, sMutexName.c_str());
    if (hMutex && GetLastError() == ERROR_ALREADY_EXISTS)
    {
        char buffer[1000];

        ReleaseMutex(hMutex);
        hMutex=0;
        isRunning = true;

        ////////////////////////////////////////////////////////////////////////////

        AnsiString fn;
        char tmp[500];

        if (FileExists(APidFile))
        {
            TFileStream *fp = new TFileStream(APidFile, fmOpenRead);
            HWND hwnd;
            AnsiString nfo;

            memset(buffer, 0, 1000);
            fp->Read(buffer, 100);
            delete fp;

            hwnd = (HWND)(String(buffer).ToIntDef(0));
            if (hwnd)
            {
                SendMessage(hwnd, WM_USER, WM_WINDOW_RESTORE, 0);
            }
        }
    }

    if (hMutex)
    {
        ReleaseMutex(hMutex);
        hMutex=0;
    }

    return isRunning;
}
//---------------------------------------------------------------------------

/*
 * 환경설정 정보를 저장하는 함수.
 */
bool APP_WriteConfigInfo(String ASection, String AItem, String AValue, String ACfgFile/*=""*/)
{
	String	  sConfigFile;
	TIniFile *pIniFile = NULL;

    sConfigFile = ACfgFile;

    try
    {
        pIniFile = new TIniFile(sConfigFile);
        if (pIniFile == NULL)
        {
            return false;
        }

        pIniFile->WriteString(ASection, AItem, AValue);
    }
    catch(...)
    {
    }

    if (pIniFile)
    {
        pIniFile->Free();
        pIniFile = NULL;
    }

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

/*
 * 환경설정 정보를 읽어오는 함수.
 */
bool APP_ReadConfigInfo(String ASection, String AItem, String &AValue, String ACfgFile/*=""*/)
{
    bool      bRes;
	String    sConfigFile;
	TIniFile *pIniFile = NULL;

    bRes = false;
    sConfigFile = ACfgFile;

    try
    {
        pIniFile = new TIniFile(sConfigFile);
        if (pIniFile == NULL)
        {
            return bRes;
        }

        AValue = pIniFile->ReadString(ASection, AItem, "");
        if (AValue != "")
        {
            bRes = true;
        }
    }
    catch(...)
    {
    }

    if (pIniFile)
    {
        pIniFile->Free();
        pIniFile = NULL;
    }

	return bRes;
}
//---------------------------------------------------------------------------

/*
 * 시스템오류 메시지를 얻는다.
 */
String APP_GetSysError()
{
    AnsiString sErrMsg  = "";
    LPVOID     lpMsgBuf = NULL;

    try
    {
        try
        {
            FormatMessage(
                FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
                NULL,
                GetLastError(),
                //MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
                (LPTSTR) &lpMsgBuf,
                0,
                NULL
            );

            char *pData = (char*)lpMsgBuf;
            if (strlen(pData) > 2)
            {
                pData[strlen(pData)-2] = 0x00;
                pData[strlen(pData)-1] = 0x00;
            }
            sErrMsg = AnsiString(pData);
        }
        __finally
        {
            if (lpMsgBuf) LocalFree(lpMsgBuf);
            lpMsgBuf = NULL;
        }
    }
    catch(Exception &e)
    {
    }
    return sErrMsg;
}
//---------------------------------------------------------------------------

