/*
  ICS Mail Queue demo - C++Builder translation of the Delphi unit OverbyteIcsMailQuTstView.pas
  (demos-delphi-vcl), ICS V9.8. Lists the mail waiting in the queue; double click deletes an item.

  How this C++ version differs from the Delphi original, apart from syntax:
  - ViewQuWinFlag is also set when the window is shown again (OnShow, assigned in FormCreate).
  - FormDestroy is not bound; the destructor clears ViewQuWinFlag.
*/

#include <vcl.h>
#pragma hdrstop

#include <memory>
#include <Vcl.Dialogs.hpp>

#include "OverbyteIcsMailQuTstView.h"
#include "OverbyteIcsMailQuTst1.h"
#include "OverbyteIcsIniFiles.hpp"
#include "OverbyteIcsUtils.hpp"

#pragma package(smart_init)
#pragma resource "*.dfm"

TViewQuForm *ViewQuForm;

namespace {
const wchar_t *const SectionWindow = L"ViewQuWindow";
}

__fastcall TViewQuForm::TViewQuForm(TComponent *Owner)
    : TForm(Owner)
{
}

__fastcall TViewQuForm::~TViewQuForm()
{
    ViewQuWinFlag = false;
}

void __fastcall TViewQuForm::doCloseClick(TObject *Sender)
{
    Close();
}

void __fastcall TViewQuForm::doUpdateClick(TObject *Sender)
{
    UpdateList();
}

void __fastcall TViewQuForm::FormClose(TObject *Sender, TCloseAction &Action)
{
    ViewQuWinFlag = false;
    std::unique_ptr<TIcsIniFile> ini(new TIcsIniFile(IniFileName, true));
    ini->WriteInteger(SectionWindow, "Top", Top);
    ini->WriteInteger(SectionWindow, "Left", Left);
    ini->WriteInteger(SectionWindow, "Width", Width);
    ini->WriteInteger(SectionWindow, "Height", Height);
    ini->UpdateFile();
}

void __fastcall TViewQuForm::FormCreate(TObject *Sender)
{
    std::unique_ptr<TIcsIniFile> ini(new TIcsIniFile(IniFileName, true));
    Top = ini->ReadInteger(SectionWindow, "Top", (Screen->Height - Height) / 2);
    Left = ini->ReadInteger(SectionWindow, "Left", (Screen->Width - Width) / 2);
    Width = ini->ReadInteger(SectionWindow, "Width", Width);
    Height = ini->ReadInteger(SectionWindow, "Height", Height);
    ViewQuWinFlag = true;
    // Delphi sets the flag only here, so after the window is closed once the timer stops refreshing it.
    OnShow = FormShow;
}

void __fastcall TViewQuForm::FormShow(TObject *Sender)
{
    ViewQuWinFlag = true;
}

void __fastcall TViewQuForm::QuListViewDblClick(TObject *Sender)
{
    if (!DemoForm->IcsMailQueue1->Active || QuListView->ItemIndex < 0)
        return;
    const String item = QuListView->Items->Item[QuListView->ItemIndex]->Caption;
    const int key = MessageDlg("Confirm Delete Item " + item + " From Mail Queue?", mtConfirmation,
        TMsgDlgButtons() << mbYes << mbNo << mbCancel, 0);
    if (key != mrYes)
        return;
    if (DemoForm->IcsMailQueue1->UnQueueMail(Icsatoi(item)))
        LabelState->Caption = "Queue State: Removed Item OK";
    else
        LabelState->Caption = "Queue State: Failed to Remove Item";
}

void __fastcall TViewQuForm::UpdateList()
{
    TIcsMailQueue *queue = DemoForm->IcsMailQueue1;
    if (!queue->Active) {
        LabelState->Caption = "Queue State: Not Running";
        return;
    }
    QuListView->Items->Clear();
    if (queue->MailTotItems == 0) {
        LabelState->Caption = "Queue State: Empty";
        return;
    }
    LabelState->Caption = "Queue State: " + IntToStr(queue->MailTotItems) + " Waiting Mail Items";
    for (int i = 0; i < queue->MailTotItems; ++i) {
        // MailQuIdx holds pointers to the queue's TMailQuItem records; take a copy, as Delphi does.
        const TMailQuItem item = *static_cast<PMailQuItem>(queue->MailQuIdx->Items[i]);
        TListItem *row = QuListView->Items->Add();
        row->Caption = IntToStr(item.ItemNr);
        row->SubItems->Add(item.LastResp);
        row->SubItems->Add(DateTimeToStr(item.NextAttemptDT));
        row->SubItems->Add(item.XReceivers);
        row->SubItems->Add(item.XSender);
        row->SubItems->Add(item.Subject);
        row->SubItems->Add(IntToKbyte(item.BodySize));
        row->SubItems->Add(ExtractFileName(item.FName));
        row->SubItems->Add(DateTimeToStr(item.QueuedDT));
        row->SubItems->Add(DateTimeToStr(item.LastAttemptDT));
        row->SubItems->Add(IntToStr(item.AttemptNr));
        row->SubItems->Add(IntToStr(static_cast<int>(item.Priority)));
        row->SubItems->Add(String(MailSmtpMethNames[item.SmtpMeth]));
        String servers;
        for (int j = 0; j < MaxSmtpSrv; ++j) {
            if (j > 0)
                servers += ", ";
            servers += item.SmtpSrvs[j];
        }
        row->SubItems->Add(servers);
    }
}
