unit MFChat;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, SRVSkinManager, ImgList, StdCtrls, SRVControl, SRVComboBox,
  SRVListBox, SRVEdit, SRVTypeItems, SRVPanel, SRVTabSet, SRVButton;

type
  TfrmChat = class(TForm)
    ImgListStatus: TImageList;
    SRVSkinManager1: TSRVSkinManager;
    pnlContact: TSRVPanel;
    lstUsers: TSRVListBox;
    pnlContent: TSRVPanel;
    TabChat: TSRVTabSet;
    SRVPanel1: TSRVPanel;
    cbStatus: TSRVComboBox;
    btnStatus: TSRVButton;
    procedure btnStatusClick(Sender: TObject);
    procedure lstUsersClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure TabChatChange(Sender: TObject);
    procedure TabChatCloseTab(Sender: TSRVTabSet; TabIndex: Integer;
      var CanClose: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
    AvatarsDir: String;
    function  FindGroup(GroupId : Integer) : Integer;
    function  FindUserTab(UserId : Integer) : Integer;
    function  FindChatEditor(UserId : Integer): TFrame;
    procedure AddGroup(GroupName: String; GroupId: Word);
    procedure AddUser(UserName: String; UserId: Integer; GroupId, Status: Word);
    procedure AddTabChat(UserName : String; UserId : Integer; Status: Word);

    procedure GenerateGroups();
    procedure GenerateListUsers();
  end;

var
  frmChat: TfrmChat;
  MyUserName : String;
  MyUserId : Integer;

implementation

uses MFSubStatus, MChatForm;

{$R *.dfm}

var
  CurrentChatEditor : TframeChatEditor = nil;
{------------------------------------------------------------------------------}
procedure TfrmChat.FormCreate(Sender: TObject);
begin
  TabChat.Tabs.Clear;
  cbStatus.ItemIndex := 2;

  MyUserName := 'Me';
  MyUserId := 1000;
  AvatarsDir := ExtractFilePath(Application.ExeName)+'Avatars\';

  GenerateGroups();
  GenerateListUsers();
end;
{------------------------------------------------------------------------------}
// Returns the index of item (in lstUsers) representing the specified user group
function TfrmChat.FindGroup(GroupId : Integer) : Integer;
var
     i : Integer;
begin
  Result := 0;
  for i:=0 to lstUsers.Items.Count-1 do
    with lstUsers.Items[i] do
      If (Indent = 0) and (Tag = GroupId) then begin
        Result := i;
        Break;
      end;
end;
{------------------------------------------------------------------------------}
// Returns the index of tab (in TabChat) representing the specified user group
function TfrmChat.FindUserTab(UserId : Integer) : Integer;
var
     i : Integer;
begin
  Result := -1;
  for i:=0 to TabChat.Tabs.Count-1 do
    with TabChat.Tabs[i] do
      If (Tag = UserId) then begin
        Result := i;
        Break;
      end;
end;
{------------------------------------------------------------------------------}
// Adds user group in lstUsers
procedure TfrmChat.AddGroup(GroupName: String; GroupId: Word);
var
  LI : TSRVLBoxItem;
begin
  LI := lstUsers.AppendItem(GroupName, -1, -1, 0, True, False, [fsBold], clHighlight,
    clInfoBk, 'Arial', True,
    [srvioShowCheckBox, srvioShowText, srvioCanHaveChildren]);
  LI.Tag := GroupId;
  lstUsers.Repaint;
end;
{------------------------------------------------------------------------------}
// Adds user in lstUsers
procedure TfrmChat.AddUser(UserName: String; UserId: Integer; GroupId, Status: Word);
var
     Index : Integer;
     LI : TSRVLBoxItem;
begin
  Index := FindGroup(GroupId) + 1;
  LI := lstUsers.InsertItem(Index, UserName, Status, Status, 10, True, False, [],
    clBlack, clNone, 'Arial', False,
    [srvioShowCheckBox, srvioShowImage, srvioShowText, srvioCanSelect, srvioCanHaveChildren]);
  LI.Tag := UserId;
  lstUsers.Repaint;
end;
{------------------------------------------------------------------------------}
// Adds user groups
procedure TfrmChat.GenerateGroups();
begin
  Randomize;
  AddGroup('General', 0);
  AddGroup('Work', 1);
  AddGroup('Friends', 2);
  AddGroup('Other', 3);
end;
{------------------------------------------------------------------------------}
// Add users
procedure TfrmChat.GenerateListUsers();
begin
  Randomize;
  AddUser('Qwery',  1, Random(4), Random(15));
  AddUser('Anabel', 9, Random(4), Random(15));
  AddUser('Martin', 15, Random(4), Random(15));
  AddUser('John',   17, Random(4), Random(15));
  AddUser('Ilya',   32, Random(4), Random(15));
  AddUser('Sergey', 50, Random(4), Random(15));
  AddUser('Anna',   55, Random(4), Random(15));
  AddUser('Joy',    63, Random(4), Random(15));
  AddUser('Luke',   71, Random(4), Random(15));
  AddUser('Obama',  86, Random(4), Random(15));
end;
{------------------------------------------------------------------------------}
// Returns a chat editor window for the given user
function TfrmChat.FindChatEditor(UserId : Integer): TFrame;
begin
  Result := FindComponent('ChatForm_' + IntToStr(UserId)) as TFrame;
end;
{------------------------------------------------------------------------------}
// Adds a tab for the given User in TabChat
procedure TfrmChat.AddTabChat(UserName : String; UserId : Integer; Status: Word);
var
     TI : TSRVTabItem;
     i : Integer;
     ChatForm : TframeChatEditor;
begin
  TabChat.BeginUpdate;
  TI := TSRVTabItem(TabChat.Tabs.Add);
  TI.Text := UserName;
  TI.ImageIndex := Status;
  TI.Tag := UserId;

  // Creating a new chat editor window for this tab
  CurrentChatEditor := TframeChatEditor.Create(Self);
  CurrentChatEditor.Name := 'ChatForm_' + IntToStr(UserId);
  CurrentChatEditor.Parent := pnlContent;
  CurrentChatEditor.Align := alClient;
  CurrentChatEditor.ImgUser.Picture.LoadFromFile(AvatarsDir + IntToStr(UserId mod 3) + '.jpg');
  CurrentChatEditor.ImgMy.Picture.LoadFromFile(AvatarsDir + IntToStr(MyUserId mod 3) + '.jpg');
  CurrentChatEditor.Show();
  // Hiding other chat windows, showing this new window
  for i:= 0 to TabChat.Tabs.Count-1 do begin
    ChatForm := TframeChatEditor(FindChatEditor(TabChat.Tabs[i].Tag));
    if Assigned(ChatForm) and (CurrentChatEditor <> ChatForm) then
      ChatForm.Hide();
  end;
  TabChat.TabIndex := TI.Index;
  TabChat.EndUpdate;
end;
{------------------------------------------------------------------------------}
// Adding status
procedure TfrmChat.btnStatusClick(Sender: TObject);
begin
  If frmSubStatus.ShowModal = mrOk then begin
    Application.MessageBox('Not implemented in this demo', 'Not implemented',
      MB_OK or MB_ICONEXCLAMATION);
  end;
end;
{------------------------------------------------------------------------------}
// Clicking in the user list: creating or showing an editor for this user
procedure TfrmChat.lstUsersClick(Sender: TObject);
var
     LI : TSRVLBoxItem;
begin
  If lstUsers.ItemIndex = -1 then
    Exit;
  LI := lstUsers.Items[lstUsers.ItemIndex];
  If LI.Indent > 0 then
    If FindUserTab(LI.Tag) = -1 then
      AddTabChat(LI.Caption, LI.Tag, LI.ImageIndex)
    else
      TabChat.TabIndex := FindUserTab(LI.Tag);
end;
{------------------------------------------------------------------------------}
// On changing user in TabChat...
procedure TfrmChat.TabChatChange(Sender: TObject);
var
     i : Integer;
     ChatForm : TframeChatEditor;
begin
  If TabChat.TabIndex = -1 then
    Exit;
  // Showing a editor form for the current tab
  CurrentChatEditor := TframeChatEditor(FindChatEditor(TabChat.Tabs[TabChat.TabIndex].Tag));
  if Assigned(CurrentChatEditor) then
    CurrentChatEditor.Show();
  // Hiding all other editor forms
  for i:= 0 to TabChat.Tabs.Count-1 do begin
    ChatForm := TframeChatEditor(FindChatEditor(TabChat.Tabs[i].Tag));
    if Assigned(ChatForm) and (CurrentChatEditor <> ChatForm) then
      ChatForm.Hide();
  end;
end;
{------------------------------------------------------------------------------}
// On closing tag
procedure TfrmChat.TabChatCloseTab(Sender: TSRVTabSet; TabIndex: Integer;
  var CanClose: Boolean);
var ChatForm : TframeChatEditor;
begin
  ChatForm := TframeChatEditor(FindChatEditor(TabChat.Tabs[TabIndex].Tag));
  ChatForm.Free;
end;

end.
