{*********************************************************

 SlavaNap source code.

 Copyright 2001,2002 by SlavaNap development team
 Released under GNU General Public License

 Latest version is available at
 http://www.slavanap.org

**********************************************************

 Unit: ChannelForm

 Channel Window

*********************************************************}
unit ChannelForm;

interface

uses
  Windows, Messages, SysUtils, Classes, Classes2, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, SlavaSplitter, ComCtrls, Menus, ClipBrd,
  StringResources;

type
  TSlavaNapChannelWindow = class(TForm)
    Panel_Bottom: TPanel;
    Edit: TEdit;
    Panel_Client: TPanel;
    Panel_Right: TPanel;
    SlavaSplitter1: TSlavaSplitter;
    Panel_Left: TPanel;
    Log: TRichEdit;
    Users: TListView;
    PopupMenu1: TPopupMenu;
    Mnu_Im: TMenuItem;
    Mnu_Whois: TMenuItem;
    N1: TMenuItem;
    Mnu_Op: TMenuItem;
    Mnu_Deop: TMenuItem;
    Mnu_Voice: TMenuItem;
    Mnu_Unvoice: TMenuItem;
    Mnu_Ban: TMenuItem;
    Mnu_Banip: TMenuItem;
    Mnu_Kick: TMenuItem;
    N2: TMenuItem;
    Mnu_CopyName: TMenuItem;
    Timer1: TTimer;
    Popup_Log: TPopupMenu;
    Mnu_Log_Clear: TMenuItem;
    Mnu_Log_Copy: TMenuItem;
    Mnu_Level: TMenuItem;
    Mnu_Level0: TMenuItem;
    Mnu_Level1: TMenuItem;
    Mnu_Level2: TMenuItem;
    Mnu_Level3: TMenuItem;
    Mnu_Level4: TMenuItem;
    Mnu_Muzzle: TMenuItem;
    Mnu_Friends: TMenuItem;
    Mnu_Browse: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Panel_BottomResize(Sender: TObject);
    procedure LogChange(Sender: TObject);
    procedure usersResize(Sender: TObject);
    procedure CreateParams(var Params: TCreateParams); override;
    procedure editKeyPress(Sender: TObject; var Key: Char);
    procedure FormDestroy(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure editKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    function ProcessCommand(Command: string): Boolean;
    procedure Panel_ClientResize(Sender: TObject);
    procedure DrawPopupItem(Sender: TObject; ACanvas: TCanvas;
      ARect: TRect; Selected: Boolean);
    procedure MeasurePopupItem(Sender: TObject; ACanvas: TCanvas;
      var Width, Height: Integer);
    procedure Mnu_ImClick(Sender: TObject);
    procedure Mnu_WhoisClick(Sender: TObject);
    procedure Mnu_OpClick(Sender: TObject);
    procedure Mnu_DeopClick(Sender: TObject);
    procedure Mnu_VoiceClick(Sender: TObject);
    procedure Mnu_UnvoiceClick(Sender: TObject);
    procedure Mnu_BanClick(Sender: TObject);
    procedure Mnu_BanipClick(Sender: TObject);
    procedure Mnu_KickClick(Sender: TObject);
    procedure Mnu_CopyNameClick(Sender: TObject);
    procedure MyWndProc(var Message: TMessage);
    procedure Timer1Timer(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure Mnu_Log_CopyClick(Sender: TObject);
    procedure Mnu_Log_ClearClick(Sender: TObject);
    procedure logMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Mnu_LevelClick(Sender: TObject);
    procedure Mnu_MuzzleClick(Sender: TObject);
    procedure Mnu_FriendsClick(Sender: TObject);
    procedure Mnu_BrowseClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Channel: string;
    Topic: string;
    Flash_Count: Integer;
    History: TMyStringList;
    Last: Integer;
    procedure AddMessage(Color: Integer; Text: string);
    procedure ChangeColors;
  end;

implementation

uses STypes, Vars, Constants, SlavaMenu, Console, Handler, MainForm, Lang,
  Languages;

{$R *.DFM}

procedure TSlavaNapChannelWindow.MyWndProc(var Message: TMessage);
begin
  WndProc(Message);
  if Message.Msg = WM_ACTIVATE then
    Flash_Count := 100;
end;

procedure TSlavaNapChannelWindow.CreateParams(var Params: TCreateParams);
begin
  inherited CreateParams(Params);
  Params.ExStyle := Params.ExStyle and not WS_EX_TOOLWINDOW or WS_EX_APPWINDOW;
end;

procedure TSlavaNapChannelWindow.FormCreate(Sender: TObject);
var
  R: TRect;
begin
  SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0);
  Top := (R.Top + R.Bottom - Height) div 2;
  Left := (R.Right + R.Left - Width - 4) div 2;
  History := TMyStringList.Create;
  WindowProc := MyWndProc;
  SetActiveWindow(Handle);
  Flash_Count := 100;
  Log.Lines.Clear;
  Edit.Text := '';
  SetFont(Self.Font);
  Mnu_Im.Caption := GetLangI(LNG_CHMNU_IM);
  Mnu_Whois.Caption := GetLangI(LNG_CHMNU_WHOIS);
  Mnu_Browse.Caption := RS_ChannelForm_LNG_CHMNU_BROWSE;
  Mnu_Friends.Caption := GetLangI(LNG_CHMNU_FRIENDS);
  Mnu_Op.Caption := GetLangI(LNG_CHMNU_OP);
  Mnu_Deop.Caption := GetLangI(LNG_CHMNU_DEOP);
  Mnu_Voice.Caption := GetLangI(LNG_CHMNU_VOICE);
  Mnu_Unvoice.Caption := GetLangI(LNG_CHMNU_UNVOICE);
  Mnu_Ban.Caption := GetLangI(LNG_CHMNU_BAN);
  Mnu_Banip.Caption := GetLangI(LNG_CHMNU_BANIP);
  Mnu_Kick.Caption := GetLangI(LNG_CHMNU_KICK);
  Mnu_Level.Caption := GetLangI(LNG_CHMNU_LEVEL);
  Mnu_Muzzle.Caption := GetLangI(LNG_CHMNU_MUZZLE);
  Mnu_CopyName.Caption := GetLangI(LNG_CHMNU_COPYNAME);
  Mnu_Log_Clear.Caption := GetLangI(LNG_MENU_CLEAR);
  Mnu_Log_Copy.Caption := GetLangI(LNG_MENU_COPY);
end;

procedure TSlavaNapChannelWindow.FormShow(Sender: TObject);
begin
  ChangeColors;
  if WindowState = wsNormal then
  begin
    Width := Width + 1;
    Height := Height + 1;
  end;
  try
    Edit.SetFocus;
  except
  end;
  Panel_Right.Width := Panel_Right.Width + 1;
end;

procedure TSlavaNapChannelWindow.Panel_BottomResize(Sender: TObject);
begin
  Edit.Width := Panel_Bottom.Width - 4;
end;

procedure TSlavaNapChannelWindow.LogChange(Sender: TObject);
var
  C1: TRichEdit;
begin
  if Sender Is TRichEdit then
  begin
    C1 := Sender as TRichEdit;
    C1.SelStart := C1.Perform(EM_LINEINDEX, C1.Lines.Count, 0);
    C1.Perform(EM_SCROLLCARET, 0, 0);
    Exit;
  end;
end;

procedure TSlavaNapChannelWindow.UsersResize(Sender: TObject);
begin
  Users.Columns.Items[0].Width := Users.Width - 21;
end;

procedure TSlavaNapChannelWindow.EditKeyPress(Sender: TObject;
  var Key: Char);
begin
  if Key = #13 then
    Key := #0;
end;

procedure TSlavaNapChannelWindow.AddMessage(Color: Integer; Text: string);
begin
  try
    if Log.Lines.Count > 1000 then
    begin
      Log.Lines.BeginUpdate;
      while Log.Lines.Count > 1000 do
        Log.Lines.Delete(0);
      Log.Lines.EndUpdate;
    end;
    Log.SelLength := 0;
    Log.SelStart := Length(Log.Text);
    Log.SelAttributes.Color := Color;
    if Channels_Timestamp then
      Log.Lines.Add(GetLogTime + Text)
    else
      Log.Lines.Add(Text);
    LogChange(Log);
    if Chat_Flash then
      Flash_Count := 0;
  except
  end;
  try
    if Switch_Chat then
      Edit.SetFocus;
  except
  end;
end;

procedure TSlavaNapChannelWindow.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  History.Free;
  History := nil;
  if Cons_Channels <> nil then
    for I := Cons_Channels.Count - 1 downto 0 do
      if Cons_Channels.Items[I] = Self then
        Cons_Channels.Delete(I);
end;

procedure TSlavaNapChannelWindow.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action := caFree;
end;

procedure TSlavaNapChannelWindow.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  if Running then
    Cmd_List.AddDoubleCmd(MSG_CLIENT_PART, 0, Channel, '');
end;

function TSlavaNapChannelWindow.ProcessCommand(Command: string): Boolean;
begin
  Result := False;
  Command := LowerCase(Command);
  if Command = '>cls' then
  begin
    Log.Lines.Clear;
    Result := True;
  end;
end;

procedure TSlavaNapChannelWindow.EditKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var
  Str: string;
  B: Boolean;
begin
  case Key of
    13:
      try
        if not Running then Exit;
        Str := Edit.Text;
        B := False;
        if (Length(Str) > 0) then
        begin
          if Str[1] = '/' then
            Str[1] := '>';
          if Str[1] = '>' then
            B := ProcessCommand(Str);
        end;
        if not B then
          Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' ' + Str, '');
        Last := History.Add(Str) + 1;
        if History.Count > 100 then
        begin
          History.Delete(0);
          Dec(Last);
        end;
        Edit.Text := '';
      except
      end;
    38:
      begin // Up
        if Last > 0 then
        begin
          Dec(Last);
          Str := History.Strings[Last];
          Edit.SelectAll;
          Edit.SetSelTextBuf(PChar(Str));
        end
        else if History.Count > 0 then
        begin
          Str := History.Strings[0];
          Edit.SelectAll;
          Edit.SetSelTextBuf(PChar(Str));
        end;
      end;
    40:
      begin // Down
        if Last < (History.Count - 1) then
        begin
          Inc(Last);
          Str := History.Strings[Last];
          Edit.SelectAll;
          Edit.SetSelTextBuf(PChar(Str));
        end
        else
        begin
          Last := History.Count;
          Edit.Text := '';
        end;
      end;
  end;
end;

procedure TSlavaNapChannelWindow.Panel_ClientResize(Sender: TObject);
begin
  try
    Log.Invalidate;
    Users.Invalidate;
  except
  end;
end;

procedure TSlavaNapChannelWindow.DrawPopupItem(Sender: TObject;
  ACanvas: TCanvas; ARect: TRect; Selected: Boolean);
begin
  SlavaDrawPopupItem(Sender, ACanvas, ARect, Selected);
end;

procedure TSlavaNapChannelWindow.MeasurePopupItem(Sender: TObject;
  ACanvas: TCanvas; var Width, Height: Integer);
begin
  SlavaMeasurePopupItem(Sender, ACanvas, Width, Height);
end;

procedure TSlavaNapChannelWindow.Mnu_ImClick(Sender: TObject);
begin
  if not Running then Exit;
  if Users.SelCount <> 1 then Exit;
  if Users.Selected = nil then Exit;
  SlavaNapWindow.CreateChatWindow(Users.Selected.SubItems[0]);
end;

procedure TSlavaNapChannelWindow.Mnu_WhoisClick(Sender: TObject);
begin
  if not Running then Exit;
  if Users.SelCount <> 1 then Exit;
  if Users.Selected = nil then Exit;
  Cmd_List.AddDoubleCmd(MSG_CLIENT_WHOIS, 0, Users.Selected.SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_OpClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >Op ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_DeopClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >Deop ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_VoiceClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >Voice ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_UnvoiceClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >Unvoice ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_BanClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >Ban ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_BanipClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >Banip ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_KickClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >Kick ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_CopyNameClick(Sender: TObject);
begin
  if not Running then Exit;
  if Users.SelCount <> 1 then Exit;
  if Users.Selected = nil then Exit;
  Clipboard.AsText := Users.Selected.SubItems[0];
end;

procedure TSlavaNapChannelWindow.Timer1Timer(Sender: TObject);
begin
  if Flash_Count < 11 then
    FlashWindow(Handle, not Active);
  if Flash_Count = 11 then
    FlashWindow(Handle, False);
  Inc(Flash_Count);
end;

procedure TSlavaNapChannelWindow.FormActivate(Sender: TObject);
begin
  Flash_Count := 100;
end;

procedure TSlavaNapChannelWindow.ChangeColors;
begin
  Log.Color := slBackground;
  Log.Font.Color := slText;
  Users.Color := slBackground;
  Users.Font.Color := slText;
  Edit.Color := slBackground;
  Edit.Font.Color := slText;
end;

procedure TSlavaNapChannelWindow.Mnu_Log_CopyClick(Sender: TObject);
begin
  Log.CopyToClipboard;
end;

procedure TSlavaNapChannelWindow.Mnu_Log_ClearClick(Sender: TObject);
begin
  Log.Lines.Clear;
end;

procedure TSlavaNapChannelWindow.LogMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then
  begin
    Popup_Log.Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y);
  end;
end;

procedure TSlavaNapChannelWindow.Mnu_LevelClick(Sender: TObject);
var
  Str: string;
  I: Integer;
begin
  if Sender = Mnu_Level0 then
    Str := ' 0'
  else if Sender = Mnu_Level1 then
    Str := ' 1'
  else if Sender = Mnu_Level2 then
    Str := ' 2'
  else if Sender = Mnu_Level3 then
    Str := ' 3'
  else if Sender = Mnu_Level4 then
    Str := ' 4'
  else
    Exit;
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      // Cmd_List.AddDoubleCmd(MSG_CLIENT_SETUSERLEVEL, 0, Users.Items.Item[I].SubItems[0] + Str, '');
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >a Level ' +
        Users.Items.Item[I].SubItems[0] + Str, '');
end;

procedure TSlavaNapChannelWindow.Mnu_MuzzleClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_MUZZLEINV, 0,
        Users.Items.Item[I].SubItems[0] + ' Channel ' + Channel, '');
end;

procedure TSlavaNapChannelWindow.Mnu_FriendsClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to Users.Items.Count - 1 do
    if Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_PUBLIC, 0, Channel + ' >a Friends add ' +
        Users.Items.Item[I].SubItems[0], '');
end;

procedure TSlavaNapChannelWindow.Mnu_BrowseClick(Sender: TObject);
begin
  if not Running then Exit;
  if Users.SelCount <> 1 then Exit;
  if Users.Selected = nil then Exit;
  Cmd_List.AddDoubleCmd(MSG_CLIENT_BROWSE, 0, Users.Selected.SubItems[0], '');
end;

end.
