unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdCustomTCPServer,
  IdTCPServer, IdContext, IdGlobal;

type
  TForm1 = class(TForm)
    IdTCPServer1: TIdTCPServer;
    btnStartStop: TButton;
    Memo_Userlist: TMemo;
    procedure btnStartStopClick(Sender: TObject);
    procedure IdTCPServer1Execute(AContext: TIdContext);
    procedure IdTCPServer1Connect(AContext: TIdContext);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure IdTCPServer1Disconnect(AContext: TIdContext);
  private
    { Private declarations }
  public
    { Public declarations }
    CmdList : TStringList;
    UsrList : TStringList;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btnStartStopClick(Sender: TObject);
begin
   self.IdTCPServer1.Active := not Self.IdTCPServer1.Active;

   if self.IdTCPServer1.Active then
      self.btnStartStop.Caption := 'Stop'
   else self.btnStartStop.Caption := 'Start';
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
   self.CmdList := TStringList.Create;
   self.CmdList.Sorted := True;

   self.CmdList.Add('login');
   self.CmdList.Add('broadcast');
   self.CmdList.Add('private');
   self.CmdList.Add('list');
   self.CmdList.Add('logout');

   UsrList := TStringList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   FreeAndNil(self.CmdList);
   FreeAndNil(self.UsrList);
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
begin
   AContext.Connection.IOHandler.WriteLn('who');
end;

procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
var
   userIndex : integer;

begin
  userIndex := self.UsrList.IndexOfObject(AContext);

  if userIndex > -1 then begin
     self.UsrList.Delete(userIndex);

     self.Memo_Userlist.Lines.Clear;
     self.Memo_Userlist.Lines.AddStrings(self.UsrList);
  end;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
   tempStr : string;
   cmd, data, username : string;
   cmdIndex, userIndex : integer;
  count: Integer;
  tmpContext : TIdContext;
begin
   //
   tempStr := AContext.Connection.IOHandler.ReadLn();
   //ShowMessage('I got msg:' + tempStr);
   //AContext.Connection.IOHandler.WriteLn('Hello, I got your msg:' + tempStr);

   cmd := Fetch(tempStr, ' ');
   cmdIndex := self.CmdList.IndexOf(cmd);

   case cmdIndex of
         0 : {$REGION 'broadcast'} begin
             userIndex := self.UsrList.IndexOfObject(AContext);

             if userIndex > -1 then begin
               username := self.UsrList.Strings[userIndex];
               for count := 0 to self.UsrList.Count - 1 do begin
                   tmpContext := TIdContext(self.UsrList.Objects[count]);

                   if Assigned(tmpContext) then begin
                      tmpContext.Connection.IOHandler.Writeln(username + 'boardcast:' + tempStr);
                   end;
               end;
             end;
         end; {$ENDREGION}

         1 : {$REGION 'list'} begin
             tempStr := '';

             for count := 0 to self.UsrList.Count - 1 do
             begin
               if count = 0 then
                  tempStr := self.UsrList.Strings[count]
               else
                   tempStr := tempStr + #9 + self.UsrList.Strings[count];
             end;

             AContext.Connection.IOHandler.WriteLn(tempStr);
         end; {$ENDREGION}

         2 : {$REGION 'Login'} begin
             if self.UsrList.IndexOf(tempStr) = -1 then  begin
                self.UsrList.AddObject(tempStr, AContext);
                self.Memo_Userlist.Lines.Clear;
                self.Memo_Userlist.Lines.AddStrings(self.UsrList);
             end else begin
                 AContext.Connection.IOHandler.WriteLn('username exists');
             end;
         end; {$ENDREGION}

         3 : {$REGION 'logout'} begin
             if self.UsrList.IndexOf(tempStr) <> -1 then  begin
                userIndex := self.UsrList.IndexOf(tempStr);
                self.UsrList.Delete(userIndex);
                self.Memo_Userlist.Lines.Clear;
                self.Memo_Userlist.Lines.AddStrings(self.UsrList);
             end;
         end; {$ENDREGION}

         4 : {$REGION 'private'} begin
             username := Fetch(tempStr, ' ');

             userIndex := self.UsrList.IndexOf(username);

             if userIndex > -1 then begin
                tmpContext := TIdContext(self.UsrList.Objects[userIndex]);
                tmpContext.Connection.IOHandler.Write(username + 'private msg:' + tempStr);
             end;
         end; {$ENDREGION}
   end;
end;

end.
