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

#include <vcl.h>
#include "AppGlobalF.h"
#include "ITSSkinF.h"
#include "ITSUtilF.h"
#include "ITSLangTransF.h"
#include "ITSMapF.h"
#pragma hdrstop

#include "FRAME_OpenMapF.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "cxButtons"
#pragma link "cxCheckBox"
#pragma link "cxContainer"
#pragma link "cxControls"
#pragma link "cxEdit"
#pragma link "cxGraphics"
#pragma link "cxLabel"
#pragma link "cxLookAndFeelPainters"
#pragma link "cxLookAndFeels"
#pragma link "cxTextEdit"
#pragma link "dxSkinBlue"
#pragma link "dxSkinsCore"
#pragma link "dxSkinBlack"
#pragma link "dxSkinCaramel"
#pragma link "dxSkinCoffee"
#pragma link "dxSkinDarkRoom"
#pragma link "dxSkinDarkSide"
#pragma link "dxSkinFoggy"
#pragma link "dxSkinGlassOceans"
#pragma link "dxSkiniMaginary"
#pragma link "dxSkinLilian"
#pragma link "dxSkinLiquidSky"
#pragma link "dxSkinLondonLiquidSky"
#pragma link "dxSkinMcSkin"
#pragma link "dxSkinMoneyTwins"
#pragma link "dxSkinOffice2007Black"
#pragma link "dxSkinOffice2007Blue"
#pragma link "dxSkinOffice2007Green"
#pragma link "dxSkinOffice2007Pink"
#pragma link "dxSkinOffice2007Silver"
#pragma link "dxSkinOffice2010Black"
#pragma link "dxSkinOffice2010Blue"
#pragma link "dxSkinOffice2010Silver"
#pragma link "dxSkinSeven"
#pragma link "dxSkinSharp"
#pragma link "dxSkinSilver"
#pragma link "dxSkinStardust"
#pragma resource "*.dfm"
//TFRAMEOpenMap *FRAMEOpenMap;
//---------------------------------------------------------------------------
__fastcall TFRAMEOpenMap::TFRAMEOpenMap(TComponent* Owner)
    : TFrame(Owner), MapCallbackFunc(NULL)
{
    LangTrans->Translate(this, ITSDb_GetConnection());
    ITSSkin_Load((TForm*)this);
    LoadLocalSkin();

    fJSExec = new TJSExec(WebBrowser1);
    reMsg->Lines->Clear();

    FLayerIdx = 0;
    FMapStart = false;
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::LoadLocalSkin()
{
}
//---------------------------------------------------------------------------

void __fastcall TFRAMEOpenMap::OpenMap()
{
    TmrMapOpen->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::TmrMapOpenTimer(TObject *Sender)
{
    TmrMapOpen->Enabled = false;
    LoadMap();
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::LoadMap()
{
    FHtmlFileName = "";
    try {
        FHtmlFileName = ITSMap_MapOpen(g_sMapDir, g_nMapSource);
        if (FHtmlFileName != "")
        {
#if 0
            //reMsg->Lines->Add(FHtmlFileName);
            WebBrowser1->Navigate(FHtmlFileName.c_str());
#else
            TStringList        *pStringList        = NULL;
            TMemoryStream      *mstm               = NULL;
            TStreamAdapter     *stmadt             = NULL;
            IPersistStreamInit *pPersistStreamInit = NULL;
            String              sHtml              = "";

            try {
                try {
                    pStringList = new TStringList();
                    pStringList->LoadFromFile(FHtmlFileName);

                    sHtml = pStringList->Text;
                    if (g_GisInfo.sApiKey != "")
                    {
                        sHtml = StringReplace(sHtml, "MAP_API_KEY", g_GisInfo.sApiKey, TReplaceFlags() << rfReplaceAll);
                    }
#if 0
                    sHtml = StringReplace(sHtml, "INIT_ZOOM",   g_AppCfg.map.InitZoom, TReplaceFlags() << rfReplaceAll);
                    sHtml = StringReplace(sHtml, "MIN_ZOOM",    g_AppCfg.map.MinZoom,  TReplaceFlags() << rfReplaceAll);
                    sHtml = StringReplace(sHtml, "MAX_ZOOM",    g_AppCfg.map.MaxZoom,  TReplaceFlags() << rfReplaceAll);
                    sHtml = StringReplace(sHtml, "INIT_LAT",    g_AppCfg.map.InitLat,  TReplaceFlags() << rfReplaceAll);
                    sHtml = StringReplace(sHtml, "INIT_LNG",    g_AppCfg.map.InitLng,  TReplaceFlags() << rfReplaceAll);
#endif
                    sHtml.Trim();
                    pStringList->Text = sHtml;

                    //reMsg->Lines->Clear();
                    //reMsg->Lines->Add(sHtml);
                    if (DeleteFile(FHtmlFileName))
                    {
                        //FHtmlFileName = "";
                    }

                    if (!WebBrowser1->Document)
                    {
                        String sTmpUrl = "about:blank";
                        WebBrowser1->Navigate(sTmpUrl.c_str());
                        //WebBrowser1->Stop();
                        //WebBrowser1->Navigate("about:blank");
                        while(WebBrowser1->ReadyState != 4/*READYSTATE_COMPLETE*/)
                        {
                            Application->ProcessMessages();
                        }
                    }

                    mstm = new TMemoryStream();
                    pStringList->SaveToStream(mstm, TEncoding::Unicode);

                    mstm->Seek(0, soFromBeginning);

                    stmadt = new TStreamAdapter(mstm, soReference);
                    if (S_OK == WebBrowser1->Document->QueryInterface(IID_IPersistStreamInit, (void**)&pPersistStreamInit))
                    {
                        pPersistStreamInit->Load(*stmadt);
                        pPersistStreamInit->Release();
                        pPersistStreamInit = NULL;
                    }
                }
                catch(Exception &exception)
                {
                }
            }
            __finally {
                SAFE_DELETE(pStringList);
                SAFE_DELETE(mstm);
                //SAFE_DELETE(stmadt);
                if (DeleteFile(FHtmlFileName))
                {
                    FHtmlFileName = "";
                }
            }
#endif
        }
    } catch(...) {}
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::OnCloseQuery(bool &CanClose)
{
    try
    {
        if (fJSExec)
        {
            fJSExec->Free();
        }
        if (FHtmlFileName != "")
        {
            if (FileExists(FHtmlFileName))
            {
                if (DeleteFile(FHtmlFileName))
                {
                    FHtmlFileName = "";
                }
            }
        }
    }
    catch(Exception &exception)
    {
    }
}
//---------------------------------------------------------------------------
bool __fastcall TFRAMEOpenMap::ExecScript(String AScript)
{
    if (FMapStart == false) return false;

    try
    {
        fJSExec->RunJSFn(AScript);
    }
    catch(Exception &exception)
    {
        WriteLog("ExecScript: [%s]", AnsiString(exception.ClassName()+exception.Message).c_str());
        return false;
    }
    return true;
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::SelectObjectByPos(double dPosX, double dPosY, bool bArrow/*=false*/)
{
    if (FMapStart == false) return;
    String sJs;
    sJs.printf(L"selectPos(0, '%.7f', '%.7f')", dPosX, dPosY);
    ExecScript(sJs);
}
//---------------------------------------------------------------------------
bool __fastcall TFRAMEOpenMap::SelectLinkByPos(int X, int Y, String &ALinkId)
{
    return false;
}
//---------------------------------------------------------------------------
bool __fastcall TFRAMEOpenMap::GetLevelLinkId(int ALinkLevel, String &sLinkId, int X, int Y)
{
    return false;
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::SelGisItem(int AType, String AId)
{
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::WebBrowser1DownloadComplete(TObject *Sender)
{
	// 웹페이지 스크롤바 없애기
#if 0
    try
    {
        Variant vBody;
        Variant vObj = WebBrowser1->OleObject;
        String strDocCompatMode = vObj.OlePropertyGet("document").OlePropertyGet("compatMode");
        if (SameText(strDocCompatMode, "CSS1Compat"))
            vBody = vObj.OlePropertyGet("Document").OlePropertyGet("documentElement");
        else
            vBody = vObj.OlePropertyGet("Document").OlePropertyGet("body");

        vBody.OlePropertyGet("style").OlePropertySet("overflow", "hidden");
    }
    catch(Exception &e)
    {
    }
#endif
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnMapToJpgClick(TObject *Sender)
{
    // 지도 이미지 저장
    String sFileName = "";

    Application->ProcessMessages();
    SaveDialog1->FileName = Now().FormatString("YYYYMMDDHHNNSS") + ".jpg";
    if (!SaveDialog1->Execute()) return;

    sFileName = SaveDialog1->FileName;
    if (sFileName == "")
    {
        return ;
    }

    ShowCursor(false);

    POINT oldCursorPos;
    GetCursorPos(&oldCursorPos);
    SetCursorPos(-1, -1);

    Application->ProcessMessages();

    HDC dc;
    RECT r;

    try
    {
        GetWindowRect(WebBrowser1->Handle, &r);

        dc = GetWindowDC(Handle);
        Graphics::TCanvas *MyCanvas = new Graphics::TCanvas;
        MyCanvas->Handle = dc;


        int nIW;
        int nIH;
        nIW = (r.right - r.left);
        nIH = (r.bottom - r.top);

        Image1->Width = nIW;
        Image1->Height = nIH;
        Image1->Picture->Bitmap->Width = nIW;
        Image1->Picture->Bitmap->Height = nIH;
        Image1->Picture->Bitmap->Canvas->CopyMode = cmSrcCopy;

        Image1->Picture->Bitmap->Canvas->CopyRect
        (
            TRect(0,0, Image1->Width, Image1->Height),
            MyCanvas,
            TRect(0,0,Image1->Width,Image1->Height)
        );
        delete MyCanvas;
        ReleaseDC(NULL,dc);

        TJPEGImage *jpeg = new TJPEGImage ();
        try
        {
            jpeg->Assign(Image1->Picture->Bitmap);
            jpeg->SaveToFile(sFileName);
        }
        __finally
        {
            delete jpeg;
            Image1->Picture->Bitmap->FreeImage();
        }
    }
    catch(Exception &e)
    {
    }

    ShowCursor(true);
    SetCursorPos(oldCursorPos.x, oldCursorPos.y);

    String sMsg;
    //sMsg = "The image file is saved.\r\n";
    sMsg = "이미지 파일을 저장하였습니다.\r\n";
    sMsg += sFileName;
    ShowMessage(sMsg);
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnMoveMapToFitClick(TObject *Sender)
{
    // 지도객체영역을 전체영역으로
    String sJs;
    sJs.printf(L"extentLayer(%d)", FLayerIdx);
    ExecScript(sJs);
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnMoveDefBoundsClick(TObject *Sender)
{
    // 지도 기본영역으로 이동
    ExecScript("stdExtent()");
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnZoomInClick(TObject *Sender)
{
    // 지도 확대
    ExecScript("zoomIn()");
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnZoomOutClick(TObject *Sender)
{
    // 지도 축소
    ExecScript("zoomOut()");
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnZoomPrevClick(TObject *Sender)
{
    // 지도 이전영역 이동
    ExecScript("mapPrev()");
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnZoomNextClick(TObject *Sender)
{
    // 지도 다음영역 이동
    ExecScript("mapNext()");
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnRefreshClick(TObject *Sender)
{
    // 지도 새로고침
    ExecScript("refreshMap()");
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::ChkShowNmbrClick(TObject *Sender)
{
    String sJs;
    sJs.printf(L"showLayerText(%d, %d)", FLayerIdx, (ChkShowNmbr->Checked) ? 1: 0);
    ExecScript(sJs);
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnMapClickClick(TObject *Sender)
{
    String sJs;
    sJs.printf(L"setMouseClick(%d)", (BtnMapClick->SpeedButtonOptions->Down) ? 1: 0);
    ExecScript(sJs);
    EdMapPos->Visible = BtnMapClick->SpeedButtonOptions->Down;
    EdMapPos->Text = "";
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::PnlGisToolDblClick(TObject *Sender)
{
    if (EdMapPos->Visible)
    {
        ExecScript("setMouseClick(0)");
    }
    else
    {
        ExecScript("setMouseClick(1)");
    }
    EdMapPos->Visible = !EdMapPos->Visible;
    EdMapPos->Text = "";
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::BtnMapSelectClick(TObject *Sender)
{
//
}
//---------------------------------------------------------------------------
void __fastcall TFRAMEOpenMap::WebBrowser1BeforeNavigate2(TObject *ASender, const IDispatch *pDisp, OleVariant &URL, OleVariant &Flags,
          OleVariant &TargetFrameName, OleVariant &PostData, OleVariant &Headers, WordBool &Cancel)
{
    bool bFirst  = false;
    bool bCancel = false;
    String sUrl, sFunc, sArgs;

    try
    {
        sUrl = URL.operator UnicodeString();
        URL.VOleStr = NULL;

        int nFuncIdx = sUrl.Pos(":");
        sFunc = sUrl.SubString(0,          nFuncIdx-1).LowerCase();
        //sArgs = sUrl.SubString(nFuncIdx+1, sUrl.Length()).LowerCase();
        sArgs = sUrl.SubString(nFuncIdx+1, sUrl.Length());

        WriteLog("mapEvent: %s, %s", AnsiString(sFunc).c_str(), AnsiString(sArgs).c_str());
        Application->ProcessMessages();
        if (nFuncIdx > 0 && sFunc.Pos("onmap"))
        {
            TStringList *pStringList = new TStringList;
            pStringList->CommaText = sArgs;

            try
            {
                String sZoom      = pStringList->Strings[0];
                String sCenterLat = pStringList->Strings[1];
                String sCenterLng = pStringList->Strings[2];

                FMapZoom = sZoom.ToIntDef(0);
                FCenterX = sCenterLat.ToDouble();
                FCenterY = sCenterLng.ToDouble();
                LblZoom->Caption = "Zoom: " + sZoom;
            }
            catch(Exception &e)
            {
            }
            delete pStringList;

            try
            {
                if (FHtmlFileName != "")
                {
                    if (FileExists(FHtmlFileName))
                    {
                        if (DeleteFile(FHtmlFileName))
                        {
                            FHtmlFileName = "";
                        }
                    }
                }
            }
            catch(Exception &e) {}

            if (sFunc == "onmapinit")
            {
                FMapStart = true;
                String sJs;
                sJs.printf(L"setMapInfo('%.7f', '%.7f', %d, %d, %d, %d, '%s', '%s')",
                          g_GisInfo.dCenterX, g_GisInfo.dCenterY, g_GisInfo.nZoomLevel, g_GisInfo.nMinZoom, g_GisInfo.nMaxZoom, g_GisInfo.mapType,
                          g_GisInfo.imagePath.c_str(), g_GisInfo.mapUrl.c_str());
                ExecScript(sJs);

                ExecScript("DoMap()");
                Cancel = true;
                return;
            }
            else
            if (sFunc == "onmapzoomchanged")
            {
            }
            else
            if (sFunc == "onmapdragstart")
            {
            }
            else
            if (sFunc == "onmapdragend")
            {
            }
            else
            if (sFunc == "onmapcompleted")
            {
                FMapStart = true;
                PnlToolbar->Enabled = true;
                bFirst = true;
            }
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onchangedmaptype"))
        {
            bCancel = true;
            TStringList *pStringList = new TStringList;
            pStringList->CommaText = sArgs;

            try
            {
                String sMapType = pStringList->Strings[0];
                g_GisInfo.mapType = sMapType.ToIntDef(1);
                WriteConfigInfo(g_AppCfg.sConfigFile, "MAP", "MAPTYPE", String(g_GisInfo.mapType));
            }
            catch(Exception &e)
            {
            }
            delete pStringList;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onmouseclick"))
        {
            bCancel = true;
            EdMapPos->Text = sArgs;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onfacilityclick"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onfacilityrightclick"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onfacilitydragstart"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onfacilitydragmove"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onfacilitydragend"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onlinkclick"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onlinkrightclick"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("ondebug"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onlayervisiblechanged"))
        {
            bCancel = true;
        }
        else
        if (nFuncIdx > 0 && sFunc.Pos("onextentmap"))
        {
            bCancel = true;
        }
    }
    catch(Exception &e)
    {
    }
    Cancel = bCancel;

    try
    {
        if (bCancel && MapCallbackFunc)
        {
            MapCallbackFunc(ASender, sFunc, sArgs, bFirst);
        }
    }
    catch(Exception &exception) {}

}
//---------------------------------------------------------------------------
void TFRAMEOpenMap::WriteLog(char *AFmt, ...)
{
    if (!reMsg->Visible) return;

    va_list ap;
    int     cnt;
    char    szFmtData[2048];

    try
    {
        va_start(ap, AFmt);
        cnt = vsprintf(szFmtData, AFmt, ap);
        va_end(ap);

        reMsg->Lines->Add(Now().FormatString("nn:ss.zzz") + ", " + String(szFmtData));
    }
    catch(Exception &exception)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TFRAMEOpenMap::LblZoomDblClick(TObject *Sender)
{
    reMsg->Visible = !reMsg->Visible;
}
//---------------------------------------------------------------------------

void __fastcall TFRAMEOpenMap::reMsgDblClick(TObject *Sender)
{
    reMsg->Lines->Clear();
}
//---------------------------------------------------------------------------

