#ifndef OverbyteIcsThrdSrvV3_1H
#define OverbyteIcsThrdSrvV3_1H

#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>

#include "OverbyteIcsWSocket.hpp"
#include "OverbyteIcsWSocketS.hpp"
#include "OverbyteIcsWSocketTS.hpp"
#include "OverbyteIcsWndControl.hpp"
#include "OverbyteIcsIniFiles.hpp"
#include "OverbyteIcsTypes.hpp"

#include <mutex>
#include <vector>

const unsigned WM_APPSTARTUP = WM_USER + 1;
const unsigned WM_LOG_MESSAGE = WM_USER + 2;

class TMyClient : public TWSocketThrdClient
{
public:
    __fastcall virtual TMyClient(TComponent *AOwner) : TWSocketThrdClient(AOwner) {}
    String RcvdLine;
    TDateTime ConnectTime;
};

struct TWhoEntry
{
    TObject *Client;
    String Addr;
    String Port;
    TDateTime ConnectTime;
};

class TThrdSrvForm : public TForm
{
__published:
    TPanel *ToolPanel;
    TMemo *DisplayMemo;
    TEdit *ClientsPerThreadEdit;
    TLabel *Label1;
    TButton *DisconnectAllButton;
    TButton *ClearMemoButton;
    TWSocketThrdServer *WSocketThrdServer1;
    void __fastcall FormShow(TObject *Sender);
    void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall WSocketThrdServer1ClientConnect(TObject *Sender, TWSocketClient *Client, System::Word Error);
    void __fastcall WSocketThrdServer1ClientDisconnect(TObject *Sender, TWSocketClient *Client, System::Word Error);
    void __fastcall WSocketThrdServer1BgException(TObject *Sender, Exception *E, bool &CanClose);
    void __fastcall WSocketThrdServer1ClientCreate(TObject *Sender, TWSocketClient *Client);
    void __fastcall ClientsPerThreadEditChange(TObject *Sender);
    void __fastcall DisconnectAllButtonClick(TObject *Sender);
    void __fastcall ClearMemoButtonClick(TObject *Sender);
    void __fastcall WSocketThrdServer1ThreadException(TObject *Sender, TWsClientThread *AThread, const String AErrMsg);

protected:
    void __fastcall WmLogMessage(TMessage &Msg);
    void __fastcall WMAppStartup(TMessage &Msg);

    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(WM_LOG_MESSAGE, TMessage, WmLogMessage)
        VCL_MESSAGE_HANDLER(WM_APPSTARTUP, TMessage, WMAppStartup)
    END_MESSAGE_MAP(TForm)

private:
    String FIniFileName;
    bool FInitialized = false;
    std::mutex FLogMutex;
    std::vector<String> FLogList;
    std::mutex FWhoMutex;
    std::vector<TWhoEntry> FWho;

    void Display(const String &Msg);
    void __fastcall ClientDataAvailable(TObject *Sender, System::Word Error);
    void ProcessData(TMyClient *Client);
    void __fastcall ClientBgException(TObject *Sender, Exception *E, bool &CanClose);
    void __fastcall ClientLineLimitExceeded(TObject *Sender, int Cnt, bool &ClearData);

public:
    __fastcall TThrdSrvForm(TComponent *Owner);
    __fastcall ~TThrdSrvForm();
    __property String IniFileName = {read = FIniFileName, write = FIniFileName};
};

extern PACKAGE TThrdSrvForm *ThrdSrvForm;

#endif
