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

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

#include "VMSM430MF.h"

//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "cxButtons"
#pragma link "cxCalendar"
#pragma link "cxContainer"
#pragma link "cxControls"
#pragma link "cxDropDownEdit"
#pragma link "cxEdit"
#pragma link "cxGraphics"
#pragma link "cxGroupBox"
#pragma link "cxLabel"
#pragma link "cxLookAndFeelPainters"
#pragma link "cxLookAndFeels"
#pragma link "cxMaskEdit"
#pragma link "cxPC"
#pragma link "cxPCdxBarPopupMenu"
#pragma link "cxSpinEdit"
#pragma link "cxSplitter"
#pragma link "cxTextEdit"
#pragma link "cxTimeEdit"
#pragma link "dxSkinBlack"
#pragma link "dxSkinBlue"
#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 "dxSkinsCore"
#pragma link "dxSkinscxPCPainter"
#pragma link "dxSkinSeven"
#pragma link "dxSkinSharp"
#pragma link "dxSkinSilver"
#pragma link "dxSkinStardust"
#pragma link "cxRadioGroup"
#pragma link "cxClasses"
#pragma link "cxCustomData"
#pragma link "cxData"
#pragma link "cxDataStorage"
#pragma link "cxDBData"
#pragma link "cxFilter"
#pragma link "cxGrid"
#pragma link "cxGridCustomTableView"
#pragma link "cxGridCustomView"
#pragma link "cxGridDBTableView"
#pragma link "cxGridLevel"
#pragma link "cxGridTableView"
#pragma link "cxStyles"
#pragma link "cxCheckBox"
#pragma link "cxImage"
#pragma link "cxButtonEdit"
#pragma link "cxBlobEdit"
#pragma link "dxGDIPlusClasses"
#pragma link "FFBaseComponent"
#pragma link "FFBasePlay"
#pragma link "FFPlay"
#pragma link "FFDecode"
#pragma link "IdAntiFreeze"
#pragma link "IdAntiFreezeBase"
#pragma link "IdBaseComponent"
#pragma link "IdComponent"
#pragma link "IdExplicitTLSClientServerBase"
#pragma link "IdFTP"
#pragma link "IdTCPClient"
#pragma link "IdTCPConnection"
#pragma resource "*.dfm"

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

TVMSM430M *VMSM430M = NULL;
//---------------------------------------------------------------------------

__fastcall TVMSM430M::TVMSM430M(TComponent* Owner)
    : TForm(Owner)
{
    LangTrans->Translate(this, ITSDb_GetConnection());
    ITSSkin_Load(this);
    PnlVmsList->Visible = false;
    cxSplitter2->Visible = false;
    PnlSymbol->Align = alClient;

    CMM_LoadForm(g_sFormsDir, this);

    FUpdate= false;
    FTitle = Caption;//"VMS 심볼이미지 관리";

    //FRAMEVmsList1->Column02->Visible = false;
    FRAMEVmsList1->PnlTop->Visible = true;
    FRAMEVmsList1->PnlBottom->Visible = false;
    FRAMEVmsList1->ColumnSel->Visible = true;

    m_pGDC = FRAMEVmsList1->TvList->DataController;

	FListSymb = new TList;

    EditMode = false;

    TvList->OptionsView->DataRowHeight  = 0;
    TvList->OptionsView->CellAutoHeight = true;
    TvList->OptionsView->Indicator      = false;

    TvList->OptionsCustomize->ColumnMoving  = false;
    TvList->OptionsCustomize->ColumnSorting = false;

    TvList->Columns[0]->Width = 60;
    TvList->Columns[0]->Options->HorzSizing = false;

    //BtnSaveImgFile->Caption = "Save as image file";
    //BtnSaveImgFile->Hint = "Save as image file";

    FTrackBar[0]    = TrackBar1;
    FLblDuration[0] = lblDuration1;
    FLblCurrPTS[0]  = lblCurrentPTS1;
    FFPlayer[0]     = FFPlayer1;
    FDispArea[0]    = PnlPlayer;
    for (int ii = 0; ii < MAX_PLAYER; ii++)
    {
        FDispArea[ii]->Tag = ii;
        FDispArea[ii]->ParentColor = false;
        FDispArea[ii]->Color = clBlack;
        FDispArea[ii]->Caption = "";
        FDispArea[ii]->Refresh();
    }
    FThumbNail = 0;
    FMakeThumbNail = false;

    FFDecoder1->SetLicenseKey(LICENSE_KEY);
    String sAVILibDir = g_sAppDir + "LibAV";
    for (int ii = 0; ii < MAX_PLAYER; ii++)
    {
        FFPlayer[ii]->SetLicenseKey(LICENSE_KEY);
        FFPlayer[ii]->DisableFPUExceptions();

        if (!FFPlayer[ii]->LoadAVLib(sAVILibDir))
        {
            if (g_AppCfg.sLang != "kr") Application->MessageBox(L"Stream display library load failed.", L"Stream display fail", MB_OK|MB_ICONERROR|MB_APPLMODAL);
            else                        Application->MessageBox(L"영상표출 라이브러리를 로드하지 못하였습니다.", L"영상표출 오류", MB_OK|MB_ICONERROR|MB_APPLMODAL);
        }
    }
    FPlayStream = false;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::CommClose()
{
    try
    {
        ClearSymbloList();
        SAFE_DELETE(FListSymb);
        CMM_SaveForm(g_sFormsDir, this);
    }
    catch(...)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FormShow(TObject *Sender)
{
    Refresh();

    FormInit();
    ChangeEditMode(1);
    TmrShow->Enabled = true;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FormInit()
{
	EdNmbr->Text = "";
    EdExpl->Text = "";
    EdImageFileName->Text = "";

    ImgPreView->Picture->Bitmap->FreeImage();
    ImgPreView->Picture->Bitmap = NULL;

    FNewDb = false;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::TmrShowTimer(TObject *Sender)
{
    TmrShow->Enabled = false;

    FRAMEVmsList1->UpdateList();

    LoadImageSymbol();
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnCloseClick(TObject *Sender)
{
    Close();
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FormClose(TObject *Sender, TCloseAction &Action)
{
    CommClose();
    VMSM430M = NULL;
    Action = caFree;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FormCloseQuery(TObject *Sender, bool &CanClose)
{
    if (FUpdate)
    {
        POST_MSG(Application->MainForm->Handle, WM_DATABASE_REFRESH, WP_MSG_14, 0);
    }

    FRAMEVmsList1->OnCloseQuery(CanClose);
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::DisplayInfo()
{
    FormInit();

	int nRow = TvList->DataController->FocusedRecordIndex;
	if( nRow <= -1 )
		return;

	TcxGridDataController *pDc = TvList->DataController;

	nRow = pDc->FocusedRecordIndex;
    if (nRow < FListSymb->Count)
    {
        Graphics::TBitmap *bitmap = (Graphics::TBitmap*)FListSymb->Items[nRow];
        try
        {
            ImgPreView->Picture->Bitmap->Assign(bitmap);
        }
        catch(...)
        {
            ImgPreView->Picture->Bitmap->Assign(ImgTemp->Picture->Bitmap);
        }
    }

    EdNmbr->Text  = VarToStr(pDc->Values[nRow][ColLink1->Index]);
    EdExpl->Text  = VarToStr(pDc->Values[nRow][ColLink3->Index]);
    EdVmsCd->Text = VarToStr(pDc->Values[nRow][ColLink4->Index]);
    EdFileName->Text = VarToStr(pDc->Values[nRow][ColLink5->Index]);
    PlayerFile[0] = g_sVideoDir + EdFileName->Text;

    ChangeEditMode(3);
    BtnPlay->Enabled = true;
    BtnStop->Enabled = false;
    BtnPause->Enabled = false;
    EdFileName->Properties->ReadOnly = true;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnEditClick(TObject *Sender)
{
    if (BtnEdit->Caption == FrmLang->lblEdit->Caption)//"편집")
    {
        ChangeEditMode(0);
        FNewDb = false;
    }
    else
    {
        String sId = EdNmbr->Text;
        ChangeEditMode(1);

        if (CMM_FindGridData(TvList->DataController, sId, ColLink1->Index) >= 0)
        {
            CMM_SetGridRow(CxList, TvList, sId, ColLink1->Index);
            DisplayInfo();
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::ChangeEditMode(int AEdit)
{
    if (FPlayStream) BtnStopClick(NULL);

    bool bEnabled = false;
    EdFileName->Properties->ReadOnly = true;
    switch(AEdit)
    {
    case 0: //편집버튼클릭
        {
            BtnEdit->Enabled = true;
            BtnInsert->Enabled = false;
            BtnDelete->Enabled = false;
            BtnSave->Enabled = true;

            BtnEdit->Caption = FrmLang->lblCancel->Caption;//"취소";
            BtnEdit->Hint    = FrmLang->lblCancel->Hint;//데이터 편집 취소";
            EditMode = true;
            EdImageFileName->Enabled = false;
        }
        break;
    case 1: //편집[취소]버튼클릭
        {
            FormInit(); //화면을 모두 지운다.
            BtnEdit->Enabled = false;
            BtnInsert->Enabled = true;
            BtnDelete->Enabled = false;
            BtnSave->Enabled = false;

            BtnEdit->Caption = FrmLang->lblEdit->Caption;//"편집";
            BtnEdit->Hint    = FrmLang->lblEdit->Hint;//데이터 편집";
            //bEnabled = true;
            EditMode = false;
            EdImageFileName->Enabled = false;
        }
        break;
    case 2: //추가
        {
            BtnEdit->Enabled = true;
            BtnInsert->Enabled = false;
            BtnDelete->Enabled = false;
            BtnSave->Enabled = true;

            BtnEdit->Caption = FrmLang->lblCancel->Caption;//"취소";
            BtnEdit->Hint    = FrmLang->lblCancel->Hint;//데이터 편집 취소";
            EditMode = true;
            EdImageFileName->Enabled = true;
            //EdFileName->Properties->ReadOnly = false;
        }
        break;
    case 3: //수정모드
        {
            BtnEdit->Enabled = true;
            BtnInsert->Enabled = true;
            BtnDelete->Enabled = true;
            BtnSave->Enabled = false;

            BtnEdit->Caption = FrmLang->lblEdit->Caption;//"편집";
            BtnEdit->Hint    = FrmLang->lblEdit->Hint;//데이터 편집";
            bEnabled = true;
            EditMode = false;
            EdImageFileName->Enabled = false;
        }
        break;
    }

    BtnDownload->Enabled = false;
    BtnSaveImgFile->Enabled = false;
    if (ImgPreView->Picture->Bitmap != NULL)
    {
        if (ImgPreView->Picture->Bitmap->Height != 0)
        {
            BtnSaveImgFile->Enabled = true;
            BtnDownload->Enabled = true;
        }
    }
    if (AEdit == 0 || AEdit == 2)
    {
        GrpList->Enabled = false;
        PnlCmd->Enabled = true;
    }
    else
    {
        GrpList->Enabled = true;
        PnlCmd->Enabled = false;
    }

    //PnlEdit->Enabled = EditMode;
}
//---------------------------------------------------------------------------

bool __fastcall TVMSM430M::UpdateVmsImage(String ANmbr, String AExpl)
{
    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "UPDATE TB_VMS_SYMB_LIB                                    \r\n"
           "   SET RGST_DT   = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS'),  \r\n"
           "       SYMB_EXPL = :p02,                                  \r\n"
           "       UPDT_DT   = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')   \r\n"
           " WHERE SYMB_LIB_NMBR = :p01                               \r\n";

    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLBind(pADO, "p01", ANmbr);
            ITSDb_SQLBind(pADO, "p02", AExpl);
			pADO->ExecSQL();
            return true;
        }
        catch(EDatabaseError &E)
        {
            DBERRORMSG("TVMSM430M::UpdateVmsImage", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORMSG("TVMSM430M::UpdateVmsImage", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }
    return true;
}
//---------------------------------------------------------------------------
void __fastcall TVMSM430M::DeleteFtpFile(AnsiString AFileName)
{
    TStringList *sList = new TStringList;

    IdFtp->List(sList, "", false);
    for (int ii = 0; ii < sList->Count; ii++)
    {
        if (sList->Strings[ii] == AFileName)
        {
            IdFtp->Delete(AFileName);
            break;
        }
    }
    delete sList;
}
//---------------------------------------------------------------------------
bool __fastcall TVMSM430M::UploadFtpServer()
{
    String sOrgFile = EdImageFileName->Text;
    String sDstFile = EdFileName->Text.Trim();

    if (g_AppCfg.vmsFtp.SERVER == "") return false;

    IdFtp->Host     = g_AppCfg.vmsFtp.SERVER;
    IdFtp->Port     = g_AppCfg.vmsFtp.PORT;
    IdFtp->Username = g_AppCfg.vmsFtp.USER;
    IdFtp->Password = g_AppCfg.vmsFtp.PSWD;
    IdFtp->Passive  = g_AppCfg.vmsFtp.PASSIVE;

    String sErrMsg;
    bool   bConnect = false;
    try
    {
        try
        {
            IdFtp->Connect();
            IdFtp->ChangeDir("VIDEO");
            IdFtp->IOHandler->DefStringEncoding = TIdTextEncoding::UTF8;//IndyTextEncoding(949);
            bConnect = true;

            IdFtp->TransferType = ftBinary;
            IdFtp->Put(sOrgFile, sDstFile, false/*append_flag*/);
        }
        catch (EIdSocketError &exSock)
        {
            sErrMsg = exSock.Message;
            sErrMsg = StringReplace(sErrMsg, "\r\n", " ", TReplaceFlags() << rfReplaceAll);
            Application->MessageBox(sErrMsg.c_str(), FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return false;
        }
        catch (Exception &e)
        {
            sErrMsg = e.Message;
            sErrMsg = StringReplace(sErrMsg, "\r\n", " ", TReplaceFlags() << rfReplaceAll);
            Application->MessageBox(sErrMsg.c_str(), FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return false;
        }
    }
    __finally
    {
        if (bConnect && IdFtp->Connected())
        {
            IdFtp->Abort();
            IdFtp->Quit();
            IdFtp->Disconnect();
        }
    }

    String strmFileName = g_sVideoDir + sDstFile;
    if (!FileExists(strmFileName))
    {
        ::CopyFile(sOrgFile.c_str(), strmFileName.c_str(), false);
    }
    return true;
}
//---------------------------------------------------------------------------

bool __fastcall TVMSM430M::InsertVmsImage(String ANmbr, String AExpl, String AFileName, String ATypeCd)
{
    String sQry;
    TADOQuery *pADO = NULL;

    String SYMB_FILE_NM = EdFileName->Text.Trim();

    sQry = "INSERT INTO TB_VMS_SYMB_LIB(SYMB_LIB_NMBR, RGST_DT, SYMB_EXPL, IMAG_DATA, SYMB_FILE_NM, SYMB_TYPE, IMAG_SIZE, PLAY_TM, UPDT_DT, DEL_YN) \r\n"
           "                     VALUES(:p01,          :p02,    :p03,      :p04,      :p05,         :p06,      :p07,      :p08,    :p09,    'N'   ) \r\n";

	TMemoryStream *dataStream = new TMemoryStream();
	//TMemoryStream *videoStream = new TMemoryStream();
    try
    {
        try
        {
   	        ImgPreView->Picture->Bitmap->SaveToStream(dataStream);
            //videoStream->LoadFromFile(EdImageFileName->Text);//, ftBlob);

            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLBind(pADO, "p01", ANmbr);
            ITSDb_SQLBind(pADO, "p02", Now().FormatString("yyyymmddhhnnss"));
            ITSDb_SQLBind(pADO, "p03", AExpl);
    		pADO->Parameters->ParamByName("p04")->LoadFromStream(dataStream, ftBlob);
            ITSDb_SQLBind(pADO, "p05", SYMB_FILE_NM);
            ITSDb_SQLBind(pADO, "p06", ATypeCd);
            ITSDb_SQLBind(pADO, "p07", FFileSize);
            ITSDb_SQLBind(pADO, "p08", FPlayTime);
            ITSDb_SQLBind(pADO, "p09", Now().FormatString("yyyymmddhhnnss"));

			pADO->ExecSQL();

#if 0
    sQry = "UPDATE TB_VMS_SYMB_LIB         \r\n"
           "   SET AVI_DATA        = :p02  \r\n"
           " WHERE SYMB_LIB_NMBR   = :p01  \r\n";

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLBind(pADO, "p01", ANmbr);
    		pADO->Parameters->ParamByName("p02")->LoadFromFile(EdImageFileName->Text, ftBlob);
    		//pADO->Parameters->ParamByName("p02")->LoadFromStream(videoStream, ftBlob);

			pADO->ExecSQL();
#endif

            return true;
        }
        catch(EDatabaseError &E)
        {
            DBERRORMSG("TVMSM430M::InsertVmsImage", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORMSG("TVMSM430M::InsertVmsImage", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        if (dataStream) delete dataStream;
        dataStream = NULL;
        //if (videoStream) delete videoStream;
        //videoStream = NULL;
    }
    return true;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnSaveClick(TObject *Sender)
{
    if (FPlayStream) BtnStopClick(NULL);

	if (EdNmbr->Text.IsEmpty())
	{
        Application->MessageBox(lblImage1->Caption.c_str(),//L"VMS 이미지정보 저장\r\n이미지 번호를 입력하세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
	}

	if (EdFileName->Text.Trim().IsEmpty())
	{
        Application->MessageBox(lblImage21->Caption.c_str(),//L"VMS 이미지정보 저장\r\n동영상 파일명을 입력하세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
	}

    String sCurExt = ExtractFileExt(EdFileName->Text.Trim());
    String sNewExt = ExtractFileExt(EdImageFileName->Text.Trim());
    if (sCurExt.UpperCase() != sNewExt.UpperCase())
    {
        Application->MessageBox(lblImage22->Caption.c_str(),//L"VMS 이미지정보 저장\r\n동영상 파일명을 입력하세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
    }

	if (EdExpl->Text.Trim().IsEmpty())
	{
        Application->MessageBox(lblImage2->Caption.c_str(),//L"VMS 이미지정보 저장\r\n이미지 설명을 입력하세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
	}

    bool bResult = false;

    String sNmbr = EdNmbr->Text;
    String sExpl = EdExpl->Text.Trim();
    if (!FNewDb)
    {
        bResult = UpdateVmsImage(sNmbr, sExpl);
    }
    else
    {
        if (EdImageFileName->Text.Trim().IsEmpty() || EdFileName->Text.Trim().IsEmpty())
        {
            Application->MessageBox(lblImage3->Caption.c_str(),//L"VMS 이미지정보 저장\r\n이미지를 선택하셔야 합니다.",
                                    FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return;
        }

        if (IsUsedVideoFileName(EdFileName->Text.Trim()))
        {
            Application->MessageBox(lblSameFile->Caption.c_str(),//L"동일한 파일명이 존재합니다.\r\n파일명을 변경 한 후 다시 저장하십시요.",
                                    FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return;
        }

        // VMS FTP 전송
        if (UploadFtpServer() == false)
        {
            Application->MessageBox(lblFtpServer->Caption.c_str(),//L"VMS 통신서버로 파일을 전송할 수 없습니다.\r\n환경설정 파일에서 FTP 정보를 확인하세요.",
                                    FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
            return;
        }

        bResult = InsertVmsImage(sNmbr, sExpl, "", "SBT3");
    }

    if (bResult)
    {
        Application->MessageBox(lblText1->Caption.c_str(),//L"VMS 이미지정보 저장\r\nVMS 이미지정보를 저장 하였습니다.",
                                FTitle.c_str(), MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

        FUpdate = true;

        LoadImageSymbol();
        CMM_SetGridRow(CxList, TvList, sNmbr, ColLink1->Index);
        DisplayInfo();

        CComm_VmsImageSymbolUpdate();   // VMS서버로 이미지가 업데이트 되었음을 알린다.

        POST_MSG(Application->MainForm->Handle, WM_DATABASE_REFRESH, WP_MSG_14, 0);
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnInsertClick(TObject *Sender)
{
    FormInit();
    //신규아이디를 얻어와서 화면을 초기화한다.

    int nNmbr;

    if (!GetNextVmsImgeId(nNmbr))
    {
        Application->MessageBox(lblImage4->Caption.c_str(),//L"새로운 VMS 이미지정보를 생성하지 못하였습니다.\r\n프로그램 종료후에 다시 시도해 보세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
        return;
    }

    EdNmbr->Text = String(nNmbr);

    ChangeEditMode(2);
    FNewDb = true;
    EdImageFileNameClick((TObject *)EdImageFileName);
}
//---------------------------------------------------------------------------

bool __fastcall TVMSM430M::GetNextVmsImgeId(int &ANmbr)
{
    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "SELECT NVL(MAX(SYMB_LIB_NMBR), 4999)+1 AS NEWID FROM TB_VMS_SYMB_LIB WHERE SYMB_LIB_NMBR BETWEEN 5000 AND 5999 \r\n";

    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();
			pADO->SQL->Clear();
			pADO->SQL->Text = sQry;

			pADO->Open();
            ANmbr = pADO->FieldByName("NEWID")->AsInteger;
            return true;
        }
        catch(EDatabaseError &E)
        {
            DBERRORLOG("TVMSM430M::GetNextVmsImgeId", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORLOG("TVMSM430M::GetNextVmsImgeId", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }
    return false;
}
//---------------------------------------------------------------------------

bool __fastcall TVMSM430M::CheckImageUse(String ANmbr)
{
    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "SELECT COUNT(1) AS CNT      \r\n"
           "  FROM TB_VMS_FORM_OBJECT   \r\n"
           " WHERE SYMB_LIB_NMBR = :p01 \r\n";

    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLBind(pADO, "p01", ANmbr);
            ITSDb_SQLOpen(pADO);
            if (pADO->FieldByName("CNT")->AsInteger > 0)
            {
                Application->MessageBox(lblImage5->Caption.c_str(),//L"삭제할 이미지가 VMS 폼에서 사용되고 있습니다.\r\n먼저 해당 폼에서 삭제해주시기 바랍니다.",
                                        FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
                return false;
            }
        }
        catch(EDatabaseError &E)
        {
            DBERRORMSG("TVMSM430M::CheckImageUse", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORMSG("TVMSM430M::CheckImageUse", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }
    return true;
}
//---------------------------------------------------------------------------

bool __fastcall TVMSM430M::DelVmsImage(String ANmbr)
{
    String sQry;
    TADOQuery *pADO = NULL;

#if 0
    sQry = "DELETE TB_VMS_SYMB_LIB      \r\n"
           " WHERE SYMB_LIB_NMBR = :p01 \r\n";
#else
    sQry = "UPDATE TB_VMS_SYMB_LIB                                  \r\n"
           "   SET DEL_YN  = 'Y',                                   \r\n"
           "       UPDT_DT = TO_CHAR(SYSDATE, 'YYYYMMDDHH24MISS')   \r\n"
           " WHERE SYMB_LIB_NMBR = :p01 \r\n";
#endif

    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLBind(pADO, "p01", ANmbr);
			pADO->ExecSQL();
            return true;
        }
        catch(EDatabaseError &E)
        {
            DBERRORMSG("TVMSM430M::DelVmsImage", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORMSG("TVMSM430M::DelVmsImage", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }
    return true;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnDeleteClick(TObject *Sender)
{
    int nIdx = TvList->DataController->FocusedRecordIndex;
    if (nIdx < 0) return;

    String sId = EdNmbr->Text;

    if (sId.IsEmpty())
    {
        Application->MessageBox(lblImage6->Caption.c_str(),//L"삭제할 VMS 이미지를 목록에서 선택하세요.\r\n목록에서 더블클릭하여 선택합니다.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
        return;
    }

    if (!CheckImageUse(sId)) return;

    String sMsg;
    sMsg = lblImage7->Caption + ": " + sId;//"VMS이미지번호: " + sId;
    sMsg+= "\r\n" + lblImage8->Caption;//"선택하신 VMS 이미지 정보를 삭제하시겠습니까?";

    if (Application->MessageBox(sMsg.c_str(), FTitle.c_str(), MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL) != IDYES) return;

    if (DelVmsImage(sId))
    {
        FUpdate = true;

        Application->MessageBox(lblImage9->Caption.c_str(),//L"VMS 이미지정보삭제\r\nVMS 이미지정보를 삭제 하였습니다.",
                                FTitle.c_str(), MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

        FormInit();
        ChangeEditMode(1);

        LoadImageSymbol();

        POST_MSG(Application->MainForm->Handle, WM_DATABASE_REFRESH, WP_MSG_14, 0);
	}
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnSaveImgFileClick(TObject *Sender)
{
    SaveDialog->Title      = FTitle;
    SaveDialog->InitialDir = ExtractFilePath(Application->ExeName);
    SaveDialog->Filter     = "Video Files|*.AVI;*.MP4;*.MPG;*.MPEG";
    SaveDialog->FileName   = EdFileName->Text;

    if (SaveDialog->Execute())
    {
        try {
            String sFileName = SaveDialog->FileName;

            int iRet = sFileName.Pos(".bmp");
            if (iRet == 0)
            {
                sFileName = SaveDialog->FileName + ".bmp";
            }

            ImgPreView->Picture->SaveToFile(sFileName);
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::EdImageFileNameClick(TObject *Sender)
{
    OpenBmp->Title    = FTitle;
    OpenBmp->FileName = "";
    OpenBmp->Execute();
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::OpenBmpCanClose(TObject *Sender, bool &CanClose)
{
    String sFName = OpenBmp->FileName;

    if (!FFDecoder1->LoadFile(sFName))
    {
        Application->MessageBox(lblImage12->Caption.c_str(),//L"이미지 파일을 읽어 오는데 실패하였습니다.",
                                lblImage1->Caption.c_str(),//L"VMS 이미지 선택",
                                MB_OK|MB_ICONWARNING|MB_APPLMODAL);
        return;
    }

    if (FFDecoder1->Decode())
    {
        __int64 FDuration   = FFDecoder1->FileStreamInfo.Duration;
        //__int64 FCurrentPTS = FFDecoder1->FrameInfo.PTS;
        FPlayTime = (FDuration + 5000) / 1000000;
        FPlayTime++;

        FFDecoder1->CopyToBitmap(ImgTemp->Picture->Bitmap);

        ImgPreView->Picture->Bitmap->Width  = ImgPreView->Width;
        ImgPreView->Picture->Bitmap->Height = ImgPreView->Height;
        APP_ImageClear(ImgPreView->Canvas, 0, 0, ImgPreView->Width, ImgPreView->Height, clBlack);
        SetStretchBltMode(ImgPreView->Canvas->Handle, MAXSTRETCHBLTMODE);//HALFTONE);//MAXSTRETCHBLTMODE)//STRETCH_HALFTONE;
        ImgPreView->Canvas->CopyRect(Classes::Rect(0, 0, ImgPreView->Width, ImgPreView->Height),
                                     ImgTemp->Picture->Bitmap->Canvas,
                                     Classes::Rect(0, 0, ImgTemp->Picture->Bitmap->Width, ImgTemp->Picture->Bitmap->Height));
    }

    FFDecoder1->CloseFile();

    try
    {
        FFileSize = ITSUtil_GetFileSize(sFName);
        if (FFileSize <= 0)
        {
            Application->MessageBox(lblImage12->Caption.c_str(),//L"이미지 파일을 읽어 오는데 실패하였습니다.",
                                    lblImage1->Caption.c_str(),//L"VMS 이미지 선택",
                                    MB_OK|MB_ICONWARNING|MB_APPLMODAL);
            return;
        }

        //EdImageSize->Text = String(dwFileSize);//GetFileSize(sFName));

        EdImageFileName->Text = sFName;
        PlayerFile[0] = sFName;
        BtnPlay->Enabled = true;
        BtnStop->Enabled = false;
        BtnPause->Enabled = false;
        //FVideoStream

        FFileName    = ExtractFileName(sFName);
        EdExpl->Text = FFileName;

        FFileExt         = ExtractFileExt(sFName);
        EdFileName->Text = FFileName;
        //EdFileName->Text = EdNmbr->Text + FFileExt;

        //EdFileName->Properties->ReadOnly = false;
    }
    catch(...)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::ClearSymbloList()
{
	for(int ii = 0; ii < FListSymb->Count; ii++)
	{
		Graphics::TBitmap *bitmap = (Graphics::TBitmap *)FListSymb->Items[ii];
		delete bitmap;
	}
	FListSymb->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::LoadImageSymbol()
{
    FormInit();

    CMM_ClearGridTableView(TvList);
    ClearSymbloList();

    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "SELECT SYMB_LIB_NMBR,                       \r\n"
           "       IMAG_DATA,                           \r\n"
           "       SYMB_EXPL, SYMB_FILE_NM, SYMB_TYPE,  \r\n"
           "       AVI_DATA                             \r\n"
           "  FROM TB_VMS_SYMB_LIB                      \r\n"
           " WHERE SYMB_LIB_NMBR BETWEEN 5000 AND 5999  \r\n"
           "   AND SYMB_TYPE = 'SBT3'                   \r\n"
           "   AND DEL_YN = 'N'                         \r\n"
           " ORDER BY SYMB_LIB_NMBR                     \r\n";

    ForceDirectories(g_sVideoDir.c_str());

    try
    {
        int nRow;
        TcxDataController *pGDC = TvList->DataController;
        TvList->BeginUpdate();
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLOpen(pADO);

            for( ; !pADO->Eof; pADO->Next())
            {
                nRow = pGDC->AppendRecord();
                pGDC->Values[nRow][ColLink1->Index] = pADO->FieldByName("SYMB_LIB_NMBR")->AsString;
                pGDC->Values[nRow][ColLink2->Index] = pADO->FieldByName("IMAG_DATA")->AsVariant;
                pGDC->Values[nRow][ColLink3->Index] = pADO->FieldByName("SYMB_EXPL")->AsString;
                pGDC->Values[nRow][ColLink4->Index] = pADO->FieldByName("SYMB_TYPE")->AsString;
                pGDC->Values[nRow][ColLink5->Index] = pADO->FieldByName("SYMB_FILE_NM")->AsString;

#if 0
                String strmFileName = g_sVideoDir + pADO->FieldByName("SYMB_FILE_NM")->AsString;
                if (!FileExists(strmFileName))
                {
                    TMemoryStream *Stream1 = (TMemoryStream *)pADO->CreateBlobStream(pADO->FieldByName("AVI_DATA"), bmRead);
                    Stream1->SaveToFile(strmFileName);
                    SAFE_DELETE(Stream1);
                }
#endif

                Graphics::TBitmap *bitmap = new Graphics::TBitmap;
                try
                {
                    bitmap->LoadFromStream(pADO->CreateBlobStream(pADO->FieldByName("IMAG_DATA"), bmRead));
                }
                catch(...)
                {
                    bitmap->Assign(ImgTemp->Picture->Bitmap);
                }
                FListSymb->Add(bitmap);
            }
        }
        catch(EDatabaseError &E)
        {
            DBERRORMSG("TVMSM430M::LoadImageSymbol", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORMSG("TVMSM430M::LoadImageSymbol", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
        TvList->EndUpdate();
    }
}
//---------------------------------------------------------------------------
bool __fastcall TVMSM430M::IsUsedVideoFileName(String AFileName)
{
    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "SELECT COUNT(1) AS CNT          \r\n"
           "  FROM TB_VMS_SYMB_LIB          \r\n"
           " WHERE SYMB_TYPE    = 'SBT3'    \r\n"
           "   AND SYMB_FILE_NM = :p01      \r\n";

    int nExist = 1;
    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);
            ITSDb_SQLBind(pADO, "p01", AFileName);
            ITSDb_SQLOpen(pADO);

            for( ; !pADO->Eof; pADO->Next())
            {
                nExist = pADO->FieldByName("CNT")->AsInteger;
            }
        }
        catch(EDatabaseError &E)
        {
            DBERRORMSG("TVMSM430M::IsUsedVideoFileName", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            DBERRORMSG("TVMSM430M::IsUsedVideoFileName", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }
    return nExist == 0 ? false : true;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::TvListCellDblClick(TcxCustomGridTableView *Sender, TcxGridTableDataCellViewInfo *ACellViewInfo,
          TMouseButton AButton, TShiftState AShift,
          bool &AHandled)
{
	if (!ACellViewInfo) return;

    DisplayInfo();
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnDownloadClick(TObject *Sender)
{
	if (EdNmbr->Text.IsEmpty())
	{
        Application->MessageBox(lblText2->Caption.c_str(),//L"VMS 이미지 제어기 다운로드\r\n이미지를 선택 하세요.",
                                FTitle.c_str(), MB_OK|MB_ICONERROR|MB_APPLMODAL);
		return;
	}

    int nSelects = CMM_GetCheckCount(FRAMEVmsList1->TvList, FRAMEVmsList1->ColumnSel->Index);
    if (0 == nSelects)
    {
        Application->MessageBox(lblText3->Caption.c_str(),//L"VMS 이미지 제어기 다운로드\r\n다운로드할 VMS 제어기를 선택 하세요.",
                                FTitle.c_str(), MB_OK|MB_ICONWARNING|MB_APPLMODAL);
        return;
    }

    String sNmbr = EdNmbr->Text;

    String sMsg;
    sMsg = lblImage7->Caption + ": " + sNmbr;//"VMS이미지번호: " + sNmbr;
    sMsg+= "\r\n" + lblText4->Caption;//"선택하신 VMS 이미지 정보를 선택한 VMS 제어기로 다운로드 하시겠습니까?";

    if (Application->MessageBox(sMsg.c_str(), FTitle.c_str(), MB_YESNO|MB_ICONQUESTION|MB_APPLMODAL) != IDYES) return;

    String sUserId = g_pLOGIN->sUserId;
    String sRgstDt = Now().FormatString("yyyymmddhhnnss");

    String sQry;
    TADOQuery *pADO = NULL;

    sQry = "INSERT INTO TB_VMS_DOWNLOAD ( \r\n"
           "           RGST_DT,           \r\n"
           "           VMS_CTLR_NMBR,     \r\n"
           "           FILETYPE,          \r\n"
           "           FILEID,            \r\n"
           "           USER_ID)           \r\n"
           "  VALUES (                    \r\n"
           "           :p01,              \r\n"
           "           :p02,              \r\n"
           "           :p03,              \r\n"
           "           :p04,              \r\n"
           "           :p05 )             \r\n";

    try
    {
        try
        {
            pADO = new TADOQuery(NULL);
			pADO->Close();
            pADO->Connection = ITSDb_GetConnection();

            ITSDb_SQLText(pADO, sQry);

            ITSDb_GetConnection()->BeginTrans();

            int nRowCnt = FRAMEVmsList1->TvList->ViewData->RecordCount;
            for (int ii = 0; ii < nRowCnt; ii++)
            {
                TcxCustomGridRow* ARow = FRAMEVmsList1->TvList->ViewData->Rows[ii];
                if (((bool)ARow->Values[FRAMEVmsList1->ColumnSel->Index]))
                {
                    String sVmsNmbr = VarToStr(ARow->Values[FRAMEVmsList1->Column01->Index]);

                    ITSDb_SQLBind(pADO, "p01", sRgstDt);
                    ITSDb_SQLBind(pADO, "p02", sVmsNmbr);
                    ITSDb_SQLBind(pADO, "p03", "1");
                    ITSDb_SQLBind(pADO, "p04", sNmbr);
                    ITSDb_SQLBind(pADO, "p05", sUserId);

                    ITSDb_SQLExec(pADO);
                }
            }

            ITSDb_GetConnection()->CommitTrans();
        }
        catch(EDatabaseError &E)
        {
            ITSDb_GetConnection()->RollbackTrans();
            DBERRORMSG("TVMSM430M::BtnDownloadClick", String(E.ClassName()), E.Message, sQry);
            throw Exception(String(E.ClassName()) + E.Message);
        }
        catch(Exception &e)
        {
            ITSDb_GetConnection()->RollbackTrans();
            DBERRORMSG("TVMSM430M::BtnDownloadClick", String(e.ClassName()), e.Message, sQry);
            throw Exception(String(e.ClassName()) + e.Message);
        }
    }
    __finally
    {
        if (pADO)
        {
            pADO->Close();
            delete pADO;
        }
    }

#if 0
    sMsg = "VMS 이미지 제어기 다운로드\r\n"
           "VMS 이미지를 제어기로 다운로드 요청하였습니다.\r\n"
           "VMS 제어기 통신상태에 따라 다운로드가 원활하게 진행되지 않을 수 있습니다.";
#else
    sMsg = lblText5->Caption;
#endif

    Application->MessageBox(sMsg.c_str(), FTitle.c_str(), MB_OK|MB_ICONINFORMATION|MB_APPLMODAL);

    //FRAMEVmsList1->BtnAllSelectClick((TObject*)FRAMEVmsList1->BtnAllClear);
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::TvListFocusedRecordChanged(TcxCustomGridTableView *Sender,
          TcxCustomGridRecord *APrevFocusedRecord, TcxCustomGridRecord *AFocusedRecord,
          bool ANewItemRecordFocusingChanged)
{
    if (!AFocusedRecord) return;
    DisplayInfo();
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnPlayClick(TObject *Sender)
{
    BtnPlay->Enabled = false;
    for (int ii = 0; ii < MAX_PLAYER; ii++)
    {
Application->ProcessMessages();
        try
        {
            if (PlayerFile[ii] == "")
            {
                if (FFPlayer[ii]->ScreenHandle != NULL)
                {
                    FFPlayer[ii]->Stop(true);
                    PostMessage(FFPlayer[ii]->ScreenHandle, CM_INVALIDATE, 0, 0);
                    UpdateWindow(FFPlayer[ii]->ScreenHandle);
                }
                continue;
            }

            FFPlayer[ii]->AspectRatio = ChkFullScreen->Checked ? -1 : 0;
            FFPlayer[ii]->TryOpen(PlayerFile[ii], FDispArea[ii]->Handle);

Application->ProcessMessages();
        }
        catch(Exception &e)
        {
        }
    }
    BtnStop->Enabled = true;
    BtnPause->Enabled = true;

    FPlayStream = true;
    ImgPreView->Visible = false;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnStopClick(TObject *Sender)
{
    BtnStop->Enabled = false;
    BtnPause->Enabled = false;
    try
    {
        for (int ii = 0; ii < MAX_PLAYER; ii++)
        {
            try
            {
                if (FFPlayer[ii]->ScreenHandle != NULL)
                {
                    FFPlayer[ii]->Stop(true);
                }
Application->ProcessMessages();
            }
            catch(Exception &e)
            {
            }
        }
    } catch(...) {}
    BtnPlay->Enabled = true;

    FPlayStream = false;
    ImgPreView->Visible = true;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::BtnPauseClick(TObject *Sender)
{
    try
    {
        for (int ii = 0; ii < MAX_PLAYER; ii++)
        {
            try
            {
                if (FFPlayer[ii]->ScreenHandle != NULL)
                {
                    FFPlayer[ii]->TogglePause();
                }
Application->ProcessMessages();
            }
            catch(Exception &e)
            {
            }
        }
    } catch(...) {}
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::ChkFullScreenClick(TObject *Sender)
{
    FFPlayer1->AspectRatio = ChkFullScreen->Checked ? -1 : 0;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::TrackBar1Change(TObject *Sender)
{
    int nTag = dynamic_cast<TComponent *>(Sender)->Tag;
    switch(nTag)
    {
    case 0:
    case 1:
    case 2:
        break;
    default: return;
    }

    if (!FTrackChanging[nTag] && !IsMouseDown())
    {
        FFPlayer[nTag]->Seek(FDuration[nTag] * FTrackBar[nTag]->Position / FTrackBar[nTag]->Max);
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FFPlayer1FileOpen(TObject *Sender, const __int64 ADuration, int AFrameWidth, int AFrameHeight,
          int &AScreenWidth, int &AScreenHeight)
{
    int nTag = dynamic_cast<TComponent *>(Sender)->Tag;
    switch(nTag)
    {
    case 0:
    case 1:
    case 2:
        break;
    default: return;
    }

#if 0
    FPlayTime = (ADuration + 5000) / 1000000;
    FPlayTime++;
    FThumbNail = 0;
    FMakeThumbNail = true;
#endif

    FDuration[nTag] = ADuration;
    FLblDuration[nTag]->Caption = DurationToStr(ADuration);
    FLblCurrPTS[nTag]->Caption = "N/A";

    // setup track bar
    FTrackBar[nTag]->Frequency = 5;
    FTrackBar[nTag]->TickStyle = tsAuto;
    FTrackBar[nTag]->Max = FTrackBar[nTag]->Width;
    FTrackBar[nTag]->SelStart = 0;
    FTrackBar[nTag]->SelEnd = 0;
    FTrackBar[nTag]->SliderVisible = ADuration > 0;

    FTrackChanging[nTag] = true;
    try
    {
        FTrackBar[nTag]->Position = 0;
    }
    __finally
    {
        FTrackChanging[nTag]= false;
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FFPlayer1OpenFailed(TObject *Sender)
{
    int nTag = dynamic_cast<TComponent *>(Sender)->Tag;
    switch(nTag)
    {
    case 0:
    case 1:
    case 2:
        break;
    default: return;
    }

    String sLastErrMsg = FFPlayer[nTag]->LastErrMsg;
    FDispArea[nTag]->Caption = sLastErrMsg;
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FFPlayer1Position(TObject *Sender, const __int64 APTS)
{
    int nTag = dynamic_cast<TComponent *>(Sender)->Tag;
    switch(nTag)
    {
    case 0:
    case 1:
    case 2:
        break;
    default: return;
    }

    FLblCurrPTS[nTag]->Caption = DurationToStr(APTS);
    if ((APTS >= 0) && (FDuration[nTag] > 0))
    {
        FTrackBar[nTag]->SelEnd = FTrackBar[nTag]->Max * APTS / FDuration[nTag];
        if (FTrackChanging[nTag] == false && (IsMouseDown() == false ||  FTrackBar[nTag]->Focused() == false))
        {
            FTrackChanging[nTag] = true;
            try
            {
                FTrackBar[nTag]->Position = FTrackBar[nTag]->Max * APTS / FDuration[nTag];
            }
            __finally
            {
                FTrackChanging[nTag] = false;
            }
        }
        if (FMakeThumbNail)
        {
            FThumbNail++;
            if (FThumbNail > 2)
            {
                //섬네일이미지 생성
                FMakeThumbNail = false;
            }
        }
    }
}
//---------------------------------------------------------------------------

void __fastcall TVMSM430M::FFPlayer1State(TObject *Sender, TPlayState APlayState)
{
    int nTag = dynamic_cast<TComponent *>(Sender)->Tag;
    switch(nTag)
    {
    case 0:
    case 1:
    case 2:
        break;
    default: return;
    }

    switch(APlayState)
    {
    case Ffbasecomponent::psPlay:
    case Ffbasecomponent::psResume:
        break;
    case Ffbasecomponent::psPause:
    case Ffbasecomponent::psStep:
        break;
    case Ffbasecomponent::psStop:
        if (FFPlayer[nTag]->ScreenHandle != NULL)
        {
            PostMessage(FFPlayer[nTag]->ScreenHandle, CM_INVALIDATE, 0, 0);
            UpdateWindow(FFPlayer[nTag]->ScreenHandle);
        }
        break;
    case Ffbasecomponent::psEnd:
        {
            FFPlayer[nTag]->Stop(true);
            //FFPlayer[nTag]->Seek((__int64)0, TSeekFlags()<<sfBackward);
        }
        break;
    }
}
//---------------------------------------------------------------------------

