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

#include <vcl.h>
#pragma hdrstop

#include "FrmVmsLogF.h"
#include "FrmSysLogF.h"
#include "AppGlobalF.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFrmVmsLog *FrmVmsLog = NULL;
//---------------------------------------------------------------------------
__fastcall TFrmVmsLog::TFrmVmsLog(TComponent* Owner)
    : TForm(Owner)
{
    FVmsIdx = -1;
    FVmsId  = " ";
    FVmsCtlr = NULL;

    reMsg->Lines->Clear();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsLog::btnClearClick(TObject *Sender)
{
    reMsg->Lines->Clear();
    Application->ProcessMessages();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsLog::btnCopyClick(TObject *Sender)
{
    try
    {
        reMsg->SelectAll();
        reMsg->CopyToClipboard();
    }
    catch(Exception &e)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsLog::OnWMLogDisplayMessage(TMessage &Msg)
{
    if (Showing)
    {
        IPC_LOG_MESSAGE *pLog = (IPC_LOG_MESSAGE *)Msg.WParam;
        if (pLog)
        {
            IPC_LOG_MESSAGE Log;
            Log.Kind = pLog->Kind;
            Log.Flag = pLog->Flag;
            Log.Len  = pLog->Len;
            Log.Tm   = pLog->Tm;
            Log.Type = pLog->Type;
            memcpy(Log.Msg, pLog->Msg, sizeof(Log.Msg));
            if (chkLogPause->Checked) return;
            LogWrite(&Log);
        }
    }
}
//---------------------------------------------------------------------------

void TFrmVmsLog::LogWrite(IPC_LOG_MESSAGE *ALog)
{
    if (ALog->Type == 'S')
    {
        if (!chkServer->Checked) return;
    }
    else
    {
        if (!chkClient->Checked) return;
    }

    if (ALog->Kind == eLOG_DATA)
    {
        LogData(ALog);
        return;
    }
    try
    {
        while (reMsg->Lines->Count >= g_AppCfg.nMaxLogLines)
            reMsg->Lines->Delete(0);

        reMsg->Lines->Add(ALog->Tm.FormatString("hh:nn:ss") + String(ALog->Msg));
    }
    catch(Exception &e)
    {
    }
}
//---------------------------------------------------------------------------

void TFrmVmsLog::LogData(IPC_LOG_MESSAGE *ALog)
{
    AnsiString     sTemp;
    AnsiString     sTime;
    int            ii, jj, pos;
    bool           bFileClose = false;
    unsigned char *AData= ALog->Msg;

    if (!AData) return;

    String sLogData = "";

    if (chkLogPause->Checked) return;

    try
    {
        AnsiString sSndRcv = ALog->Flag == 1 ? "SEND" : "RECV";
        sTime = AnsiString(ALog->Tm.FormatString("hh:nn:ss"));
        if (ALog->Type == 'C')
            sTemp.printf("%s [DATA] %s Client, [%s] %d Bytes ", sTime.c_str(), FVmsId.c_str(), sSndRcv.c_str(), ALog->Len);
        else
            sTemp.printf("%s [DATA] %s Server, [%s] %d Bytes ", sTime.c_str(), FVmsId.c_str(), sSndRcv.c_str(), ALog->Len);

        reMsg->Lines->Add("");
        reMsg->Lines->Add(sTemp);

        AnsiString sLog;
        AnsiString sChar;
        AnsiString sMsg;

        for (ii = 0; ii < ALog->Len; ii += 16)
        {
            sLogData = "";
            sLog = "";
            sMsg.printf("%08Xh ", ii);
            sLog += sMsg;
            for (jj = 0; jj < 16; jj++)
            {
                pos = ii + jj;
                if (pos < ALog->Len)
                    sMsg.printf(" %02X", AData[pos]);
                else
                    sMsg.printf("   ");

                sLog += sMsg;

                if (jj == 7)
                {
                    //sMsg.printf("  "); sLog += sMsg;
                }
            }

            sMsg.printf("  ;"); sLog += sMsg;

            for (jj = 0; jj < 16; jj++)
            {
                pos = ii + jj;
                if (pos >= ALog->Len)
                    break;

                uint8_t v = AData[pos];
                sMsg.printf("%c", isprint(v) ? v : '.');
                sLog += sMsg;
                if (jj == 7)
                {
                    //sMsg.printf(" "); sLog += sMsg;
                }
            }
            sLogData += sLog;
            //sLogData = sLogData.SubString(0, sLogData.Length()-2);
            reMsg->Lines->Add(sLogData);
        }
        reMsg->Lines->Add("");
    }
    catch(Exception &e)
    {
    }
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsLog::FormClose(TObject *Sender, TCloseAction &Action)
{
    DisplayVmsLog();
    Hide();
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsLog::DisplayVmsLog(int AVmsIdx/*=-1*/)
{
    VmsIterator it;
    for(it=VmsManager->FLists.FMapObject.begin(); it != VmsManager->FLists.FMapObject.end(); ++it)
    {
        TVmsCtlr *pObj = (TVmsCtlr*)it->second;
        if (!pObj->FDispLog)
        {
            pObj->FCLog->FLogCfg = g_LogCfg;
            pObj->FSLog->FLogCfg = g_LogCfg;
        }
    }

    if (FVmsCtlr)
    {
        FVmsCtlr->FDispLog = false;
        FVmsCtlr->FCLog->FLogCfg = g_LogCfg;
        FVmsCtlr->FSLog->FLogCfg = g_LogCfg;
    }
    if (AVmsIdx < 0)
    {
        FVmsCtlr = NULL;
        return;
    }

    FVmsCtlr = (TVmsCtlr*)AVmsIdx;

    FLogCfg = FVmsCtlr->FSLog->FLogCfg;

    chkInfo->Checked    = FLogCfg.Info;
    chkData->Checked    = FLogCfg.Data;
    chkError->Checked   = FLogCfg.Error;
    chkWarning->Checked = FLogCfg.Warning;
    chkDebug->Checked   = FLogCfg.Debug;
    chkDetail->Checked  = FLogCfg.Detail;

    FVmsCtlr->FDispLog = true;
    FVmsId = FVmsCtlr->VmsId;
    //Caption = "VMS Log: " + FVmsCtlr->VmsId + ", " + FVmsCtlr->Name;
    Caption = FVmsCtlr->VmsId + ", " + FVmsCtlr->Name;

    btnClearClick(NULL);
}
//---------------------------------------------------------------------------

void __fastcall TFrmVmsLog::btnSetLogClick(TObject *Sender)
{
    FLogCfg.Info    = chkInfo->Checked;
    FLogCfg.Data    = chkData->Checked;
    FLogCfg.Error   = chkError->Checked;
    FLogCfg.Warning = chkWarning->Checked;
    FLogCfg.Debug   = chkDebug->Checked;
    FLogCfg.Detail  = chkDetail->Checked;

    if (FVmsCtlr)
    {
        FVmsCtlr->FCLog->FLogCfg = FLogCfg;
        FVmsCtlr->FSLog->FLogCfg = FLogCfg;
    }
}
//---------------------------------------------------------------------------

