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

#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 sTmp;
    String sCfgFile;

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

    DATABASE_INFO *pDb;
    TIniFile      *pIniFile = new TIniFile(sCfgFile);

    try
    {
        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").ToIntDef(30101);
        g_AppCfg.nProcessPort = pIniFile->ReadString("APPLICATION", "PROCESSPORT",  "5301").ToIntDef(5301);
        g_AppCfg.nProcessId   = g_AppCfg.sProcessId.ToIntDef(0);

        g_AppCfg.nTrafficCycleTime = pIniFile->ReadString("APPLICATION", "TrafficCycleTime", "300").ToIntDef(300);
        g_AppCfg.nTrafficBasisTime = pIniFile->ReadString("APPLICATION", "TrafficBasisTime",  "20").ToIntDef(20);
        if (g_AppCfg.nTrafficCycleTime < 60) g_AppCfg.nTrafficCycleTime = 60;

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

        g_AppCfg.IsDbConnectPerJob = (pIniFile->ReadString("APPLICATION", "CONNECTPERJOB", "false").UpperCase() == "TRUE") ? true : false;

        g_AppCfg.comm.nCenterPort  = pIniFile->ReadString("COMMUNICATION", "CENTERPORT",  "6020").ToIntDef(6020);
        g_AppCfg.comm.nListenPort  = pIniFile->ReadString("COMMUNICATION", "LISTENPORT",  "6020").ToIntDef(6020);
        g_AppCfg.comm.nClientPort  = pIniFile->ReadString("COMMUNICATION", "CLIENTPORT",   "355").ToIntDef(355);
        g_AppCfg.comm.sLocalDomain = pIniFile->ReadString("COMMUNICATION", "LOCALDOMAIN", "VMS_SERVER");
        g_AppCfg.comm.sLoginUser   = pIniFile->ReadString("COMMUNICATION", "LOGINUSER",   "ysvms");


        pDb = &g_AppCfg.db;
        pDb->sConnectStr = pIniFile->ReadString("DATABASE", "CONNECTSTR", "");
        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",   "");
        if (pDb->sConnectStr == "")
        {
            pDb->MakeConnString();
        }

        g_AppCfg.nMaxLogLines = pIniFile->ReadString("LOG", "LOGLINE", "200").ToIntDef(200);
        g_AppCfg.sLogDay      = pIniFile->ReadString("LOG", "LOGDAY",  "");
        if (g_AppCfg.nMaxLogLines > 1000) g_AppCfg.nMaxLogLines = 1000;
        if (g_AppCfg.nMaxLogLines < 100)  g_AppCfg.nMaxLogLines = 100;

        g_LogCfg.Info    = pIniFile->ReadString("LOG", "INFO",    "1").ToIntDef(1) == 1 ? true : false;
        g_LogCfg.Data    = pIniFile->ReadString("LOG", "DATA",    "0").ToIntDef(1) == 1 ? true : false;
        g_LogCfg.Error   = pIniFile->ReadString("LOG", "ERROR",   "1").ToIntDef(1) == 1 ? true : false;
        g_LogCfg.Warning = pIniFile->ReadString("LOG", "WARNING", "1").ToIntDef(1) == 1 ? true : false;
        g_LogCfg.Debug   = pIniFile->ReadString("LOG", "DEBUG",   "0").ToIntDef(1) == 1 ? true : false;
        g_LogCfg.Detail  = pIniFile->ReadString("LOG", "DETAIL",  "0").ToIntDef(1) == 1 ? true : false;
        g_LogCfg.Detail  = false;


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

    return APP_ReLoadConfigInfo();
}
//---------------------------------------------------------------------------
bool APP_ReLoadConfigInfo()
{
    String    sTmp;
    TIniFile *pIniFile = new TIniFile(g_AppCfg.sConfigFile);

    try
    {
        LOAD_DB                    = pIniFile->ReadString("APPLICATION", "LOADDB",           "1").ToIntDef(1) == 1 ? true : false;
        g_AppCfg.DownloadBitmap    = pIniFile->ReadString("APPLICATION", "DOWNLOADBITMAP",   "0").ToIntDef(0) == 1 ? true : false;
        g_AppCfg.nSaveFormType     = pIniFile->ReadString("APPLICATION", "SaveFormType",     "0").ToIntDef(0);
        g_AppCfg.nDefaultFillColor = pIniFile->ReadString("APPLICATION", "DefaultFillColor", "0").ToIntDef(0);
        if (g_AppCfg.nSaveFormType < 0 || g_AppCfg.nSaveFormType > 2) g_AppCfg.nSaveFormType = 0;

        g_AppCfg.IsDbConnectPerJob = (pIniFile->ReadString("APPLICATION", "CONNECTPERJOB", "false").UpperCase() == "TRUE") ? true : false;

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

        g_AppCfg.IsCheckNewForm = pIniFile->ReadString ("APPLICATION", "CheckNewForm", "1").ToIntDef(1) == 1 ? true : false;
        g_AppCfg.PixelValue     = pIniFile->ReadString ("APPLICATION", "PixelValue",   "0").ToIntDef(0);
        if (g_AppCfg.PixelValue <   0) g_AppCfg.PixelValue = 0;
        if (g_AppCfg.PixelValue > 254) g_AppCfg.PixelValue = 254;

        int nPixelFormat = pIniFile->ReadString ("APPLICATION", "BitmapFormat", "24").ToIntDef(24);
        switch(nPixelFormat)
        {
        case  4: g_AppCfg.PixelFormat = pf4bit;  break;
        case  8: g_AppCfg.PixelFormat = pf8bit;  break;
        case 16: g_AppCfg.PixelFormat = pf16bit; break;
        case 24: g_AppCfg.PixelFormat = pf24bit; break;
        case 32: g_AppCfg.PixelFormat = pf32bit; break;
        default: g_AppCfg.PixelFormat = pf24bit; break;
        }

        g_AppCfg.MaxMemory = pIniFile->ReadString("RESOURCE", "MAXMEMORY",  "512").ToIntDef(512);
        g_AppCfg.MaxHandle = pIniFile->ReadString("RESOURCE", "MAXHANDLE",    "0").ToIntDef(0);
        g_AppCfg.MaxThread = pIniFile->ReadString("RESOURCE", "MAXTHREAD", "4096").ToIntDef(4096);
        g_AppCfg.MaxGdi    = pIniFile->ReadString("RESOURCE", "MAXGDI",       "0").ToIntDef(0);
        g_AppCfg.RcRestart = pIniFile->ReadString("RESOURCE", "RESTART",      "0").ToIntDef(0) == 1 ? true : false;


        g_AppCfg.comm.nConnectWait  = pIniFile->ReadString("COMMUNICATION", "CONNECTWAIT",  "60").ToIntDef(60);
        g_AppCfg.comm.nCmdTimeOut   = pIniFile->ReadString("COMMUNICATION", "CMDTIMEOUT",    "5").ToIntDef(5);
        g_AppCfg.comm.nWatchDogTime = pIniFile->ReadString("COMMUNICATION", "WATCHDOGTIME", "30").ToIntDef(30);
        g_AppCfg.comm.nPollingTime  = pIniFile->ReadString("COMMUNICATION", "POLLINGTIME",  "20").ToIntDef(20);
        g_AppCfg.IsIpChecking       = pIniFile->ReadString("COMMUNICATION", "IPCHECKING",    "1").ToIntDef(1) == 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(1);
        g_AppCfg.BottomTrafficCenter = pIniFile->ReadString("FIGURE", "TRAFFIC_CENTER", "1").ToIntDef(1) == 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();

        g_AppCfg.TextTrafficCenter = pIniFile->ReadString("TEXT", "TRAFFIC_CENTER", "1").ToIntDef(1) == 1 ? true : false;
        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;

    if (ACfgFile == "")
        sConfigFile = g_AppCfg.sConfigFile;
    else
        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;
    if (ACfgFile == "")
        sConfigFile = g_AppCfg.sConfigFile;
    else
        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;
}
//---------------------------------------------------------------------------

