#ifndef OverbyteIcsPemTool1H
#define OverbyteIcsPemTool1H

#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.Menus.hpp>
#include <Vcl.Buttons.hpp>
#include <Vcl.Dialogs.hpp>
#include <Vcl.CheckLst.hpp>

#include "OverbyteIcsTypes.hpp"
#include "OverbyteIcsSslBase.hpp"
#include "OverbyteIcsSslX509Utils.hpp"
#include "OverbyteIcsSslUtils.hpp"
#include "OverbyteIcsIpStreamLog.hpp"
#if __has_include(<OverbyteIcsMsSslUtils.hpp>)
#define ICS_HAVE_MSCRYPT 1
#include "OverbyteIcsMsSslUtils.hpp"
#endif

#include <memory>

const unsigned WM_APPSTARTUP      = WM_USER + 1;
const unsigned WM_IPLOGCONNECT    = WM_USER + 2;
const unsigned WM_IPLOGDISCONNECT = WM_USER + 3;

class TfrmPemTool1 : public TForm
{
__published:
    TPageControl *PageControl1;
    TTabSheet *TabCertsList;
    TListView *LvCerts;
    TPanel *Panel1;
    TLabel *Label4;
    TLabel *Label8;
    TLabel *Label34;
    TLabel *Label24;
    TButton *btnRefresh;
    TEdit *CurrentCertDirEdit;
    TButton *btnDeleteCert;
    TButton *btnCopyCert;
    TBitBtn *SelCurrDir;
    TButton *btnShowBundleFile;
    TButton *btnShowOneFile;
    TEdit *CertPassword;
    TCheckBox *CertCheckOCSP;
    TComboBox *CAFilesDir;
    TBitBtn *SelCARoots;
    TEdit *IntersCAFile;
    TBitBtn *SelIntersCA;
    TTabSheet *TabWindowsStore;
    TGroupBox *BoxStoreTools;
    TRadioGroup *MsStoreType;
    TButton *doMsDisplay;
    TRadioGroup *MsLocationType;
    TCheckBox *MSBriefList;
    TGroupBox *BoxStoreImport;
    TLabel *Label1;
    TLabel *Label2;
    TEdit *DestDirEdit;
    TCheckBox *CheckBoxWarnDestNotEmpty;
    TCheckBox *CheckBoxOverwriteExisting;
    TCheckBox *CheckBoxEmptyDestDir;
    TButton *btnImport;
    TCheckBox *CheckBoxWriteToBundle;
    TBitBtn *SelImpDir;
    TCheckBox *CheckBoxComment;
    TGroupBox *BoxStoreInstall;
    TLabel *Label3;
    TLabel *LabelAdminRightsIns;
    TEdit *MsInstallFile;
    TBitBtn *SelInstallFile;
    TButton *doMsInstallFile;
    TButton *doLoadtoCreate;
    TButton *doListPkeys;
    TButton *doCertStoreDel;
    TRadioGroup *MSKeyStoreType;
    TGroupBox *BoxFindCert;
    TLabel *Label39;
    TLabel *LabelAdminRightsSrch;
    TEdit *MsSearchCert;
    TButton *doSearchMsStore;
    TGroupBox *BoxPrivKeys;
    TLabel *Label41;
    TListBox *PkeyList;
    TButton *doKeyStoreDel;
    TListBox *CertStoreList;
    TGroupBox *BoxSigning;
    TButton *btnCheckSigned;
    TGroupBox *BoxMisc;
    TButton *btnImportPemFile;
    TTabSheet *TabCreateCerts;
    TGroupBox *BoxLoadCert;
    TLabel *Label9;
    TLabel *Label10;
    TLabel *Label11;
    TLabel *Label12;
    TLabel *Label13;
    TLabel *Label14;
    TLabel *Label27;
    TLabel *Label33;
    TEdit *LoadDirectory;
    TBitBtn *SelLoadDir;
    TMemo *CertLinesOld;
    TButton *doLoadCert;
    TEdit *LoadCertFile;
    TEdit *LoadPrivatetKey;
    TEdit *LoadRequestFile;
    TBitBtn *SelCertFile;
    TBitBtn *SelPrvKeyFile;
    TBitBtn *SelReqFile;
    TButton *doLoadPrvKey;
    TButton *doLoadReq;
    TButton *doLoadBase64;
    TEdit *LoadCertPW;
    TEdit *LoadInterCerts;
    TButton *doLoadInters;
    TBitBtn *SelIntersFile;
    TCheckBox *LoadCertPrivKey;
    TCheckBox *LoadCertInters;
    TEdit *LoadCaBundleFile;
    TBitBtn *SelCAFile;
    TButton *doLoadCABundle;
    TGroupBox *BoxCertProc;
    TLabel *LabelStateCert;
    TLabel *LabelStateReq;
    TLabel *LabelStatePrivKey;
    TLabel *LabelStateCACert;
    TLabel *LabelInters;
    TLabel *Label48;
    TButton *doClearCerts;
    TButton *doCreateReqProps;
    TButton *doCreateReqCert;
    TButton *doCreateSelfCert;
    TButton *doCreateCACert;
    TButton *doCreateBundle;
    TButton *doCheckBundleWin;
    TButton *doCheckBundleSelf;
    TButton *doListRoots;
    TButton *doListInters;
    TEdit *BundleHostName;
    TGroupBox *BoxCertSave;
    TLabel *Label17;
    TLabel *Label18;
    TLabel *Label19;
    TLabel *Label20;
    TLabel *Label22;
    TLabel *Label21;
    TLabel *Label23;
    TLabel *Label25;
    TLabel *Label26;
    TEdit *SaveDirectory;
    TBitBtn *SelSaveDir;
    TButton *doSaveCertPem;
    TEdit *SaveCertPem;
    TEdit *SavePrvFileFile;
    TEdit *SaveReqCertFile;
    TButton *doSaveCertDer;
    TButton *doSaveReqCert;
    TEdit *SavePkcs7File;
    TCheckBox *SavePrivateKey;
    TEdit *SaveCertDer;
    TEdit *SavePkcs12File;
    TEdit *SavePubKeyFile;
    TCheckBox *SaveInterCerts;
    TEdit *SaveCertPW;
    TCheckBox *SaveAutoReplace;
    TButton *doSavePkcs12;
    TButton *doSavePkcs7Cert;
    TButton *doSavePrivKey;
    TButton *doSavePubKey;
    TCheckBox *CertAddComment;
    TCheckBox *CertPwPemKeys;
    TCheckBox *CertPwPkcs12;
    TTabSheet *TabNewCertProps;
    TGroupBox *GroupBoxCertCreate;
    TLabel *lbCountry;
    TLabel *lbState;
    TLabel *lbLocality;
    TLabel *lbOrganization;
    TLabel *lbOrganizationalUnit;
    TLabel *lbCommonName;
    TLabel *lbEMail;
    TLabel *lbDays;
    TLabel *Label28;
    TLabel *Label29;
    TLabel *Label30;
    TLabel *Label31;
    TLabel *Label42;
    TLabel *Label43;
    TLabel *Label44;
    TLabel *Label45;
    TLabel *Label46;
    TEdit *CertCountry;
    TEdit *CertState;
    TEdit *CertLocality;
    TEdit *CertOrganization;
    TEdit *CertOrganizationalUnit;
    TEdit *CertCommonName;
    TEdit *CertEMail;
    TEdit *CertDays;
    TRadioGroup *CertSignHash;
    TEdit *CertDescr;
    TGroupBox *GroupBox1;
    TCheckBox *CertIsCA;
    TCheckBox *CertsRootCA;
    TGroupBox *GroupBox2;
    TCheckBox *CertUsageCertSign;
    TCheckBox *CertUsageCRLSign;
    TCheckBox *CertUsageDigSign;
    TCheckBox *CertUsageDataEn;
    TCheckBox *CertUsageKeyEn;
    TCheckBox *CertUsageKeyAgree;
    TCheckBox *CertUsageNonRepud;
    TGroupBox *GroupBox3;
    TCheckBox *CertExtServer;
    TCheckBox *CertExtClient;
    TCheckBox *CertExtEmail;
    TCheckBox *CertExtCodeSign;
    TMemo *CertLinesNew;
    TMemo *CertAltDomains;
    TMemo *CertAltIPs;
    TCheckBox *NewCertCopyExt;
    TEdit *CertStreet;
    TEdit *CertTitle;
    TEdit *CertInitals;
    TEdit *CertGivenName;
    TEdit *CertSurName;
    TGroupBox *GroupKeys;
    TRadioGroup *KeyType;
    TRadioGroup *KeyEncrypt;
    TMemo *KeyPairLines;
    TButton *doGenKey;
    TGroupBox *GroupQuickCerts;
    TLabel *Label15;
    TLabel *Label16;
    TLabel *Label38;
    TLabel *Label40;
    TLabel *LabelAdminRightsRoot;
    TEdit *QuickCAFile;
    TEdit *QuickCertPath;
    TButton *doQuickCASign;
    TButton *doQuickSelfSign;
    TEdit *QuickPassword;
    TButton *doInstallIcsRoot;
    TTabSheet *TabTestHosts;
    TLabel *Label5;
    TLabel *Label6;
    TLabel *Label7;
    TLabel *Label32;
    TLabel *Label35;
    TLabel *Label36;
    TLabel *Label37;
    TLabel *Label47;
    TMemo *TestHostList;
    TEdit *TestHostOne;
    TButton *doTestOneCert;
    TButton *doTestListCerts;
    TCheckListBox *DownloadCerts;
    TCheckListBox *DownloadInters;
    TEdit *DownCertsPath;
    TEdit *DownIntersPath;
    TBitBtn *SelDownHostPath;
    TBitBtn *SelDownInters;
    TButton *doHostSave;
    TButton *doSaveInters;
    TButton *doAddInterBundle;
    TButton *doTestAbort;
    TProgressBar *ProgressBar1;
    TPanel *Panel2;
    TLabel *Status;
    TPopupMenu *pmLv;
    TMenuItem *pmShowDetails;
    TMenuItem *N2;
    TMenuItem *pmCopy;
    TMenuItem *N1;
    TMenuItem *pmDelete;
    TOpenDialog *OpenDlg;
    TMainMenu *MainMenu1;
    TMenuItem *MMFile;
    TMenuItem *MMResaveKey;
    TMenuItem *MMFileExit;
    TMenuItem *MMExtras;
    TMenuItem *MMExtrasCreateSelfSignedCert;
    TMenuItem *MMExtrasCreateCertRequest;
    TOpenDialog *OpenDirDiag;
    TIcsIpStrmLog *IcsIpClient;
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall FormShow(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    void __fastcall FormDestroy(TObject *Sender);
    void __fastcall PageControl1Change(TObject *Sender);
    void __fastcall LvCertsColumnClick(TObject *Sender, TListColumn *Column);
    void __fastcall LvCertsCompare(TObject *Sender, TListItem *Item1, TListItem *Item2, int Data, int &Compare);
    void __fastcall LvCertsCustomDraw(TCustomListView *Sender, const TRect &ARect, bool &DefaultDraw);
    void __fastcall LvCertsDblClick(TObject *Sender);
    void __fastcall btnRefreshClick(TObject *Sender);
    void __fastcall CurrentCertDirEditChange(TObject *Sender);
    void __fastcall btnDeleteCertClick(TObject *Sender);
    void __fastcall btnCopyCertClick(TObject *Sender);
    void __fastcall SelCurrDirClick(TObject *Sender);
    void __fastcall btnShowBundleFileClick(TObject *Sender);
    void __fastcall btnShowOneFileClick(TObject *Sender);
    void __fastcall CAFilesDirClick(TObject *Sender);
    void __fastcall IntersCAFileChange(TObject *Sender);
    void __fastcall SelIntersCAClick(TObject *Sender);
    void __fastcall doMsDisplayClick(TObject *Sender);
    void __fastcall DestDirEditChange(TObject *Sender);
    void __fastcall btnImportClick(TObject *Sender);
    void __fastcall SelImpDirClick(TObject *Sender);
    void __fastcall SelInstallFileClick(TObject *Sender);
    void __fastcall doMsInstallFileClick(TObject *Sender);
    void __fastcall doLoadtoCreateClick(TObject *Sender);
    void __fastcall doListPkeysClick(TObject *Sender);
    void __fastcall doCertStoreDelClick(TObject *Sender);
    void __fastcall doSearchMsStoreClick(TObject *Sender);
    void __fastcall doKeyStoreDelClick(TObject *Sender);
    void __fastcall btnCheckSignedClick(TObject *Sender);
    void __fastcall btnImportPemFileClick(TObject *Sender);
    void __fastcall SelLoadDirClick(TObject *Sender);
    void __fastcall doLoadCertClick(TObject *Sender);
    void __fastcall SelCertFileClick(TObject *Sender);
    void __fastcall SelPrvKeyFileClick(TObject *Sender);
    void __fastcall SelReqFileClick(TObject *Sender);
    void __fastcall doLoadPrvKeyClick(TObject *Sender);
    void __fastcall doLoadReqClick(TObject *Sender);
    void __fastcall doLoadBase64Click(TObject *Sender);
    void __fastcall doLoadIntersClick(TObject *Sender);
    void __fastcall SelIntersFileClick(TObject *Sender);
    void __fastcall SelCAFileClick(TObject *Sender);
    void __fastcall doLoadCABundleClick(TObject *Sender);
    void __fastcall doClearCertsClick(TObject *Sender);
    void __fastcall doCreateReqPropsClick(TObject *Sender);
    void __fastcall doCreateReqCertClick(TObject *Sender);
    void __fastcall doCreateSelfCertClick(TObject *Sender);
    void __fastcall doCreateCACertClick(TObject *Sender);
    void __fastcall doCreateBundleClick(TObject *Sender);
    void __fastcall doCheckBundleWinClick(TObject *Sender);
    void __fastcall doCheckBundleSelfClick(TObject *Sender);
    void __fastcall doListRootsClick(TObject *Sender);
    void __fastcall doListIntersClick(TObject *Sender);
    void __fastcall SelSaveDirClick(TObject *Sender);
    void __fastcall doSaveCertPemClick(TObject *Sender);
    void __fastcall doSaveCertDerClick(TObject *Sender);
    void __fastcall doSaveReqCertClick(TObject *Sender);
    void __fastcall doSavePkcs12Click(TObject *Sender);
    void __fastcall doSavePkcs7CertClick(TObject *Sender);
    void __fastcall doSavePrivKeyClick(TObject *Sender);
    void __fastcall doSavePubKeyClick(TObject *Sender);
    void __fastcall doGenKeyClick(TObject *Sender);
    void __fastcall doQuickCASignClick(TObject *Sender);
    void __fastcall doQuickSelfSignClick(TObject *Sender);
    void __fastcall doInstallIcsRootClick(TObject *Sender);
    void __fastcall doTestOneCertClick(TObject *Sender);
    void __fastcall doTestListCertsClick(TObject *Sender);
    void __fastcall DownloadCertsDblClick(TObject *Sender);
    void __fastcall DownloadIntersDblClick(TObject *Sender);
    void __fastcall SelDownHostPathClick(TObject *Sender);
    void __fastcall SelDownIntersClick(TObject *Sender);
    void __fastcall doHostSaveClick(TObject *Sender);
    void __fastcall doSaveIntersClick(TObject *Sender);
    void __fastcall doAddInterBundleClick(TObject *Sender);
    void __fastcall doTestAbortClick(TObject *Sender);
    void __fastcall MMResaveKeyClick(TObject *Sender);
    void __fastcall MMFileExitClick(TObject *Sender);
    void __fastcall MMExtrasCreateSelfSignedCertClick(TObject *Sender);
    void __fastcall MMExtrasCreateCertRequestClick(TObject *Sender);
    void __fastcall IcsIpClientLogRecvEvent(TObject *Sender, int Socnr, const String Line);
    void __fastcall IcsIpClientLogChangeEvent(TObject *Sender, int Socnr, TStrmLogState LogState);
    void __fastcall IcsIpClientLogProgEvent(TObject *Sender, int Socnr, TLogOption LogOption, const String Msg);
    void __fastcall IcsIpClientLogHandshakeDone(TObject *Sender, Word ErrCode, TX509Base *PeerCert, bool &Disconnect);

protected:
    void __fastcall WMAppStartup(TMessage &Msg);
    void __fastcall WMIpLogConnect(TMessage &Msg);
    void __fastcall WMIpLogDisconnect(TMessage &Msg);

    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(WM_APPSTARTUP, TMessage, WMAppStartup)
        VCL_MESSAGE_HANDLER(WM_IPLOGCONNECT, TMessage, WMIpLogConnect)
        VCL_MESSAGE_HANDLER(WM_IPLOGDISCONNECT, TMessage, WMIpLogDisconnect)
    END_MESSAGE_MAP(TForm)

private:
    String FProgDir;
    String FIniFileName;
    String FCurrentCertDir;
    String FVerifyDir;
    bool FInitialized = false;
    bool FClosing = false;
    bool FLVSortFlag = false;
    int FColumnToSort = 0;
    int FTestHostTot = 0;
    int FTestHostCur = 0;
    __int64 FStartTickCount = 0;
    std::unique_ptr<TSslCertTools> FSslCertTools;
    std::unique_ptr<TX509Base> FSslCAX509;
    std::unique_ptr<TOcspHttp> FOcspHttp;
    std::unique_ptr<TX509List> FInterCAList;
    std::unique_ptr<TX509List> FDownCertsList;
    std::unique_ptr<TX509List> FDownIntersList;
#ifdef ICS_HAVE_MSCRYPT
    std::unique_ptr<TMsX509List> FMsX509List;
    std::unique_ptr<TMsCertChainEngine> FMsCertChainEngine;
    TStorePkeyInfos FStorePkeyInfos;
    TMsCertStoreType FMsListStoreType = MsStoreMy;
    TMsCertLocation FMsListLocation = MsLocCurUser;
    TMsKeyProvider FMsKeyListProvider = MsKeySoftware;
    TMsCertLocation FMsKeyListLocation = MsLocCurUser;
#endif

    void __fastcall AppOnException(TObject *Sender, Exception *E);
    void __fastcall ToolsOKeyProgress(TObject *Sender);
    void __fastcall LogEvent(TObject *Sender, TLogOption LogOption, const String Msg);
    void AddLog(const String &S);
    void AppendLogText(const String &S);
    void DispError(const String &Err);
    void ShowLogWindow();
    void LoadSettings();
    void SaveSettings();
    void AddListView(TX509Base *X, const String &FileName);
    void FillListView();
    TListItem *SelectedCert(String &FileName);
    void ShowBundleCerts(const String &FileName);
    void ShowOneCert(const String &FileName);
    String PickCertFile(const String &Filter);
    void SelectLoadFile(TEdit *FileEdit);
    bool SelectDir(TEdit *DirEdit);
    String BuildLoadName(const String &FName);
    String BuildSaveName(const String &FName);
    TSslPrivKeyCipher SelectedKeyCipher();
    void CleanAltDomains(const String &CName);
    void SetCertProps();
    void DispCert();
    void DispPKey();
    void DispReq();
    void DispInter();
    void DispCACert();
    void LoadRootCA();
    void LoadInterCA();
    String ListOcspStatus(TX509Base *Cert);
    void TestHostCert(const String &HostPort);
    void SaveDownloadedCerts(TX509List *List, TCheckListBox *Box, const String &Path);
    void CreateQuickCert(bool CASigned);

public:
    __fastcall TfrmPemTool1(TComponent *Owner);
};

extern PACKAGE TfrmPemTool1 *frmPemTool1;

#endif
