/*
  ICS PEM Certificate Tool - C++Builder translation of the Delphi demo
  OverbyteIcsPemTool3.pas (demos-delphi-vcl), ICS V9.8.

  Dialog for the Extras menu: create a self-signed certificate, or a certificate
  request and its private key, with the simple helper functions in
  OverbyteIcsSslX509Utils rather than the full TSslCertTools component.
*/

#include <vcl.h>
#pragma hdrstop

#include <memory>

#include "OverbyteIcsPemTool3.h"
#include "OverbyteIcsSslX509Utils.hpp"

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

TfrmPemTool3 *frmPemTool3;

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

void __fastcall TfrmPemTool3::FormShow(TObject *Sender)
{
    const bool selfSigned = (FToDo == tdCreateSelfSignedCert);
    CheckBoxCA->Visible = selfSigned;
    Editdays->Visible = selfSigned;
    lbDays->Visible = selfSigned;

    if (selfSigned) {
        Caption = "Create self-signed certificate and private key";
        lbInfo->Caption = "Certificate and private key are written to the same file.\r\n"
                          "Private key will not be password protected.";
    }
    else {
        Caption = "Create certificate request and private key";
        lbInfo->Caption = "Request and private key are written to different files.\r\n"
                          "Private key will not be password protected.";
    }
}

void __fastcall TfrmPemTool3::btnCreateClick(TObject *Sender)
{
    std::unique_ptr<TSaveDialog> Dlg(new TSaveDialog(nullptr));
    Dlg->DefaultExt = ".pem";
    Dlg->Filter = "PEM files|*.pem|All files|*.*";

    if (FToDo == tdCreateSelfSignedCert) {
        Dlg->Title = "Where do you want the certificate file to be stored";
        if (Dlg->Execute())
            // Delphi passes True for IsCA and ignores the visible "Is CA" box.
            CreateSelfSignedCert(Dlg->FileName, EditCountry->Text, EditState->Text,
                                 EditLocality->Text, EditOrganization->Text,
                                 EditOrganizationalUnit->Text, EditCommonName->Text,
                                 EditEMail->Text, StrToIntDef(EditBits->Text, 2048),
                                 CheckBoxCA->Checked, StrToIntDef(Editdays->Text, 365),
                                 String(), CheckBoxComment->Checked);
        return;
    }

    Dlg->Title = "Where do you want the private key file to be stored";
    String KeyFileName;
    if (Dlg->Execute())
        KeyFileName = Dlg->FileName;
    if (KeyFileName.IsEmpty())
        return;

    Dlg->Title = "Where do you want the request file to be stored";
    Dlg->FileName = "";
    bool picked;
    while ((picked = Dlg->Execute()) && KeyFileName == Dlg->FileName) {
        if (MessageDlg("Key and request cannot be stored in the same file.\r\n"
                       "Do you want to select a different request file name now?",
                       mtError, TMsgDlgButtons() << mbYes << mbNo, 0) != mrYes)
            return;
    }
    // Delphi carries on after Cancel, writing the request to an empty or the key's file name.
    if (!picked)
        return;
    CreateCertRequest(Dlg->FileName, KeyFileName, EditCountry->Text, EditState->Text,
                      EditLocality->Text, EditOrganization->Text,
                      EditOrganizationalUnit->Text, EditCommonName->Text, EditEMail->Text,
                      StrToIntDef(EditBits->Text, 2048), CheckBoxComment->Checked);
}
