unit chat;

interface

uses
  Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, StdCtrls, ExtCtrls, jpeg, XPMan, WSocketS, WSocket;

type
  TChatToK = class(TForm)
    ImageFond: TImage;
    PanelConnexion: TPanel;
    LabelConnexion: TLabel;
    RBClient: TRadioButton;
    RBServeur: TRadioButton;
    PanelClient: TPanel;
    RBServeurToK: TRadioButton;
    RBAutreServeur: TRadioButton;
    EditIPServeur: TEdit;
    PanelChat: TPanel;
    MemoChat: TMemo;
    EditPseudo: TEdit;
    EditMessage: TEdit;
    ButtonEnvoyer: TButton;
    MainMenu1: TMainMenu;
    Fichier1: TMenuItem;
    Rinitialiser1: TMenuItem;
    Quitter1: TMenuItem;
    MemoConnectes: TMemo;
    XPManifest1: TXPManifest;
    WSocketClient: TWSocket;
    WSocketServer: TWSocketServer;
    ButtonConnexion: TButton;
    MemoIPperso: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure RBClientClick(Sender: TObject);
    procedure RBServeurClick(Sender: TObject);
    procedure RBServeurToKClick(Sender: TObject);
    procedure RBAutreServeurClick(Sender: TObject);
    procedure EditIPServeurClick(Sender: TObject);
    procedure EditIPServeurChange(Sender: TObject);
    procedure EditIPServeurExit(Sender: TObject);
    procedure Quitter1Click(Sender: TObject);
    procedure ButtonConnexionClick(Sender: TObject);
    procedure WSocketClientSessionConnected(Sender: TObject;
      ErrCode: Word);
    procedure WSocketClientSessionClosed(Sender: TObject; ErrCode: Word);
    procedure ButtonEnvoyerClick(Sender: TObject);
    procedure WSocketServerDataAvailable(Sender: TObject; ErrCode: Word);
    procedure WSocketClientDataAvailable(Sender: TObject; ErrCode: Word);
    procedure EditMessageClick(Sender: TObject);
    procedure EditMessageChange(Sender: TObject);
    procedure WSocketServerClientConnect(Sender: TObject;
      Client: TWSocketClient; Error: Word);
    procedure WSocketClientSocksError(Sender: TObject; Error: Integer;
      Msg: String);
    procedure EditIPServeurKeyPress(Sender: TObject; var Key: Char);
    procedure MemoIPpersoClick(Sender: TObject);
    procedure MemoIPpersoChange(Sender: TObject);
    procedure MemoIPpersoExit(Sender: TObject);
    procedure MemoIPpersoKeyPress(Sender: TObject; var Key: Char);
    procedure EditMessageKeyPress(Sender: TObject; var Key: Char);
    procedure EditPseudoExit(Sender: TObject);
    procedure EditPseudoClick(Sender: TObject);
    procedure EditPseudoKeyPress(Sender: TObject; var Key: Char);
    procedure WSocketServerClientDisconnect(Sender: TObject;
      Client: TWSocketClient; Error: Word);
  private
    { Déclarations privées }
  public
    { Déclarations publiques }
  end;

var
  ChatToK: TChatToK;
  ip : string;  // adresse ip
  ExPseudo : string;
  i : integer;

implementation

{$R *.dfm}


{##############################################################################
############################### INITIALISATION ################################
##############################################################################}


procedure TChatToK.FormCreate(Sender: TObject);       //  -- Lancement --  //
begin
  ButtonConnexion.Enabled := False;
  ImageFond.Visible       := True;
  PanelChat.Visible       := True;
  ButtonEnvoyer.Enabled   := False;
  EditMessage.Enabled     := False;
  EditMessage.Text        := '<Message>';
  EditPseudo.Text         := '<Pseudo>';
  EditPseudo.Enabled      := True;
  MemoChat.ReadOnly       := True;
  MemoChat.Clear;
  MemoConnectes.ReadOnly  := True;
  MemoConnectes.Clear;
  PanelClient.Visible     := False;
  EditIPServeur.Visible   := False;
  EditIPServeur.Text      := 'IP du Serveur';
  MemoIpPerso.lines       := WSocket.LocalIPList;
  MemoIpPerso.Visible     := False;
  RBServeurToK.Checked    := False;
  RBAutreServeur.Checked  := False;
  PanelConnexion.Visible  := True;
  LabelConnexion.Visible  := True;
  RBClient.Checked        := False;
  RBServeur.Checked       := False;
  ButtonConnexion.Caption := 'Connexion';
  WSocketClient.Close;
  WSocketServer.Close;
end;

procedure TChatToK.RBClientClick(Sender: TObject);    //  -- RBClient --  //
begin
  PanelClient.Visible     := True;
  PanelClient.Enabled     := True;
  MemoIPPerso.Visible     := False;
  EditIPServeur.Visible   := False;
  ButtonConnexion.Enabled := False;
  ButtonConnexion.Caption := 'Connexion';
end;

procedure TChatToK.RBServeurClick(Sender: TObject);   //  -- RBServeur --  //
begin
  PanelClient.Visible     := False;
  MemoIPperso.Visible     := True;
  MemoIPPerso.ReadOnly    := False;
  ButtonConnexion.Enabled := False;
  ButtonConnexion.Caption := 'Création';
  MemoIpPerso.Lines       := WSocket.LocalIPList ;
  ip                      := MemoIpPerso.Text;
end;

procedure TChatToK.RBServeurToKClick(Sender: TObject);   //  -- RBToK --  //
begin
  ip :=  '82.242.23.80';  //  Adresse Ip du Serveur ToK (Saadik' : 82.123.227.244 ; Thorn : 82.242.23.80)
  ButtonConnexion.Enabled := True;
end;

procedure TChatToK.RBAutreServeurClick(Sender: TObject); // -- RBAutreS -- //
begin
  EditIPserveur.Visible := True;
end;

procedure TChatToK.EditIPServeurClick(Sender: TObject); //- IpServeur Clic -//
begin
  EditIPserveur.Clear;
end;

procedure TChatToK.EditIPServeurChange(Sender: TObject); //-IPServeur Change-//
begin
  if EditIPServeur.Text <> '' then
  ButtonConnexion.Enabled := True;
end;

procedure TChatToK.EditIPServeurExit(Sender: TObject);  //- IpServeur Exit -//
begin
  ip := EditIPServeur.Text;
end;


procedure TChatToK.MemoIPpersoClick(Sender: TObject);
begin
  if MemoIPperso.Text = ('') then
    MemoIPPerso.Clear ;
end;

procedure TChatToK.MemoIPpersoChange(Sender: TObject);
begin
  ButtonConnexion.Enabled := true
end;

procedure TChatToK.MemoIPpersoExit(Sender: TObject);
begin
  ip := MemoIPperso.Text ;
end;

procedure TChatToK.MemoIPpersoKeyPress(Sender: TObject; var Key: Char);
begin
  if key =#13 then
    begin
      ButtonConnexion.Click;
      key := #0;
    end;
end;


procedure TChatToK.Quitter1Click(Sender: TObject);
begin
  if ButtonConnexion.Caption = ('Déconnexion') then
        begin
          ButtonConnexion.Caption := 'Déconnexion en cours...';
          WSocketClient.SendStr(EditPseudo.Text +' vient de se déconnecter');
          Sleep(300);
          WSocketClient.Close;
        end
  else
    if ButtonConnexion.Caption = ('Quitter') then
    begin
          ButtonConnexion.Caption := 'Arret en cours...';
          i := 0;
          while (i <> WSocketServer.ClientCount) do
            begin;
              WSocketServer.Client[i].SendStr('  (¯`·._)  Serveur Arrété  (¯`·._) ');
              i := i + 1;
            end;
          Sleep(400);
          WSocketServer.Close;
    end;
  Application.Terminate;
end;



{##############################################################################
################################## CONNEXIONS #################################
##############################################################################}


procedure TChatToK.ButtonConnexionClick(Sender: TObject);
begin
                        //  -----   Client   -----  //
 if EditPseudo.Text <> '<Pseudo>' then
  if  RBClient.Checked = true then
      if ButtonConnexion.Caption = 'Connexion' then   // Si on est pas connecté
        begin
          ButtonConnexion.Caption := 'Connexion en cours...';
          WSocketClient.Addr   := ip;
          WSocketClient.Port   := '42';
          WSocketClient.Proto  := 'tcp';
          WSocketClient.Connect;
        end
      else                                           //Si on n'est pas connecté
        begin
          ButtonConnexion.Caption := 'Déconnexion en cours...';
          WSocketClient.SendStr(EditPseudo.Text +' vient de se déconnecter');
          MemoChat.Lines.Add(EditPseudo.Text +' vient de se déconnecter');
          WSocketClient.Close;
        end
                       //  -----   Serveur   -----  //
  else
      if ButtonConnexion.Caption = 'Création' then //Si le serveur n'existe pas
        begin
          ButtonConnexion.Caption   :=  'Création en cours...';
          WSocketServer.Addr      := '0.0.0.0';
          WSocketServer.Port      := '42';
          WSocketServer.Proto     := 'tcp';
          WSocketServer.Listen;
          EditMessage.Enabled     := True;
          MemoIPperso.ReadOnly    := True;
          PanelConnexion.Enabled  := False;
          MemoChat.Lines.Add('  (¯`·._)  Serveur Démarré ! (¯`·._) ');
          ButtonConnexion.Caption := 'Quitter';
        end
      else
        begin
          ButtonConnexion.Caption := 'Arret en cours...';
          i := 0;
          while (i <> WSocketServer.ClientCount) do
            begin;
              WSocketServer.Client[i].SendStr('  (¯`·._)  Serveur Arrété ! (¯`·._) ');
              i := i + 1;
            end;
          Sleep(400);
          Application.Terminate;
        end
 else
    ShowMessage('Et ton pseudo ?');
end;

                 //  -----   Connexion du Client   -----  //


procedure TChatToK.WSocketClientSessionConnected(Sender: TObject;
  ErrCode: Word);
begin
  EditMessage.Enabled := True;
  PanelConnexion.Enabled := False;
  PanelClient.Enabled := False;
  WSocketClient.SendStr(TimeToStr(Time)+'  >  '+EditPseudo.Text+
                                                    ' vient de se connecter');
  ButtonConnexion.Caption := 'Déconnecter';
end;


                 //  -----   Déconnexion du Client   -----  //

procedure TChatToK.WSocketClientSessionClosed(Sender: TObject;
  ErrCode: Word);
begin
  ShowMessage('Déconnecté du Serveur.');
  ButtonConnexion.Enabled := False;
  ImageFond.Visible       := True;
  PanelChat.Visible       := True;
  ButtonEnvoyer.Enabled   := False;
  EditMessage.Enabled     := False;
  EditMessage.Text        := '<Message>';
  EditPseudo.Text         := '<Pseudo>';
  EditPseudo.Enabled      := True;
  MemoChat.ReadOnly       := True;
  MemoChat.Clear;
  MemoConnectes.ReadOnly  := True;
  MemoConnectes.Clear;
  PanelClient.Visible     := False;
  EditIPServeur.Visible   := False;
  EditIPServeur.Text      := 'IP du Serveur';
  MemoIpPerso.Lines        := WSocket.LocalIPlist;
  MemoIpPerso.Visible     := False;
  RBServeurToK.Checked    := False;
  RBAutreServeur.Checked  := False;
  PanelConnexion.Visible  := True;
  PanelConnexion.Enabled  := True;
  LabelConnexion.Visible  := True;
  RBClient.Checked        := False;
  RBServeur.Checked       := False;
  ButtonConnexion.Caption := 'Connexion';
  WSocketClient.Close;
  WSocketServer.Close;
end;

procedure TChatToK.WSocketClientSocksError(Sender: TObject; Error: Integer;
  Msg: String);
begin
  ShowMessage('Erreur !');
end;

{##############################################################################
####################### ENVOI ET RECEPTION DE MESSAGES ########################
##############################################################################}

                        // Envoi de Messages //
procedure TChatToK.ButtonEnvoyerClick(Sender: TObject);
begin
  if (EditMessage.Text <> '') then
    if RBClient.Checked = True then
    begin
      WSocketClient.SendStr(TimeToStr(Time)+' > '+EditPseudo.Text+' > '+
                                                          EditMessage.Text);
    end
    else
      begin
        i := 0;
          while (i <> WSocketServer.ClientCount) do
            begin;
              WSocketServer.Client[i].SendStr(TimeToStr(Time)+' > '+
              EditPseudo.Text+' > '+EditMessage.Text);
              i := i + 1;
            end;
          MemoChat.Lines.Add(TimeToStr(Time)+' > '+EditPseudo.Text+' > '+
                                                          EditMEssage.Text);
      end;
  EditMessage.Clear;
end;

                      // Reception de Messages //

procedure TChatToK.WSocketServerDataAvailable(Sender: TObject;
  ErrCode: Word);
var
  msg: string;
  i: integer;

begin
  i := 0;
    with sender as TWSocket do
      begin
        msg := ReceiveStr;
        MemoChat.Lines.Add(msg);
      end;
     while (i <> WSocketServer.ClientCount) do
        begin
          WSocketServer.Client[i].SendStr(msg);
          i := i + 1;
        end;
end;


procedure TChatToK.WSocketClientDataAvailable(Sender: TObject;
  ErrCode: Word);
begin
    With Sender as TWSocket do
    MemoChat.Lines.Add(ReceiveStr);
    if  WSocketClient.ReceiveStr = ('Serveur Arreté') then
    begin
      ShowMessage('Erreur Serveur. Déconnecté.');
      ButtonConnexion.Click;
    end;
end;

procedure TChatToK.EditMessageClick(Sender: TObject);
begin
  EditMessage.Clear;
end;

procedure TChatToK.EditMessageChange(Sender: TObject);
begin
  If EditMessage.Text <> '' then
    ButtonEnvoyer.Enabled := True;
end;

procedure TChatToK.WSocketServerClientConnect(Sender: TObject;
  Client: TWSocketClient; Error: Word);
begin
  Client.OnDataAvailable := WSocketServerDataAvailable;
  MemoConnectes.Lines.Add(Client.GetPeerAddr);
end;

procedure TChatToK.EditIPServeurKeyPress(Sender: TObject; var Key: Char);
begin
  if key =#13 then
    begin
      ButtonConnexion.Click;
      key := #0;
    end;
end;

procedure TChatToK.EditMessageKeyPress(Sender: TObject; var Key: Char);
begin
  if key =#13 then
    begin
      ButtonEnvoyer.Click;
      key := #0;
    end;
end;

procedure TChatToK.EditPseudoExit(Sender: TObject);

begin
        if (ButtonConnexion.Caption = 'Déconnecter') then
          WSocketClient.SendStr(WSocketClient.GetPeerAddr+ Expseudo+
                      ' : vient de changer son pseudo en : '+EditPseudo.Text)
        else
          begin
            i := 0;
              while (i <> WSocketServer.ClientCount) do
                begin
                  WSocketServer.Client[i].SendStr
                          (WSocketServer.Client[i].GetPeerAddr+' > '+
                          Expseudo+' : vient de changer son pseudo en : '
                                                            +EditPseudo.Text);
                  MemoChat.Lines.Add(WSocketServer.Client[i].GetPeerAddr
                  +' > '+Expseudo+' : vient de changer son pseudo en : '
                                                            +EditPseudo.Text);
                  i := i + 1;
                end;
          end;
end;

procedure TChatToK.EditPseudoClick(Sender: TObject);
begin
  Expseudo := EditPseudo.Text
end;

procedure TChatToK.EditPseudoKeyPress(Sender: TObject; var Key: Char);
begin
  if key =#13 then
    begin
        if (ButtonConnexion.Caption = 'Déconnecter') then
          WSocketClient.SendStr(WSocketClient.GetPeerAddr+ Expseudo+
                      ' : vient de changer son pseudo en : '+EditPseudo.Text)
        else
          begin
            i := 0;
              while (i <> WSocketServer.ClientCount) do
                begin
                  WSocketServer.Client[i].SendStr
                          (WSocketServer.Client[i].GetPeerAddr+' > '+
                          Expseudo+' : vient de changer son pseudo en : '
                                                            +EditPseudo.Text);
                  MemoChat.Lines.Add(TimeToStr(Time)+' > '+Expseudo+
                    ' : vient de changer son pseudo en : '+EditPseudo.Text);
                  i := i + 1;
                end;
          end;
      key := #0;
    end;
end;

procedure TChatToK.WSocketServerClientDisconnect(Sender: TObject;
  Client: TWSocketClient; Error: Word);
begin
  MemoConnectes.Lines.Delete(MemoConnectes.Lines.IndexOf(Client.GetPeerAddr));
end;

end.

