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

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

#include "FrmFullScreenF.h"
#include "FrmStreamPlayerF.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "FFBaseComponent"
#pragma link "FFBasePlay"
#pragma link "FFPlay"
#pragma link "cxContainer"
#pragma link "cxControls"
#pragma link "cxEdit"
#pragma link "cxGraphics"
#pragma link "cxLabel"
#pragma link "cxLookAndFeelPainters"
#pragma link "cxLookAndFeels"
#pragma link "dxSkinBlack"
#pragma link "dxSkinBlue"
#pragma link "dxSkinsCore"
#pragma link "dxSkinMcSkin"
#pragma link "AcesTechXPlayer2Lib_OCX"
#pragma resource "*.dfm"

#define LICENSE_KEY "FSXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX-XXXXXXXX"

#define FFPLAY  0
#define ACES    1

//TFrmStreamPlayer *FrmStreamPlayer;
//---------------------------------------------------------------------------
__fastcall TFrmStreamPlayer::TFrmStreamPlayer(TComponent* Owner)
    : TForm(Owner)
{
    LangTrans->Translate(this, ITSDb_GetConnection());

    FObj.Installed = false;
    FObj.Data      = NULL;

    PnlBlob->Visible = false;
    PnlBlob->Align = alClient;
    FDispBlob = false;

    FPlay = false;
    FAutoPlay = true;
    FConHandle = 0;

    FFullScreen = false;
    InitCamera(NULL, FAutoPlay);

    FParent = this->Parent;
    PnlStream->Tag = (int)this;
#if FFPLAY
    AcesTechXPlayer21->Visible = false;
#endif
}
//---------------------------------------------------------------------------
void __fastcall TFrmStreamPlayer::TmrShowTimer(TObject *Sender)
{
    TmrShow->Enabled = false;
    if (FObj.Installed)
    {
        Caption = FObj.ID + ": " + FObj.NAME;
        if (FDispBlob == false)
        {
            Connect();
        }
    }
}
//---------------------------------------------------------------------------
void __fastcall TFrmStreamPlayer::FormShow(TObject *Sender)
{
    if (FObj.Installed) PnlStream->Caption = FObj.NAME;
    else                PnlStream->Caption = "";

    Refresh();
    this->FLastBounds = this->BoundsRect;

    RefreshPlayer();

    if (PnlStream->Visible)
    {
#if FFPLAY
        FFPlayer1->SetLicenseKey(LICENSE_KEY);
        FFPlayer1->DisableFPUExceptions();

        if (!FFPlayer1->AVLibLoaded())
        {
            String sAVILibDir = g_sAppDir + "LibAV";
            if (!FFPlayer1->LoadAVLib(sAVILibDir))
            {
                Application->MessageBox(lblErr1->Caption.c_str(),//L"영상표출 라이브러리를 로드하지 못하였습니다.",
                                        lblErr2->Caption.c_str(),//L"영상표출 오류",
                                        MB_OK|MB_ICONERROR|MB_APPLMODAL);
                return;
            }
        }
#endif
    }

    TmrShow->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::FormClose(TObject *Sender, TCloseAction &Action)
{
    try {
        Disconnect();
        if (FObj.Data) FObj.Data->FData1 = NULL;
    } catch(...) {}

    Action = caFree;
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::FormDestroy(TObject *Sender)
{
    try {
        Disconnect();
        if (FObj.Data) FObj.Data->FData1 = NULL;
    } catch(...) {}
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::RefreshPlayer()
{
    FDispBlob = false;
    PnlBlob->Visible = false;

    if (FObj.Installed == false) return;

    String sQry;

    //CCTV영상인 경우 대체영상 표출 여부 확인
    if (FObj.FCLT_TYPE == "CCTV")
    {
        sQry = "SELECT CCTV_SBST_DSPL_YN, CCTV_SBST_IMGN \r\n"
               "  FROM TB_CCTV_CTLR                      \r\n"
               " WHERE CCTV_CTLR_ID = :p01               \r\n";
    }
    else
    {
        FDispBlob = false;
        PnlBlob->Visible = false;
        PnlStream->Visible = true;

        return;
    }

    try
    {
        pADO->Close();
        pADO->SQL->Clear();
        pADO->Connection = ITSDb_GetConnection();
        pADO->SQL->Text = sQry;
        pADO->Parameters->ParamByName("p01")->Value = FObj.ID;
        pADO->Prepared = true;
        pADO->Open();
    }
    catch(EDatabaseError &E)
    {
        PnlBlob->Caption = lblErr3->Caption;//"대체영상 이미지 정보 읽기 실패";
        ShowMessage(String(E.ClassName()) + E.Message);
        return;
    }

    if (pADO->RecordCount == 0)
    {
        pADO->Close();
        return;
    }

    ForceDirectories(g_sTempDir);

    TADOBlobStream *BS;
    int             nFileSize = 0;
    String          sImgFile  = g_sTempDir + "CCTVB_" + FObj.ID + ".bmp";

    try {
        DeleteFile(sImgFile);
    } catch(...) {}

    String sDispBlob = "N";
    try
    {
        sDispBlob = pADO->FieldByName("CCTV_SBST_DSPL_YN")->AsString;
        if (sDispBlob == "Y")
        {
            BS = (TADOBlobStream *)pADO->CreateBlobStream(pADO->FieldByName("CCTV_SBST_IMGN"), bmRead);
            //ImgBlob->Picture->Graphic->LoadFromStream(BS);
            BS->SaveToFile(sImgFile);
            nFileSize = BS->Size;
            delete BS;
        }
        pADO->Close();
    }
    catch(Exception &e)
    {
        delete BS;
        PnlBlob->Caption = lblErr4->Caption;//"대체영상 이미지 스트림 로딩 실패";
        return;
    }

    if (sDispBlob == "Y")
    {
        FDispBlob = true;
        PnlBlob->Visible = true;
        PnlStream->Visible = false;
        if (nFileSize)
        {
            try
            {
                ImgBlob->Picture->LoadFromFile(sImgFile);
                return;
            }
            catch(...)
            {
                ImgBlob->Visible = false;
                PnlBlob->Caption = lblErr5->Caption;//"대체영상 이미지 파일 로딩 실패";
                return;
            }
        }
        else
        {
            ImgBlob->Visible = false;
            PnlBlob->Caption = lblErr6->Caption;//"대체영상 이미지 사이즈 오류";
        }
    }
    else
    {
        FDispBlob = false;
        PnlBlob->Visible = false;
        PnlStream->Visible = true;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::MnuConnectClick(TObject *Sender)
{
    FAutoPlay = true;
    Connect();
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::MnuDisconnectClick(TObject *Sender)
{
    FAutoPlay = false;
    Disconnect();
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::Connect()
{
    Disconnect();

    PnlStream->Caption = FObj.STRM_ADDR;//"Connecting...";

    try
    {
#if FFPLAY
        FFPlayer1->AspectRatio = -1;
        FFPlayer1->TryOpen(FObj.STRM_ADDR, PnlStream->Handle);
        FConHandle = (long)FFPlayer1->ScreenHandle;
#endif
#if ACES
        AcesTechXPlayer21->URL = FObj.STRM_ADDR;
        FConHandle = AcesTechXPlayer21->ConnectAsync();
        if (FConHandle > 0)
        {
        }
#endif
Application->ProcessMessages();
    }
    catch(Exception &e)
    {
    }
    FPlay = true;
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::Disconnect()
{
    if (!FPlay) return;

    FPlay = false;
    PnlStream->Caption = "Disconnect";
    try
    {
#if FFPLAY
        if (FFPlayer1->ScreenHandle != NULL)
        {
            FFPlayer1->Stop(true);
            PostMessage(FFPlayer1->ScreenHandle, CM_INVALIDATE, 0, 0);
            UpdateWindow(FFPlayer1->ScreenHandle);
            FFPlayer1->ScreenHandle = NULL;
        }
#endif
#if ACES
        if (FConHandle > 0)
        {
            AcesTechXPlayer21->Close();
        }
#endif
Application->ProcessMessages();
        FConHandle = 0;
    }
    catch(Exception &e)
    {
    }

    PnlStream->Caption = "Disconnected";
    FConHandle = 0;
    FPlay = false;
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::InitCamera(void *ACctv, bool AAutoPlay/*=true*/)
{
    FAutoPlay = AAutoPlay;
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::MaxOrNormalForm(TForm *AForm, bool AMax)
{
    if (AMax)
    {
        //this->FParent = this->Parent;
        //AForm->Parent = FrmMain;    //Application->MainForm;
        this->FLastBounds = AForm->BoundsRect;
        AForm->BorderStyle = bsNone;
        AForm->FormStyle = fsStayOnTop;
        AForm->BoundsRect = AForm->Monitor->BoundsRect;
        PnlStream->Align = alClient;
#if 0
        ShowMessage(String(AForm->BoundsRect.Left)   + ", " +
                    String(AForm->BoundsRect.Top)    + ": " +
                    String(AForm->BoundsRect.Width()) + ", " +
                    String(AForm->BoundsRect.Height()) );
#endif
    }
    else
    {
        //AForm->Parent = this->FParent;
        AForm->FormStyle = fsNormal;
        AForm->BorderStyle = bsToolWindow;
        AForm->BoundsRect = this->FLastBounds;
        PnlStream->Align = alClient;
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::PnlStreamDblClick(TObject *Sender)
{
#if 0
    if (FFullScreen == false)
    {
        MaxOrNormalForm(this, true);
        FFullScreen = true;
    }
    else
    {
        MaxOrNormalForm(this, false);
        FFullScreen = false;
    }
#else
#if FFPLAY
    // 여기서 더블클릭은 최대화면을 호출하는 것임
    TFrmFullScreen *pFrmFullScreen = new TFrmFullScreen(this);
    pFrmFullScreen->BoundsRect = this->Monitor->BoundsRect;
    pFrmFullScreen->PnlStream->Align = alNone;
    pFrmFullScreen->PnlStream->Align = alClient;

    if (FObj.FULL_STRM_ADDR != "")
    {
        pFrmFullScreen->STRM_ADDR = FObj.FULL_STRM_ADDR;
    }
    else
    {
        pFrmFullScreen->STRM_ADDR = FObj.STRM_ADDR;
    }

    pFrmFullScreen->ShowModal();
    PnlStream->Parent = this;
    PnlStream->Tag = (int)this;

    delete pFrmFullScreen;
    pFrmFullScreen = NULL;
#endif
#endif

#if 0
    TForm *pForm = (TForm*)PnlStream->Tag;
    if (pForm == this)
    {
        TFrmFullScreen *pFrmFullScreen = new TFrmFullScreen(this);
        pFrmFullScreen->BoundsRect = this->Monitor->BoundsRect;
        pFrmFullScreen->PnlStream->Align = alNone;
        pFrmFullScreen->PnlStream->Align = alClient;

        pFrmFullScreen->STREAM_ADDR = FObj.STREAM_ADDR;
        PnlStream->Parent = pFrmFullScreen->PnlStream;
        PnlStream->Tag = (int)pFrmFullScreen;

        PnlStream->Align = alClient;

        pFrmFullScreen->ShowModal();
        FFPlayer1->ScreenHandle = PnlStream->Handle;
        PnlStream->Parent = this;
        PnlStream->Tag = (int)this;

        delete pFrmFullScreen;
        pFrmFullScreen = NULL;
    }
    else
    {
        PnlStream->Parent = this;
        PnlStream->Tag = (int)this;
        TFrmFullScreen *pFullForm = (TFrmFullScreen*)pForm;
        pFullForm->TmrClose->Enabled = true;
    }
#endif
}
//---------------------------------------------------------------------------

void __fastcall TFrmStreamPlayer::FFPlayer1State(TObject *Sender, TPlayState APlayState)
{
enum TPlayState { psPlay, psPause, psResume, psStep, psStop, psEnd };

    if (APlayState == Ffbasecomponent::psStop || APlayState == Ffbasecomponent::psEnd)
    {
        if (FPlay)
        {
            Caption = Caption + " : Disconnected";
            TmrShow->Enabled = true;
        }
    }
}
//---------------------------------------------------------------------------

