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

 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: MainForm

 SlavaNap main window

*********************************************************}
unit MainForm;

interface

{$I Defines.pas}

uses
  Windows, Messages, SysUtils, Classes2, Graphics, Controls, Forms, Dialogs,
  ComCtrls, SlavaSplitter, ExtCtrls, StdCtrls, IniFiles, ShellApi,
  ImgList, Menus, WinSock, ClipBrd, ChannelForm, ChatForm, STypes,
  WhoisForm, SlavaStrings, Mmsystem, Buttons, Classes, Spin,
  Class_Cmdlist, Class_CmdExList, Class_DoubleCmdList, Class_Cmd2List,
  BrowseForm, AnnounceForm, OfficeToolBar, RXShell, StringResources;

type
  TSlavaNapWindow = class(TForm)
    StatusBar1: TStatusBar;
    Dock_Toolbar: TksoOfficeDock;
    Client: TPanel;
    Panel_Console: TPanel;
    SlavaSplitter1: TSlavaSplitter;
    Pages: TPageControl;
    Sh_Log: TTabSheet;
    Sh_Users: TTabSheet;
    Dock_Log: TksoOfficeDock;
    Panel_Log: TPanel;
    Log_Main: TRichEdit;
    Log_Console: TRichEdit;
    Tray: TRxTrayIcon;
    Timer1: TTimer;
    Imagelist_Icons: TImageList;
    Imagelist_Digits: TImageList;
    Imagelist_Digits4: TImageList;
    Toolbar: TksoOfficeToolBar;
    Bar_Log: TksoOfficeToolBar;
    Sh_Registered: TTabSheet;
    Popup_Tray: TPopupMenu;
    Mnu_Tray_Show: TMenuItem;
    N1: TMenuItem;
    Mnu_Tray_Settings: TMenuItem;
    N2: TMenuItem;
    Mnu_Tray_Restart: TMenuItem;
    Mnu_Tray_Exit: TMenuItem;
    Sh_Hidden: TTabSheet;
    Img_Popup: TImage;
    Timer2: TTimer;
    KsoOfficeDock1: TksoOfficeDock;
    KsoOfficeToolBar1: TksoOfficeToolBar;
    KsoOfficeDock2: TksoOfficeDock;
    KsoOfficeToolBar2: TksoOfficeToolBar;
    Sh_Servers: TTabSheet;
    KsoOfficeDock3: TksoOfficeDock;
    KsoOfficeToolBar3: TksoOfficeToolBar;
    Panel1: TPanel;
    Panel2: TPanel;
    Panel3: TPanel;
    List_Users: TListView;
    Btn_Tb_Log: TSpeedButton;
    Btn_Tb_Users: TSpeedButton;
    Btn_Tb_Registered: TSpeedButton;
    Btn_Tb_Servers: TSpeedButton;
    List_Registered: TListView;
    List_Servers: TListView;
    MainMenu1: TMainMenu;
    Mnu_Server: TMenuItem;
    Mnu_Log: TMenuItem;
    Mnu_Window: TMenuItem;
    Mnu_Help: TMenuItem;
    Mnu_Languages: TMenuItem;
    N3: TMenuItem;
    Mnu_Restart: TMenuItem;
    Mnu_Close: TMenuItem;
    Mnu_Settings: TMenuItem;
    Lbl_Users: TLabel;
    Mnu_Save: TMenuItem;
    Edit_Users_Reason: TEdit;
    Btn_Users_Kick: TSpeedButton;
    Btn_Users_Nuke: TSpeedButton;
    Btn_Users_Muzzle: TSpeedButton;
    Btn_Users_Refresh: TSpeedButton;
    Btn_Users_Ban: TSpeedButton;
    Popup_Log: TPopupMenu;
    Mnu_Log_Clear: TMenuItem;
    Popup_Users: TPopupMenu;
    Mnu_Users_Refresh: TMenuItem;
    N4: TMenuItem;
    Mnu_Users_Kick: TMenuItem;
    Mnu_Users_Nuke: TMenuItem;
    Mnu_Users_Muzzle: TMenuItem;
    Mnu_Users_Ban: TMenuItem;
    N5: TMenuItem;
    Mnu_Users_Level: TMenuItem;
    Mnu_Users_Level0: TMenuItem;
    Mnu_Users_Level1: TMenuItem;
    Mnu_Users_Level2: TMenuItem;
    Mnu_Users_Level3: TMenuItem;
    Mnu_Users_Level4: TMenuItem;
    Mnu_Users_Speed: TMenuItem;
    Mnu_Users_Speed0: TMenuItem;
    Mnu_Users_Speed1: TMenuItem;
    Mnu_Users_Speed2: TMenuItem;
    Mnu_Users_Speed3: TMenuItem;
    Mnu_Users_Speed4: TMenuItem;
    Mnu_Users_Speed5: TMenuItem;
    Mnu_Users_Speed6: TMenuItem;
    Mnu_Users_Speed7: TMenuItem;
    Mnu_Users_Speed8: TMenuItem;
    Mnu_Users_Speed9: TMenuItem;
    Mnu_Users_Speed10: TMenuItem;
    N6: TMenuItem;
    Mnu_Users_Im: TMenuItem;
    Mnu_Users_Whois: TMenuItem;
    N7: TMenuItem;
    Mnu_Users_Ignore: TMenuItem;
    Mnu_Users_Hotlist: TMenuItem;
    Mnu_Users_Friend: TMenuItem;
    N8: TMenuItem;
    Mnu_Users_Selall: TMenuItem;
    Mnu_Users_Selnone: TMenuItem;
    Mnu_Users_CopyName: TMenuItem;
    Lbl_Registered: TLabel;
    Cb_Reg_Mods: TCheckBox;
    Cb_Reg_Users: TCheckBox;
    Cb_Reg_Leeches: TCheckBox;
    Cb_Reg_Muzzled: TCheckBox;
    Btn_Reg_Refresh: TSpeedButton;
    Edit_Reg_Reason: TEdit;
    Btn_Reg_Nuke: TSpeedButton;
    Btn_Reg_Ban: TSpeedButton;
    Popup_Registered: TPopupMenu;
    Mnu_Reg_Refresh: TMenuItem;
    N9: TMenuItem;
    Mnu_Reg_Nuke: TMenuItem;
    Mnu_Reg_Ban: TMenuItem;
    Mnu_Reg_Level: TMenuItem;
    Mnu_Reg_Level0: TMenuItem;
    Mnu_Reg_Level1: TMenuItem;
    Mnu_Reg_Level2: TMenuItem;
    Mnu_Reg_Level3: TMenuItem;
    Mnu_Reg_Level4: TMenuItem;
    N10: TMenuItem;
    Mnu_Reg_Selall: TMenuItem;
    Mnu_Reg_Selnone: TMenuItem;
    Mnu_Reg_CopyName: TMenuItem;
    Btn_Tb_Channels: TSpeedButton;
    Sh_Channels: TTabSheet;
    KsoOfficeDock4: TksoOfficeDock;
    KsoOfficeToolBar4: TksoOfficeToolBar;
    Sh_Bans: TTabSheet;
    KsoOfficeDock5: TksoOfficeDock;
    KsoOfficeToolBar5: TksoOfficeToolBar;
    Sh_List: TTabSheet;
    KsoOfficeDock6: TksoOfficeDock;
    KsoOfficeToolBar6: TksoOfficeToolBar;
    Sh_Hotlist: TTabSheet;
    KsoOfficeDock7: TksoOfficeDock;
    KsoOfficeToolBar7: TksoOfficeToolBar;
    Panel4: TPanel;
    List_Channels: TListView;
    Panel5: TPanel;
    List_Bans: TListView;
    Panel6: TPanel;
    List_Lists: TListView;
    Panel7: TPanel;
    List_Hotlist: TListView;
    Btn_Tb_Bans: TSpeedButton;
    Btn_Tb_Hotlist: TSpeedButton;
    Btn_Tb_Friends: TSpeedButton;
    Btn_Tb_Ignored: TSpeedButton;
    Btn_Tb_Blocks: TSpeedButton;
    Lbl_Channels: TLabel;
    Btn_Ch_Refresh: TSpeedButton;
    Btn_Ch_Join: TSpeedButton;
    Btn_Ch_Props: TSpeedButton;
    Btn_Ch_Add: TSpeedButton;
    Btn_Ch_Delete: TSpeedButton;
    Edit_Ch_Reason: TEdit;
    Popup_Channels: TPopupMenu;
    Mnu_Ch_Refresh: TMenuItem;
    N11: TMenuItem;
    Mnu_Ch_Join: TMenuItem;
    N12: TMenuItem;
    Mnu_Ch_Delete: TMenuItem;
    Mnu_Ch_Clear: TMenuItem;
    Mnu_Ch_Add: TMenuItem;
    Mnu_Ch_Topic: TMenuItem;
    Mnu_Ch_Props: TMenuItem;
    N13: TMenuItem;
    N14: TMenuItem;
    Mnu_Ch_Selall: TMenuItem;
    Mnu_Ch_Selnone: TMenuItem;
    Mnu_Ch_CopyName: TMenuItem;
    Lbl_Bans: TLabel;
    Btn_Bans_Refresh: TSpeedButton;
    Btn_Bans_Add: TSpeedButton;
    Edit_Bans_User: TEdit;
    Btn_Ban_Delete: TSpeedButton;
    Edit_Ban_Reason: TEdit;
    Lbl_Servers: TLabel;
    Btn_Servers_Refresh: TSpeedButton;
    Btn_Servers_Connect: TSpeedButton;
    Btn_Servers_Disconnect: TSpeedButton;
    Btn_List_Refresh: TSpeedButton;
    Lbl_List: TLabel;
    Btn_List_Delete: TSpeedButton;
    Edit_List_Item: TEdit;
    Btn_List_Add: TSpeedButton;
    Edit_Servers_Host: TEdit;
    Btn_Servers_Add: TSpeedButton;
    Btn_Servers_Props: TSpeedButton;
    Btn_Servers_Delete: TSpeedButton;
    Mnu_Help_Manual: TMenuItem;
    Mnu_Help_Faq: TMenuItem;
    Mnu_Help_Forums: TMenuItem;
    N15: TMenuItem;
    Mnu_Help_About: TMenuItem;
    Mnu_Help_Web: TMenuItem;
    Lbl_Hotlist: TLabel;
    Btn_Hotlist_Refresh: TSpeedButton;
    Btn_Hotlist_Delete: TSpeedButton;
    Edit_Hotlist_User: TEdit;
    Btn_Hotlist_Add: TSpeedButton;
    Mnu_Log_Login: TMenuItem;
    Mnu_Log_Napigator: TMenuItem;
    Mnu_Log_Search: TMenuItem;
    Mnu_Log_Transfers: TMenuItem;
    N16: TMenuItem;
    Mnu_Log_Reset: TMenuItem;
    N17: TMenuItem;
    Mnu_Log_Clear2: TMenuItem;
    Mnu_Win_Log: TMenuItem;
    Mnu_Win_Users: TMenuItem;
    Mnu_Win_Registered: TMenuItem;
    Mnu_Win_Servers: TMenuItem;
    Mnu_Win_Channels: TMenuItem;
    Mnu_Win_Bans: TMenuItem;
    Mnu_Win_Hotlist: TMenuItem;
    Mnu_Win_Friends: TMenuItem;
    Mnu_Win_Ignored: TMenuItem;
    Mnu_Win_Blocked: TMenuItem;
    Edit_Ban_Time: TComboBox;
    Tb_Register: TksoOfficeToolBar;
    Edit_Reg_User: TEdit;
    Edit_Reg_Password: TEdit;
    Edit_Reg_Level: TComboBox;
    Btn_Reg_Add: TSpeedButton;
    Edit_Users_Time: TComboBox;
    Edit_Reg_Time: TComboBox;
    Timer3: TTimer;
    Cb_Servers_Refresh: TCheckBox;
    Lbl_Log: TLabel;
    Btn_Log_Clear: TSpeedButton;
    Btn_Users_Kickban: TSpeedButton;
    Mnu_Users_Kickban: TMenuItem;
    Dock_Bottom: TksoOfficeDock;
    Bar_Bottom2: TksoOfficeToolBar;
    Bar_Bottom3: TksoOfficeToolBar;
    Bar_Bottom4: TksoOfficeToolBar;
    Bar_Bottom5: TksoOfficeToolBar;
    StatusBar2: TStatusBar;
    StatusBar3: TStatusBar;
    StatusBar4: TStatusBar;
    StatusBar5: TStatusBar;
    // StatusBar6: TStatusBar;
    Dock_Bottom_Panel: TPanel;
    Popup_Servers: TPopupMenu;
    Mnu_Srv_Refresh: TMenuItem;
    N18: TMenuItem;
    Mnu_Srv_Connect: TMenuItem;
    Mnu_Srv_Disconnect: TMenuItem;
    Mnu_Srv_Delete: TMenuItem;
    N19: TMenuItem;
    Mnu_Srv_Comp: TMenuItem;
    Mnu_Srv_Comp0: TMenuItem;
    Mnu_Srv_Comp1: TMenuItem;
    Mnu_Srv_Comp2: TMenuItem;
    Mnu_Srv_Comp3: TMenuItem;
    Mnu_Srv_Startup: TMenuItem;
    Mnu_Srv_Startup0: TMenuItem;
    Mnu_Srv_Startup5: TMenuItem;
    Mnu_Srv_Startup10: TMenuItem;
    Mnu_Srv_Startup15: TMenuItem;
    Mnu_Srv_Startup20: TMenuItem;
    Mnu_Srv_Startup30: TMenuItem;
    Mnu_Srv_Props: TMenuItem;
    N20: TMenuItem;
    Mnu_Srv_Selall: TMenuItem;
    Mnu_Srv_Selnone: TMenuItem;
    Mnu_Srv_CopyName: TMenuItem;
    Popup_Bans: TPopupMenu;
    Mnu_Ban_Refresh: TMenuItem;
    N21: TMenuItem;
    Mnu_Ban_Unban: TMenuItem;
    N22: TMenuItem;
    Mnu_Ban_Copyuser: TMenuItem;
    Mnu_Ban_Copyip: TMenuItem;
    Mnu_Ban_Copyban: TMenuItem;
    Mnu_Ban_Copyadmin: TMenuItem;
    Mnu_Ban_Selall: TMenuItem;
    Mnu_Ban_Selnone: TMenuItem;
    Mnu_Ban_Copyreason: TMenuItem;
    Popup_Hotlist: TPopupMenu;
    Mnu_Hotlist_Refresh: TMenuItem;
    N23: TMenuItem;
    Mnu_Hotlist_Im: TMenuItem;
    Mnu_Hotlist_Whois: TMenuItem;
    Mnu_Hotlist_Friend: TMenuItem;
    Mnu_Hotlist_Delete: TMenuItem;
    N24: TMenuItem;
    Mnu_Hotlist_CopyName: TMenuItem;
    N25: TMenuItem;
    Mnu_Hotlist_Selall: TMenuItem;
    Mnu_Hotlist_Selnone: TMenuItem;
    Popup_Friends: TPopupMenu;
    Popup_Ignored: TPopupMenu;
    Popup_Blocks: TPopupMenu;
    Mnu_Ignored_Refresh: TMenuItem;
    N26: TMenuItem;
    Mnu_Ignored_Delete: TMenuItem;
    N27: TMenuItem;
    Mnu_Ignored_Selall: TMenuItem;
    Mnu_Ignored_Selnone: TMenuItem;
    Mnu_Fr_Refresh: TMenuItem;
    N28: TMenuItem;
    Mnu_Fr_Delete: TMenuItem;
    N29: TMenuItem;
    Mnu_Fr_Selall: TMenuItem;
    Mnu_Fr_Selnone: TMenuItem;
    Mnu_Fr_CopyName: TMenuItem;
    Mnu_Ignored_CopyName: TMenuItem;
    Mnu_Bl_Refresh: TMenuItem;
    N30: TMenuItem;
    Mnu_Bl_Delete: TMenuItem;
    N31: TMenuItem;
    Mnu_Bl_Selall: TMenuItem;
    Mnu_Bl_Selnone: TMenuItem;
    Mnu_Bl_CopyName: TMenuItem;
    Lbl_Tb_Selected: TLabel;
    Mnu_Ch_Clearbans: TMenuItem;
    SaveDialog1: TSaveDialog;
    Cb_Log_Away: TCheckBox;
    Lbl_Log_Away: TLabel;
    Edit_Log_Away: TEdit;
    Btn_Log_Mode: TSpeedButton;
    Cb_Log_Awaypopup: TCheckBox;
    Btn_Users_Mode: TSpeedButton;
    Popup_Usersmode: TPopupMenu;
    Mnu_Um_Level: TMenuItem;
    Mnu_Um_Shared: TMenuItem;
    Mnu_Um_Soft: TMenuItem;
    Mnu_Um_Speed: TMenuItem;
    Mnu_Um_Ip: TMenuItem;
    Mnu_Um_Port: TMenuItem;
    Mnu_Um_Time: TMenuItem;
    Mnu_Um_Transfers: TMenuItem;
    Mnu_Um_Total: TMenuItem;
    Mnu_Um_Server: TMenuItem;
    Cb_Log_Sound: TCheckBox;
    Edit_Reg_Filter: TEdit;
    Mnu_Log_Dagsta: TMenuItem;
    Btn_Users_Register: TSpeedButton;
    Mnu_Users_Register: TMenuItem;
    Btn_Users_Banip: TSpeedButton;
    Btn_Users_Kickbanip: TSpeedButton;
    Mnu_Users_Banip: TMenuItem;
    Mnu_Users_Kickbanip: TMenuItem;
    Btn_Reg_Banip: TSpeedButton;
    Mnu_Reg_Banip: TMenuItem;
    Mnu_Log_Copy: TMenuItem;
    Btn_Log_Pause: TSpeedButton;
    Cb_List_Sound: TCheckBox;
    Cb_Hotlist_Sound: TCheckBox;
    Btn_List_Reload: TSpeedButton;
    Mnu_Log_Browse: TMenuItem;
    Edit_Unban_Reason: TEdit;
    Btn_Reg_Unregister: TSpeedButton;
    Mnu_Reg_Unregister: TMenuItem;
    Mnu_Um_Size: TMenuItem;
    Mnu_Um_Average: TMenuItem;
    Mnu_Um_Up: TMenuItem;
    Mnu_Um_Down: TMenuItem;
    Mnu_Um_Totalup: TMenuItem;
    Mnu_Um_Totaldown: TMenuItem;
    Mnu_Um_Ulrequests: TMenuItem;
    Mnu_Um_Dlrequests: TMenuItem;
    Mnu_Um_Searchreqs: TMenuItem;
    Mnu_Um_BlockFiles: TMenuItem;
    Mnu_Users_Browse: TMenuItem;
    Mnu_Users_Announce: TMenuItem;
    Mnu_Um_RemoteHost: TMenuItem;
    Cb_Users_Refresh: TCheckBox;
    Edit_Users_Refresh: TSpinEdit;
    Lbl_Users_Refresh: TLabel;
    Edit_Servers_Refresh: TSpinEdit;
    Lbl_Servers_Refresh: TLabel;
    KsoOfficeToolBar8: TksoOfficeToolBar;
    Cb_Users_Mods: TCheckBox;
    Cb_Users_Users: TCheckBox;
    Cb_Users_Leeches: TCheckBox;
    Cb_Users_Muzzled: TCheckBox;
    Cb_Users_Local: TCheckBox;
    Cb_Users_Remote: TCheckBox;
    Edit_Users_Filter: TEdit;
    procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
    procedure CreateParams(var Params: TCreateParams); override;
    procedure Log_Change(Sender: TObject);
    procedure Log_URLClick(Sender: TObject; const URLText: string;
      Button: TMouseButton);
    procedure LoadConfig(LoadMode: ConfigLoadMode = lmAll);
    procedure SaveConfig;
    procedure Timer1Timer(Sender: TObject);
    procedure UpdateTray;
    procedure Sh_Show(Sender: TObject);
    procedure DrawPopupItem2(Sender: TObject; ACanvas: TCanvas;
      ARect: TRect; Selected: Boolean);
    procedure MeasurePopupItem(Sender: TObject; ACanvas: TCanvas;
      var Width, Height: Integer);
    procedure Mnu_Tray_ExitClick(Sender: TObject);
    procedure Mnu_Tray_RestartClick(Sender: TObject);
    procedure Mnu_Tray_SettingsClick(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Btn_Tb_LogClick(Sender: TObject);
    procedure Btn_Tb_UsersClick(Sender: TObject);
    procedure Btn_Tb_RegisteredClick(Sender: TObject);
    procedure Btn_Tb_ServersClick(Sender: TObject);
    procedure ResizeTree(Sender: TObject);
    procedure ChangeTree(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure ListCompare(Sender: TObject; Item1,
      Item2: TListItem; Data: Integer; var Compare: Integer);
    procedure ListColumnClick(Sender: TObject;
      Column: TListColumn);
    procedure Mnu_Draw(Sender: TObject; ACanvas: TCanvas;
      ARect: TRect; Selected: Boolean);
    procedure Mnu_LanguagesClick(Sender: TObject);
    procedure DrawPopupItem(Sender: TObject; ACanvas: TCanvas;
      ARect: TRect; Selected: Boolean);
    procedure Popup_TrayPopup(Sender: TObject);
    procedure Mnu_Tray_ShowClick(Sender: TObject);
    procedure Btn_Reg_RefreshClick(Sender: TObject);
    procedure WMQueryEndSession(var Message: TMessage); Message
      WM_QUERYENDSESSION;
    procedure Btn_Users_KickClick(Sender: TObject);
    procedure Btn_Users_NukeClick(Sender: TObject);
    procedure Btn_Users_MuzzleClick(Sender: TObject);
    procedure Btn_Users_RefreshClick(Sender: TObject);
    procedure Btn_Users_BanClick(Sender: TObject);
    procedure Btn_Users_BanipClick(Sender: TObject);
    procedure Mnu_Log_ClearClick(Sender: TObject);
    procedure Log_MainMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Log_ConsoleMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Mnu_Users_LevelClick(Sender: TObject);
    procedure Popup_UsersPopup(Sender: TObject);
    procedure Mnu_Users_SpeedClick(Sender: TObject);
    procedure Mnu_Users_SelallClick(Sender: TObject);
    procedure Mnu_Users_SelnoneClick(Sender: TObject);
    procedure Mnu_Users_CopyNameClick(Sender: TObject);
    procedure Btn_Reg_NukeClick(Sender: TObject);
    procedure Btn_Reg_BanClick(Sender: TObject);
    procedure Btn_Reg_BanipClick(Sender: TObject);
    procedure Mnu_Reg_LevelClick(Sender: TObject);
    procedure Mnu_Reg_SelallClick(Sender: TObject);
    procedure Mnu_Reg_SelnoneClick(Sender: TObject);
    procedure Mnu_Reg_CopyNameClick(Sender: TObject);
    procedure Popup_RegisteredPopup(Sender: TObject);
    procedure Btn_Tb_ChannelsClick(Sender: TObject);
    procedure Btn_Tb_BansClick(Sender: TObject);
    procedure Btn_Tb_HotlistClick(Sender: TObject);
    procedure clientResize(Sender: TObject);
    procedure SlavaSplitter1Moved(Sender: TObject);
    procedure Btn_Ch_RefreshClick(Sender: TObject);
    procedure Btn_Ch_DeleteClick(Sender: TObject);
    procedure Btn_Ch_AddClick(Sender: TObject);
    procedure Popup_ChannelsPopup(Sender: TObject);
    procedure Btn_Ch_JoinClick(Sender: TObject);
    procedure Btn_Ch_PropsClick(Sender: TObject);
    procedure Btn_Bans_RefreshClick(Sender: TObject);
    procedure Btn_Bans_AddClick(Sender: TObject);
    procedure Btn_Ban_DeleteClick(Sender: TObject);
    procedure Btn_Servers_RefreshClick(Sender: TObject);
    procedure Btn_Servers_ConnectClick(Sender: TObject);
    procedure Btn_Servers_DisconnectClick(Sender: TObject);
    procedure Mnu_Users_HotlistClick(Sender: TObject);
    procedure Mnu_Users_IgnoreClick(Sender: TObject);
    procedure Mnu_Users_FriendClick(Sender: TObject);
    procedure Btn_Tb_FriendsClick(Sender: TObject);
    procedure Btn_Tb_IgnoredClick(Sender: TObject);
    procedure Btn_Tb_BlocksClick(Sender: TObject);
    procedure Mnu_Ch_SelallClick(Sender: TObject);
    procedure Mnu_Ch_SelnoneClick(Sender: TObject);
    procedure Mnu_Ch_CopyNameClick(Sender: TObject);
    procedure Btn_List_RefreshClick(Sender: TObject);
    procedure Btn_List_DeleteClick(Sender: TObject);
    procedure Btn_List_AddClick(Sender: TObject);
    procedure Btn_Servers_DeleteClick(Sender: TObject);
    procedure Btn_Servers_AddClick(Sender: TObject);
    procedure Btn_Servers_PropsClick(Sender: TObject);
    procedure Mnu_Help_ForumsClick(Sender: TObject);
    procedure Mnu_Help_WebClick(Sender: TObject);
    procedure Btn_Hotlist_RefreshClick(Sender: TObject);
    procedure Mnu_LogClick(Sender: TObject);
    procedure Mnu_L(Sender: TObject);
    procedure Mnu_Log_LoginClick(Sender: TObject);
    procedure Mnu_Log_SearchClick(Sender: TObject);
    procedure Mnu_Log_TransfersClick(Sender: TObject);
    procedure Mnu_Log_NapigatorClick(Sender: TObject);
    procedure Mnu_Log_ResetClick(Sender: TObject);
    procedure Mnu_Help_ManualClick(Sender: TObject);
    procedure Mnu_Help_FaqClick(Sender: TObject);
    procedure Btn_Reg_AddClick(Sender: TObject);
    procedure Timer3Timer(Sender: TObject);
    procedure Btn_Hotlist_AddClick(Sender: TObject);
    procedure Btn_Hotlist_DeleteClick(Sender: TObject);
    procedure Mnu_Users_ImClick(Sender: TObject);
    procedure Btn_Users_KickbanClick(Sender: TObject);
    procedure Btn_Users_KickbanipClick(Sender: TObject);
    procedure Mnu_Users_WhoisClick(Sender: TObject);
    procedure Popup_ServersPopup(Sender: TObject);
    procedure Mnu_Srv_CompClick(Sender: TObject);
    procedure Mnu_Srv_StartupClick(Sender: TObject);
    procedure Mnu_Ban_CopyuserClick(Sender: TObject);
    procedure Mnu_Ban_CopyipClick(Sender: TObject);
    procedure Mnu_Ban_CopybanClick(Sender: TObject);
    procedure Mnu_Ban_CopyadminClick(Sender: TObject);
    procedure Mnu_Ban_CopyreasonClick(Sender: TObject);
    procedure Mnu_Ban_SelallClick(Sender: TObject);
    procedure Mnu_Ban_SelnoneClick(Sender: TObject);
    procedure Popup_BansPopup(Sender: TObject);
    procedure Mnu_Hotlist_CopyNameClick(Sender: TObject);
    procedure Mnu_Hotlist_SelnoneClick(Sender: TObject);
    procedure Mnu_Hotlist_SelallClick(Sender: TObject);
    procedure Mnu_Hotlist_ImClick(Sender: TObject);
    procedure Mnu_Hotlist_WhoisClick(Sender: TObject);
    procedure Mnu_Hotlist_FriendClick(Sender: TObject);
    procedure Popup_HotlistPopup(Sender: TObject);
    procedure Mnu_List_SelallClick(Sender: TObject);
    procedure Mnu_List_SelnoneClick(Sender: TObject);
    procedure Mnu_List_CopyClick(Sender: TObject);
    procedure Popup_IgnoredPopup(Sender: TObject);
    procedure Popup_FriendsPopup(Sender: TObject);
    procedure Popup_BlocksPopup(Sender: TObject);
    procedure toolbarResize(Sender: TObject);
    procedure listSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure Mnu_Help_AboutClick(Sender: TObject);
    procedure Mnu_Ch_ClearClick(Sender: TObject);
    procedure Mnu_Srv_SelallClick(Sender: TObject);
    procedure Mnu_Srv_SelnoneClick(Sender: TObject);
    procedure Mnu_Srv_CopyNameClick(Sender: TObject);
    procedure Mnu_Ch_ClearbansClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Cb_Log_AwayClick(Sender: TObject);
    procedure Btn_Log_ModeClick(Sender: TObject);
    procedure Btn_Users_ModeClick(Sender: TObject);
    procedure Mnu_Um_Click(Sender: TObject);
    procedure Popup_UsersmodePopup(Sender: TObject);
    procedure Mnu_Log_DagstaClick(Sender: TObject);
    procedure Btn_Users_RegisterClick(Sender: TObject);
    procedure Mnu_Log_CopyClick(Sender: TObject);
    procedure Btn_Log_PauseClick(Sender: TObject);
    procedure Btn_Log_ClearClick(Sender: TObject);
    procedure Cb_List_SoundClick(Sender: TObject);
    procedure Btn_List_ReloadClick(Sender: TObject);
    procedure Mnu_Log_BrowseClick(Sender: TObject);
    procedure Btn_Reg_UnregisterClick(Sender: TObject);
    procedure Mnu_Reg_UnregisterClick(Sender: TObject);
    procedure Mnu_Users_BrowseClick(Sender: TObject);
    procedure Mnu_Users_AnnounceClick(Sender: TObject);
    procedure Cb_Users_RefreshClick(Sender: TObject);
    procedure Cb_Servers_RefreshClick(Sender: TObject);
  private
    { Private declarations }
    Splitter_Pos: Integer;
    Tray_AndMask: TBitmap;
    Tray_XOrMask: TBitmap;
    function CompareLevel(Str1, Str2: string): Integer;
    function CompareIP(Str1, Str2: string): Integer;
    function CompareDate(Str1, Str2: string): Integer;
    function CompareTime(Str1, Str2: string): Integer;
    function CompareDigit(Str1, Str2: string): Integer;
    function CompareSpeed(Str1, Str2: string): Integer;
    function CompareRemoteHost(Str1, Str2: string): Integer;
    procedure AppException(Sender: TObject; E: Exception);
    function CompareDigit2(Str1, Str2: string): Integer;
    procedure CMShowingChanged(var Msg: TMessage); Message CM_SHOWINGCHANGED;
  public
    { Public declarations }
    Console_Log_File: TFileStream;
    procedure ChangeInterface(LoadMode: ConfigLoadMode = lmAll);
    procedure LogMain(Color: Integer; Text: string; Add_Time: Boolean = True);
    procedure LogConsole(Color: Integer; Text: string; Add_Time: Boolean =
      True);
    procedure ResizeHeader(List: TListView);
    function DoCompare(List: TListView; Index: Integer;
      Str1, Str2: string): Integer;
    function CreateChannelWindow(Channel: string): TSlavaNapChannelWindow;
    function FindChannelWindow(Channel: string): TSlavaNapChannelWindow;
    function FindChatWindow(User: string): TSlavaNapChatWindow;
    function CreateChatWindow(User: string): TSlavaNapChatWindow;
    procedure ShowList(T: TConsoleList);
    function CreateWhoisWindow(User: string): TSlavaNapWhois;
    procedure SetColors(All_Windows: Boolean = True);
    function IsColumnVisible(List: TListView; N: Integer): Boolean;
    procedure SetColumnVisible(List: TListView; N: Integer; W: Integer;
      Auto: Boolean);
    function CreateBrowseWindow(User: string): TSlavaNapBrowseWindow;
    procedure SetBanItems(Control: TComboBox);
    function GetBanID(Control: TComboBox): Integer;
    function CreateAnnounceWindow(Users: TStringList): TSlavaNapAnnounceWindow;
  end;

var
  SlavaNapWindow: TSlavaNapWindow;
  PauseLog: Boolean;

procedure GetApplicationDir;
procedure InitCommandLine;

implementation

uses Form, Vars, Thread, Constants, Lang, Bans, Users, Settings,
  Languages, Registered, LocalUsers, Napigator, Dagsta, Servers, Share, Handler,
  Channels, Console, QueryOption, EditDialog, AboutForm, SetupForm,
  SlavaMenu, Memory_Manager, Ips;

{$R *.DFM}

procedure GetApplicationDir;
begin
  ApplicationDir := ExtractFilePath(Application.ExeName);
  if ApplicationDir[Length(ApplicationDir)] <> '\' then
    ApplicationDir := ApplicationDir + '\';
end;

procedure InitCommandLine;
var
  I: Integer;
  Str: string;
begin
  LogStartup('Initcommandline: Starting');
  ApplicationDir := ExtractFilePath(Application.ExeName);
  Allow_Multiple_Instances := False;
  Startup_Hide := False;
  I := 1;
  LogStartup('Initcommandline: Main loop');
  while I <= ParamCount do
  begin
    Str := LowerCase(ParamStr(I));
    Inc(I);
    if Str = '-hide' then
      Startup_Hide := True;
    if Str = '-copy' then
      Allow_Multiple_Instances := True;
    if Str = '-new' then
      Allow_Multiple_Instances := True;
    if Str = '-dir' then
    begin
      Str := ParamStr(I);
      Inc(I);
      if Str <> '' then
        ApplicationDir := Str;
    end;
  end;
  LogStartup('Initcommandline: Checking appdir');
  if ApplicationDir[Length(ApplicationDir)] <> '\' then
    ApplicationDir := ApplicationDir + '\';
end;

procedure TSlavaNapWindow.CreateParams(var Params: TCreateParams);
begin
  try
    LogStartup('Createparams: inherited CreateParams( Params );');
    inherited CreateParams(Params);
    LogStartup('Createparams: Params.ExStyle := ...');
    Params.ExStyle := Params.ExStyle and not WS_EX_TOOLWINDOW or
      WS_EX_APPWINDOW;
  except
    DebugLog('Exception in TMainForm::CreateParams()', True);
  end;
end;

procedure TSlavaNapWindow.WMQueryEndSession(var Message: TMessage);
begin
  Message.Result := 1;
  Closing := True;
  SaveConfig;
  Running := False;
end;

procedure TSlavaNapWindow.FormCreate(Sender: TObject);
var
  R: TRect;
  LogFileName: string;
  Ini: TIniFile;
begin
  Ini := TIniFile.Create(ApplicationDir + 'config');
  Log_Folder := Ini.ReadString('Other2', 'LogFolder', ApplicationDir);
  Ini.Free;
  ShortDateFormat := 'yyyymmdd';
  // LogFileName := ApplicationDir + 'server-' + DateToStr(Now) + '.log';
  LogFileName := Log_Folder + 'server-' + DateToStr(Now) + '.log';
  ShortDateFormat := 'yyyy/mm/dd';
  if not FileExists(LogFileName) then
  try
    Log_File := TFileStream.Create(LogFileName, fmCreate);
    Log_File.Free;
  except
  end;
  try
    Log_File := TFileStream.Create(LogFileName, fmOpenWrite or
      fmShareDenyWrite);
    Log_File.Seek(0, soFromEnd);
  except
    Log_File := nil;
    LogStartup('MainForm::Create: Cannot open "' + LogFileName + '" !!!');
    DebugLog('Error: Cannot open File ' + LogFileName);
  end;
  // Init variables
  LogStartup('MainForm::Create: Creating main window');
  Randomize;
  Splitter_Pos := Panel_Console.Height * 1000 div client.Height;
  LogStartup('MainForm::Create: Application.OnException := AppException;');
  Application.OnException := AppException;
  Current_Time := GetTickCount;
  Current_Time_T := GetTickCountT;

  {Create The "And" Mask}
  LogStartup('MainForm::Create: Creating bitmaps');
  Tray_AndMask := CreateTBitmap;
  Tray_AndMask.Monochrome := True;
  Tray_AndMask.Width := 16;
  Tray_AndMask.Height := 16;
  {Create The "XOr" Mask}
  Tray_XOrMask := CreateTBitmap;
  Tray_XOrMask.Width := 16;
  Tray_XOrMask.Height := 16;

  SystemParametersInfo(SPI_GETWORKAREA, 0, @R, 0);
  LogStartup('MainForm::Create: Resizing window');
  Top := (R.Top + R.Bottom - Height) div 2;
  Left := (R.Right + R.Left - Width - 4) div 2;
  LogStartup('MainForm::Create: Changing active page');
  Pages.ActivePage := Sh_Log;
  Running := False;
  Restarting := False;
  Closing := False;
  ShowForm := True;
  Console_Log_File := nil;
  if Startup_Hide then
    ShowForm := False;

  LogStartup('MainForm::Create: LoadConfig;');
  LoadConfig(lmInitial);
  LogStartup('MainForm::Create: ChangeInterface;');
  ChangeInterface(lmInitial);
  LogStartup('MainForm::Create: LogMain...');
  LogMain(slText, GetLangI(LNG_LOG_STARTING, SLAVANAP_FULL));
end;

procedure TSlavaNapWindow.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  if (Closing = False) and (B3_Canclose <> True3) and Tray.Active then
  try
    CanClose := False;
    if B3_Canclose = False3 then
      Hide
    else
      SlavaNapQueryOption.Ask(QO_CLOSE);
    Exit;
  except
    DebugLog('Exception in TMainForm::FormCloseQuery()');
    Exit;
  end;
  CanClose := not Running;
  if Running then
  begin
    SaveConfig;
    LogMain(clRed, Str_SERVER_SHUT_DOWN);
    LogMain(clRed, Str_SERVER_SHUT_DOWN2);
  end;
  Closing := True;
  Running := False;
end;

procedure TSlavaNapWindow.FormClose(Sender: TObject; var Action: TCloseAction);
var
  I: Integer;
begin
  Action := caFree;
  SlavaNapMain.Close;
  for I := Cons_Channels.Count - 1 downto 0 do
    TSlavaNapChannelWindow(Cons_Channels.Items[I]).Close;
  Cons_Channels.Clear;
  for I := Cons_Chat.Count - 1 downto 0 do
    TSlavaNapChatWindow(Cons_Chat.Items[I]).Close;
  Cons_Chat.Clear;
  for I := Cons_Whois.Count - 1 downto 0 do
    TSlavaNapWhois(Cons_Whois.Items[I]).Close;
  Cons_Whois.Clear;
  for I := Cons_Browse.Count - 1 downto 0 do
    TSlavaNapBrowseWindow(Cons_Browse.Items[I]).Close;
  Cons_Browse.Clear;
end;

procedure TSlavaNapWindow.FormDestroy(Sender: TObject);
begin
  Cons_Channels.Free;
  Cons_Chat.Free;
  Cons_Whois.Free;
  Cons_Browse.Free;
  StrHash_Clear(Cons_Friends);
  StrHash_Clear(Cons_Blocks);
  StrHash_Clear(Cons_Ignored);
  if Console_Log_File <> nil then
    Console_Log_File.Free;
  Console_Log_File := nil;
  FreeTBitmap(Tray_AndMask);
  FreeTBitmap(Tray_XOrMask);
end;

procedure TSlavaNapWindow.LoadConfig(LoadMode: ConfigLoadMode = lmAll);
var
  I: Integer;
  Str: string;
  Ini: TMemIniFile;
  List, List2: TMyStringList;
  B: Boolean;
  Rec: TOnlineUser;
  T: PStringHashItem;
  function GetInt64(Section, Value: string; Def: Int64): Int64;
  begin
    Result := StrToInt64Def(Ini.ReadString(Section, Value, IntToStr(Def)), Def);
  end;
begin
  LogStartup('MainForm::LoadConfig: Loading config');
  Ini := TMemIniFile.Create(ApplicationDir + 'config');
  try
    LogStartup('MainForm::LoadConfig: Checking config version');
    if Ini.ReadString('Server', 'Version', SLAVANAP_VERSION) < '1.9.9' then
    begin
      Ini.Free;
      ShowSetup;
      Ini := TMemIniFile.Create(ApplicationDir + 'config');
    end
    else if Ini.ReadString('Server', 'Version', SLAVANAP_VERSION) <>
      SLAVANAP_VERSION then
    begin // One of Previous builds. Convert old Config
      //   Ini.WriteBool('Server', 'BlockWinMXQueue', False);
      if Ini.ReadInteger('Server', 'TimeoutRemoteSearch', 90000) = 30000 then
        Ini.WriteInteger('Server', 'TimeoutRemoteSearch', 90000);
      // Convert CPU Usage for New handler if using Winnt/2k/Xp
      if not Win98 then
        if (Ini.ReadInteger('Server', 'CPUUsage5', 0) = 0) and
          (Ini.ReadInteger('Server', 'CPUUsage4', 3000) <= 2000) then
          Ini.WriteInteger('Server', 'CPUUsage5', Ini.ReadInteger('Server',
            'CPUUsage4', 1000) * 10);
    end;
    LogStartup('MainForm::LoadConfig: Converting config if it is in old format');
    // Converting very old config
    if Ini.SectionExists('Report0') then
    begin
      Str := Ini.ReadString('Report0', 'Host', 'stat.napigator.com');
      Ini.WriteString('Napigator', 'Host', Str);
      Str := Ini.ReadString('Report0', 'Port', '8890');
      Ini.WriteString('Napigator', 'Port', Str);
      Str := Ini.ReadString('Report0', 'User', '');
      Ini.WriteString('Napigator', 'User', Str);
      Str := Ini.ReadString('Report0', 'Password', '');
      Ini.WriteString('Napigator', 'Password', Str);
      Str := Ini.ReadString('Report0', 'Enabled', '0');
      Ini.WriteString('Napigator', 'Enabled', Str);
      Str := Ini.ReadString('Report0', 'ReportPort', '');
      Ini.WriteString('Napigator', 'ReportPort', Str);
      Ini.EraseSection('Report0');
      Ini.WriteBool('Share', 'Inform', False);
    end;
    if LoadMode <> lmRest then
    begin
      // Colors
      LogStartup('MainForm::LoadConfig: Loading colors');
      slBackground := Ini.ReadInteger('Colors', 'clBackground', $FFFFFF);
      slText := Ini.ReadInteger('Colors', 'clText', 0);
      slError := Ini.ReadInteger('Colors', 'clError', $0000FF);
      slWallop := Ini.ReadInteger('Colors', 'clWallop', $A06000);
      slAnnounce := Ini.ReadInteger('Colors', 'clAnnounce', $A00060);
      slWhowas := Ini.ReadInteger('Colors', 'clWhowas', $600060);
      slPong := Ini.ReadInteger('Colors', 'clPong', $600060);
      slOffline := Ini.ReadInteger('Colors', 'clOffline', $603000);
      slOnline := Ini.ReadInteger('Colors', 'clOnline', $A06000);
      slDebugData := Ini.ReadInteger('Colors', 'clDebugData', $000060);
      slNapigator := Ini.ReadInteger('Colors', 'clNapigator', $006000);
      slDagsta := Ini.ReadInteger('Colors', 'clDagsta', $008000);
      slSearch := Ini.ReadInteger('Colors', 'clSearch', $A000A0);
      slBrowse := Ini.ReadInteger('Colors', 'clBrowse', $E000E0);
      slTransfer := Ini.ReadInteger('Colors', 'clTransfer', $600060);
      slTopic := Ini.ReadInteger('Colors', 'clTopic', $B00060);
      slChannelMessage := Ini.ReadInteger('Colors', 'clChannelMessage', 0);
      slChannelMyMessage := Ini.ReadInteger('Colors', 'clChannelMyMessage',
        $404040);
      slChannelEmote := Ini.ReadInteger('Colors', 'clChannelEmote', $606000);
      slChannelMyEmote := Ini.ReadInteger('Colors', 'clChannelMyEmote',
        $808000);
      slChannelJoin := Ini.ReadInteger('Colors', 'clChannelJoin', $A06000);
      slChannelPart := Ini.ReadInteger('Colors', 'clChannelPart', $603000);
      slChatMessage := Ini.ReadInteger('Colors', 'clChatMessage', $A00000);
      slChatMyMessage := Ini.ReadInteger('Colors', 'clChatMyMessage', 0);
      // interface
      LogStartup('MainForm::LoadConfig: Loading interface configuration');
      ToolBar.Rolled := not Ini.ReadBool('Interface', 'ShowToolBar', True);
      Bar_Bottom2.Rolled := Ini.ReadBool('Interface', 'HideStatus2', False);
      Bar_Bottom3.Rolled := Ini.ReadBool('Interface', 'HideStatus3', False);
      Bar_Bottom4.Rolled := Ini.ReadBool('Interface', 'HideStatus4', False);
      Bar_Bottom5.Rolled := Ini.ReadBool('Interface', 'HideStatus5', False);
      Tb_Register.Rolled := Ini.ReadBool('Interface', 'HideRegisterBtn', True);
      Tray.Active := Ini.ReadBool('Interface', 'ShowTray', True);
      Left := Ini.ReadInteger('Interface', 'Left', Left);
      Top := Ini.ReadInteger('Interface', 'Top', Top);
      Width := Ini.ReadInteger('Interface', 'Width', Width);
      Height := Ini.ReadInteger('Interface', 'Height', Height);
      try
        WindowState := TWindowState(Ini.ReadInteger('Interface', 'State',
          Ord(wsNormal)));
      except
      end;
      try
        I := Ini.ReadInteger('Interface', 'Splitter', Panel_Console.Height);
        if I < ClientHeight then
          Panel_Console.Height := I;
      except
      end;
      Language := Ini.ReadString('Server', 'Language', '');
      if Language = '' then
      begin
        LogStartup('MainForm::LoadConfig: Selecting language for the first time');
        SlavaNapLanguage.ShowModal;
      end;
      LogStartup('MainForm::LoadConfig: Loading custom language(initial) - ' +
        Language);
      LoadLanguage(Language, lmInitial);
      if LoadMode = lmInitial then Exit; // 起動時間の短縮のため
    end;

    List := TMyStringList.Create;
    try
      B3_Canclose := Bool3(Ini.ReadInteger('Interface', 'CloseWindow', 0));
      Switch_Chat := Ini.ReadBool('Interface', 'SwitchChat', True);
      Cb_Users_Mods.Checked := Ini.ReadBool('Interface', 'CBUsersModes', True);
      Cb_Users_Users.Checked := Ini.ReadBool('Interface', 'CBUsersUsers', True);
      Cb_Users_Leeches.Checked := Ini.ReadBool('Interface', 'CBUsersLeeched',
        True);
      Cb_Users_Muzzled.Checked := Ini.ReadBool('Interface', 'CBUsersMuzzled',
        False);
      Cb_Users_Local.Checked := Ini.ReadBool('Interface', 'CBUsersLocal', True);
      Cb_Users_Remote.Checked := Ini.ReadBool('Interface', 'CBUsersRemote',
        True);
      Edit_Users_Filter.Text := Ini.ReadString('Interface', 'UsersFilter', '*');
      Edit_Reg_Filter.Text := Ini.ReadString('Interface', 'RegFilter', '*');
      Edit_Users_Reason.Text := Ini.ReadString('Interface', 'UsersReason',
        RS_NoReason);
      Edit_Reg_Reason.Text := Ini.ReadString('Interface', 'RegReason',
        RS_NoReason);
      Edit_Ch_Reason.Text := Ini.ReadString('Interface', 'ChReason',
        RS_NoReason);
      Edit_Ban_Reason.Text := Ini.ReadString('Interface', 'BanReason',
        RS_NoReason);
      Edit_Unban_Reason.Text := Ini.ReadString('Interface', 'UnBanReason',
        RS_NoReason);
      List_Users.Tag := Ini.ReadInteger('Interface', 'SortUsers', 0);
      List_Registered.Tag := Ini.ReadInteger('Interface', 'SortRegistered', 0);
      List_Servers.Tag := Ini.ReadInteger('Interface', 'SortServers', 0);
      List_Channels.Tag := Ini.ReadInteger('Interface', 'SortChannels', 0);
      List_Bans.Tag := Ini.ReadInteger('Interface', 'SortBans', 0);
      List_Lists.Tag := Ini.ReadInteger('Interface', 'SortLists', 0);
      List_Hotlist.Tag := Ini.ReadInteger('Interface', 'SortHotlist', 0);
      Cb_Users_Refresh.Checked := Ini.ReadBool('Interface', 'RefreshUsers',
        False);
      Edit_Users_Refresh.Value := Ini.ReadInteger('Interface',
        'RefreshUsersDelay', 30);
      Edit_Users_Refresh.Visible := Cb_Users_Refresh.Checked;
      Lbl_Users_Refresh.Visible := Cb_Users_Refresh.Checked;
      Cb_Servers_Refresh.Checked := Ini.ReadBool('Interface', 'RefreshServers',
        False);
      Edit_Servers_Refresh.Value := Ini.ReadInteger('Interface',
        'RefreshServersDelay', 30);
      Edit_Servers_Refresh.Visible := Cb_Servers_Refresh.Checked;
      Lbl_Servers_Refresh.Visible := Cb_Servers_Refresh.Checked;
      Cb_Log_Away.Checked := Ini.ReadBool('Interface', 'IsAway', False);
      // Cb_Log_Awaypopup.Checked := Ini.ReadBool('Interface', 'AwayPopup', True);
      Cb_Log_Awaypopup.Checked := Cb_Log_Away.Checked;
        // Default on restart is checked if away
      Edit_Log_Away.Text := Ini.ReadString('Interface', 'AwayMessage',
        RS_MainForm_AwayMessage);
      Cb_Log_AwayClick(nil);
      for I := 0 to 30 do
        IsHide[I] := False;
      if Ini.ReadBool('Interface', 'UsersListHideLevel', False) then
      begin
        IsHide[UL_LEVEL + 1] := True;
        SetColumnVisible(List_Users, UL_LEVEL + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideShared', False) then
      begin
        IsHide[UL_SHARED + 1] := True;
        SetColumnVisible(List_Users, UL_SHARED + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideSize', True) then
      begin
        IsHide[UL_SIZE + 1] := True;
        SetColumnVisible(List_Users, UL_SIZE + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideAverage', True) then
      begin
        IsHide[UL_AVERAGE + 1] := True;
        SetColumnVisible(List_Users, UL_AVERAGE + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideSoft', False) then
      begin
        IsHide[UL_SOFT + 1] := True;
        SetColumnVisible(List_Users, UL_SOFT + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideSpeed', False) then
      begin
        IsHide[UL_SPEED + 1] := True;
        SetColumnVisible(List_Users, UL_SPEED + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideIP', False) then
      begin
        IsHide[UL_IP + 1] := True;
        SetColumnVisible(List_Users, UL_IP + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideRemoteHost', True) then
      begin
        IsHide[UL_REMOTEHOST + 1] := True;
        SetColumnVisible(List_Users, UL_REMOTEHOST + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHidePort', True) then
      begin
        IsHide[UL_PORT + 1] := True;
        SetColumnVisible(List_Users, UL_PORT + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideTime', True) then
      begin
        IsHide[UL_TIME + 1] := True;
        SetColumnVisible(List_Users, UL_TIME + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideUp', True) then
      begin
        IsHide[UL_UP + 1] := True;
        SetColumnVisible(List_Users, UL_UP + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideDown', True) then
      begin
        IsHide[UL_DOWN + 1] := True;
        SetColumnVisible(List_Users, UL_DOWN + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideTransfers', True) then
      begin
        IsHide[UL_TRANSFERS + 1] := True;
        SetColumnVisible(List_Users, UL_TRANSFERS + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideTotalUp', True) then
      begin
        IsHide[UL_TUP + 1] := True;
        SetColumnVisible(List_Users, UL_TUP + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideTotalDown', True) then
      begin
        IsHide[UL_TDOWN + 1] := True;
        SetColumnVisible(List_Users, UL_TDOWN + 1, 0, False);
      enD;
      if Ini.ReadBool('Interface', 'UsersListHideTotal', True) then
      begin
        IsHide[UL_TTRANSFERS + 1] := True;
        SetColumnVisible(List_Users, UL_TTRANSFERS + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideServer', False) then
      begin
        IsHide[UL_SERVER + 1] := True;
        SetColumnVisible(List_Users, UL_SERVER + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideULRequests', False) then
      begin
        IsHide[UL_ULREQUESTS + 1] := True;
        SetColumnVisible(List_Users, UL_ULREQUESTS + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideDLRequests', False) then
      begin
        IsHide[UL_DLREQUESTS + 1] := True;
        SetColumnVisible(List_Users, UL_DLREQUESTS + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideSearchReqs', False) then
      begin
        IsHide[UL_SEARCHREQS + 1] := True;
        SetColumnVisible(List_Users, UL_SEARCHREQS + 1, 0, False);
      end;
      if Ini.ReadBool('Interface', 'UsersListHideBlockFiles', False) then
      begin
        IsHide[UL_BLOCKFILES + 1] := True;
        SetColumnVisible(List_Users, UL_BLOCKFILES + 1, 0, False);
      end;
      // Server data
      LogStartup('MainForm::LoadConfig: Loading server data');
      Str := Ini.ReadString('Server', 'Ports', DEF_LISTEN_PORTS);
      Log_To_File := Ini.ReadBool('Log', 'SaveToFile', True);
      Log_Console_Data := Ini.ReadBool('Log', 'LogConsoleData', True);
      SplitString(Str, List);
      for I := 0 to List.Count - 1 do
        Server_Port[I] := StrToIntDef(List.Strings[I], 0);
      ServerName_I := Ini.ReadString('Server', 'ReportHost', 'localhost');
      ServerName_T := ServerName_I;
      MyServerHandle := Ini.ReadInteger('Server', 'ServerHandle', 0);
      if MyServerHandle = 0 then
        MyServerHandle := Random(16382) + 1;
      if Win98 then
        Cpu_Usage := Ini.ReadInteger('Server', 'CPUUsage4', 1000)
      else
        Cpu_Usage := Ini.ReadInteger('Server', 'CPUUsage5', 15000);
      Cpu_Disable := Ini.ReadBool('Server', 'CPUDisable', False);
      Listen_Interface := Ini.ReadString('Server', 'SocketsInterface',
        '0.0.0.0');
      Sockets_Users_default := Ini.ReadBool('Server', 'UserSocketsDefault',
        True);
      Sockets_Users_Send := Ini.ReadInteger('Server', 'UserSocketsSend', 8192);
      Sockets_Users_Recv := Ini.ReadInteger('Server', 'UserSocketsRecv', 8192);
      Sockets_Servers_default := Ini.ReadBool('Server', 'ServerSocketsDefault',
        False);
      Sockets_Servers_Send := Ini.ReadInteger('Server', 'ServerSocketsSend',
        32768);
      Sockets_Servers_Recv := Ini.ReadInteger('Server', 'ServerSocketsRecv',
        32768);
      TimeOut_Login := Ini.ReadInteger('Server', 'TimeoutLogin', 60000);
      Network_Hub := Ini.ReadBool('Server', 'NetworkHub', False);
      if Network_Hub then
        Registered_Only := False
      else
        Registered_Only := Ini.ReadBool('Server', 'RegisteredOnly', False);
      Allow_Register := Ini.ReadBool('Server', 'AllowRegister', False);
      Accept_Remote_Users := Ini.ReadBool('Servers',
        'AcceptRemoteUserRegistrations', False);
      Allow_Link := TAllowLinkType(Ini.ReadInteger('Server', 'AllowLink', 1));
      AutoLink_Only1 := Ini.ReadBool('Server', 'LinkOnly1', False);
      Cons_Reg_User := Ini.ReadString('Server', 'RegisteredUser', '');
      ServerAlias := Trim(Ini.ReadString('Server', 'Alias', ServerName_I));
      True_Stats := Ini.ReadBool('Server', 'NoStatsAlias', False);
      if Length(ServerAlias) < 1 then
        ServerAlias := ServerName_I;
      Allowed_Servers := LowerCase(Ini.ReadString('Server', 'AllowedServers',
        ''));
      Restrict_Outgoing := Ini.ReadBool('Server', 'RestrictOutgoingConnections',
        False);
      Outgoing_List := LowerCase(Ini.ReadString('Server', 'RestrictedList',
        ''));
      Remote_Admin_Ok := Ini.ReadBool('Server', 'RemoteAdminOK', False);
      Remote_Adminpass := Ini.ReadString('Server', 'RemoteAdminPass',
        RS_MainForm_RemoteAdminPass);
      Cons_Autojoin1 := Ini.ReadString('Console', 'AutoJoinRoom1', '');
      Cons_Autojoin2 := Ini.ReadString('Console', 'AutoJoinRoom2', '');
      Cons_Autojoin3 := Ini.ReadString('Console', 'AutoJoinRoom3', '');
      Log_Commands := Ini.ReadBool('Log', 'LogCommands', False);
      Log_Napigator := Ini.ReadBool('Log', 'Napigator', True);
      Log_Dagsta := Ini.ReadBool('Log', 'Dagsta', True);
      Log_Login := Ini.ReadBool('Log', 'Login', True);
      Log_Search := Ini.ReadBool('Log', 'Search', False);
      Log_Browse := Ini.ReadBool('Log', 'Browse', True);
      Log_Transfers := Ini.ReadBool('Log', 'Transfers', True);
      // Log_Links := Ini.ReadBool('Log', 'Links', True);
      Log_Servercommands := Ini.ReadBool('Log', 'ServerCommands', False);
      Save_Stats := Ini.ReadBool('Log', 'WriteStats', False);
      Clear_Serverstats := Ini.ReadBool('Log', 'ClearServerStats', False);
      Clear_Clientstats := Ini.ReadBool('Log', 'ClearClientStats', False);
      if Clear_Clientstats then
        if DB_Software <> nil then
          DB_Software.Clear;
      {Language := Ini.ReadString('Server', 'Language', '');
      if Language = '' then
      begin
        LogStartup('MainForm::LoadConfig: Selecting language for the first time');
        SlavaNapLanguage.ShowModal;
      end;}
      Max_Users := Ini.ReadInteger('Server', 'MaxConnections', 500);
      Max_Users_Per_Minute := Ini.ReadInteger('Server', 'MaxUsersPerMinute',
        100);
      Stats_Delay := Ini.ReadInteger('Server', 'Stats', 60000);
      Max_Hotlist := Ini.ReadInteger('Server', 'MaxHotList', 32);
      Max_Ignorelist := Ini.ReadInteger('Server', 'MaxIgnoreList', 32);
      Max_Clones := Ini.ReadInteger('Server', 'MaxClones', 1);
      if Win98 then
        Memory_Limit := Ini.ReadInteger('Server', 'MemoryLimit', 0)
      else
        Memory_Limit := 0;
      Reconnect_Delay := Ini.ReadBool('Server', 'ReconnectDelay', True);
      Flood_Max_Searches := Ini.ReadInteger('Server', 'MaxSearchesPM', 5);
      Search_Noforward_Requests := Ini.ReadBool('Server',
        'SearchLagNoForwardRequests', True);
      Search_Noforward_Results := Ini.ReadBool('Server',
        'SearchLagNoForwardResults', True);
      Browse_Noforward_Requests := Ini.ReadBool('Server',
        'BrowseLagNoForwardRequests', True);
      Browse_Noforward_Results := Ini.ReadBool('Server',
        'BrowseLagNoForwardResults', True);
      TimeOut_Remote_Search := Ini.ReadInteger('Server', 'TimeoutRemoteSearch',
        90000);
      DefSearchResults := Ini.ReadInteger('Server', 'DefSearchResults', 100);
      MaxSearchResults := Ini.ReadInteger('Server', 'MaxSearchResults', 200);
      MaxRemoteSearchResults := Ini.ReadInteger('Server',
        'MaxRemoteSearchResults', 100);
      DisableRemoteSearch := Ini.ReadBool('Server', 'DisableRemoteSearch',
        False);
      MaxBrowseResults := Ini.ReadInteger('Server', 'MaxBrowseResults', 0);
      MaxRemoteBrowse := Ini.ReadInteger('Server', 'MaxRemoteBrowseResults',
        500);
      Hub_Syncreg := Ini.ReadBool('Server', 'SyncRegistered', False);
      Hub_Syncban := Ini.ReadBool('Server', 'SyncBans', Network_Hub);
      Hub_SyncBlock := Ini.ReadBool('Server', 'SyncBlockList', Network_Hub);
      // Meta_Enabled := Ini.ReadBool('Server', 'MetaServer', False);
      // Meta_Port := Ini.ReadInteger('Server', 'MetaPort', 8875);
      Max_Servers_Enabled := Ini.ReadBool('Server', 'LimitServers', False);
      Max_Servers := Ini.ReadInteger('Server', 'MaxServers', 1);
      Wallop_Serverban := Ini.ReadBool('Server', 'WallopServerBans', False);
      Redirect_Cqex := Ini.ReadBool('Server', 'RedirectCQEX', True);
      BanMail := Ini.ReadString('Server', 'BanMail', '');
      Redirect_Url := Ini.ReadString('Server', 'RedirectURL', '');
      Bandwidth_MaxUp := Ini.ReadInteger('Server', 'MaxBandwidthUp', 0);
      Bandwidth_MaxDown := Ini.ReadInteger('Server', 'MaxBandwidthDown', 0);
      Bandwidth_Limitservers := Ini.ReadBool('Server', 'LimitServersBandwidth',
        False);
      Bandwidth_Limited := False;
      Allow_Create_Channels := Ini.ReadBool('Channels', 'AllowCreate', True);
      Max_Channels := Ini.ReadInteger('Channels', 'MaxChannels', 5);
      Max_Channels_Total := Ini.ReadInteger('Channels', 'MaxChannelsTotal',
        100);
      Block_Cqex_Chat := Ini.ReadBool('Channels', 'BlockCQEXColors', True);
      Old_Opsay := Ini.ReadBool('Channels', 'OldOpSay', False);
      Max_Privmsg_Len := Ini.ReadInteger('Channels', 'MaxPrivateMessage', 1024);
      Max_Channelmsg_Len := Ini.ReadInteger('Channels', 'MaxChatMessage', 256);
      Show_Operators := Ini.ReadBool('Channels', 'ShowOperators', True);
      // Channels_Irc := Ini.ReadBool('Channels', 'IRCStyle', False);
      Channels_Irc := False;
      Channels_Timestamp := Ini.ReadBool('Channels', 'TimeStamp', False);
      Channels_Low := Ini.ReadBool('Channels', 'LowerCase', False);
      Prevent_Shouting := Ini.ReadBool('Channels', 'PreventShouting', False);
      Chat_Flash := Ini.ReadBool('Channels', 'ChatFlash', False);
      Chat_MIni := Ini.ReadBool('Channels', 'ChatMinimize', False);
      Wallop_Im := Ini.ReadBool('Channels', 'WallopAsMessage', False);
      Wallop_Sound := Ini.ReadBool('Channels', 'WallopSound', False);
      Cb_Log_Sound.Checked := Ini.ReadBool('Channels', 'ChatSound', False);
      Cb_List_Sound.Checked := Ini.ReadBool('Server', 'FriendSound', False);
      Friend_Sound := Cb_List_Sound.Checked;
      Cb_Hotlist_Sound.Checked := Ini.ReadBool('Server', 'HotlistSound', False);
      Flood_Max_User_Message := Ini.ReadInteger('Channels', 'FloodRepeat', 10);
      Flood_Max_Same_Message := Ini.ReadInteger('Channels', 'FloodSame', 3);
      Flood_Warning := Ini.ReadBool('Channels', 'FloodWarning', True);
      Flood_Enable := Ini.ReadBool('Channels', 'FloodEnabled', True);
      Levels[0] := Ini.ReadString('Levels', 'Leech', Levels[0]);
      Levels[1] := Ini.ReadString('Levels', 'User', Levels[1]);
      Levels[2] := Ini.ReadString('Levels', 'Moderator', Levels[2]);
      Levels[3] := Ini.ReadString('Levels', 'Admin', Levels[3]);
      Levels[4] := Ini.ReadString('Levels', 'Elite', Levels[4]);
      Levels[5] := Ini.ReadString('Levels', 'Console', Levels[5]);
      ShareInform := Ini.ReadBool('Share', 'Inform', False);
      Allow_Share := Ini.ReadBool('Share', 'Allow', True);
      MaxShare := Ini.ReadInteger('Share', 'MaxShare', 10000);
      MinFileName := Ini.ReadInteger('Share', 'MinFileName', 8);
      Auto_FriendAdd := Ini.ReadBool('Share', 'AutoFriendAdd', False);
      Share_Auto_FriendAdd_Minimum := Ini.ReadInteger('Share',
        'AutoFriendAddMin', 10000);
      MaxShareIndex := Ini.ReadInteger('Share', 'MaxIndex', 48);
      MinDuration := Ini.ReadInteger('Share', 'MinDuration', 10);
      MaxShare_Total := GetInt64('Share', 'ServerFilesLimit', 0);
      MaxShare_Audio := Ini.ReadInteger('Share', 'MaxAudio', 10000);
      MinFileSize_Audio := GetInt64('Share', 'MinSizeAudio', 10240);
      MaxFileSize_Audio := GetInt64('Share', 'MaxSizeAudio', 1073741824);
      MaxShare_Video := Ini.ReadInteger('Share', 'MaxVideo', 10000);
      MinFileSize_Video := GetInt64('Share', 'MinSizeVideo', 1048576);
      MaxFileSize_Video := GetInt64('Share', 'MaxSizeVideo', 10737418240);
      MaxShare_Image := Ini.ReadInteger('Share', 'MaxImages', 10000);
      MinFileSize_Image := GetInt64('Share', 'MinSizeImage', 10240);
      MaxFileSize_Image := GetInt64('Share', 'MaxSizeImage', 10485760);
      MaxShare_App := Ini.ReadInteger('Share', 'MaxApps', 10000);
      MinFileSize_App := GetInt64('Share', 'MinSizeApp', 10240);
      MaxFileSize_App := GetInt64('Share', 'MaxSizeApp', 10737418240);
      MaxShare_Cd := Ini.ReadInteger('Share', 'MaxCD', 10000);
      MinFileSize_Cd := GetInt64('Share', 'MinSizeCD', 10485760);
      MaxFileSize_Cd := GetInt64('Share', 'MaxSizeCD', 10737418240);
      MaxShare_Text := Ini.ReadInteger('Share', 'MaxText', 10000);
      MinFileSize_Text := GetInt64('Share', 'MinSizeText', 1);
      MaxFileSize_Text := GetInt64('Share', 'MaxSizeText', 1073741824);
      MaxShare_Mp3 := Ini.ReadInteger('Share', 'MaxMP3', 10000);
      MinFileSize_Mp3 := GetInt64('Share', 'MinSizeMP3', 1048576);
      MaxFileSize_Mp3 := GetInt64('Share', 'MaxSizeMP3', 10737418240);
      Share_Nomodem := Ini.ReadBool('Share', 'NoModem', False);
      Share_Checkdup := Ini.ReadBool('Share', 'CheckDup', True);
      Ext_Mp3 := Ini.ReadString('Share', 'MP3 Extensions',
        RS_MainForm_MP3Extentions);
      Ext_Audio := Ini.ReadString('Share', 'Audio Extensions',
        RS_MainForm_AudioExtentions);
      Ext_Video := Ini.ReadString('Share', 'Video Extensions',
        RS_MainForm_VideoExtentions);
      Ext_Text := Ini.ReadString('Share', 'Text Extensions',
        RS_MainForm_TextExtentions);
      Ext_Image := Ini.ReadString('Share', 'Image Extensions',
        RS_MainForm_ImageExtentions);
      Ext_App := Ini.ReadString('Share', 'App Extensions',
        RS_MainForm_AppExtentions);
      Ext_Cd := Ini.ReadString('Share', 'CD Extensions',
        RS_MainForm_CDExtentions);
      Block_AllowShare := Ini.ReadBool('BlockList', 'AllowShare', False);
      Block_AllowShare_Admins := Ini.ReadBool('BlockList', 'AllowShareAdmins',
        False);
      Block_CheckMods := Ini.ReadBool('BlockList', 'CheckMods', True);
      LogStartup('MainForm::LoadConfig: Checking extensions');
      StrHash_Reset(Ext_Mp3_List);
      SplitString(LowerCase(Ext_Mp3), Ext_Mp3_List);
      StrHash_Reset(Ext_Audio_List);
      SplitString(LowerCase(Ext_Audio), Ext_Audio_List);
      StrHash_Reset(Ext_Video_List);
      SplitString(LowerCase(Ext_Video), Ext_Video_List);
      StrHash_Reset(Ext_Text_List);
      SplitString(LowerCase(Ext_Text), Ext_Text_List);
      StrHash_Reset(Ext_Image_List);
      SplitString(LowerCase(Ext_Image), Ext_Image_List);
      StrHash_Reset(Ext_App_List);
      SplitString(LowerCase(Ext_App), Ext_App_List);
      StrHash_Reset(Ext_Cd_List);
      SplitString(LowerCase(Ext_Cd), Ext_Cd_List);
      Share_320 := Ini.ReadBool('Share', 'Share320', True);
      Share_256 := Ini.ReadBool('Share', 'Share256', True);
      Share_224 := Ini.ReadBool('Share', 'Share224', True);
      Share_192 := Ini.ReadBool('Share', 'Share192', True);
      Share_160 := Ini.ReadBool('Share', 'Share160', True);
      Share_128 := Ini.ReadBool('Share', 'Share128', True);
      Share_112 := Ini.ReadBool('Share', 'Share112', True);
      Share_96 := Ini.ReadBool('Share', 'Share96', True);
      Share_80 := Ini.ReadBool('Share', 'Share80', True);
      Share_64 := Ini.ReadBool('Share', 'Share64', True);
      Share_56 := Ini.ReadBool('Share', 'Share56', True);
      Share_48 := Ini.ReadBool('Share', 'Share48', True);
      Share_40 := Ini.ReadBool('Share', 'Share40', True);
      Share_32 := Ini.ReadBool('Share', 'Share32', True);
      Share_24 := Ini.ReadBool('Share', 'Share24', True);
      Share_Unknown := Ini.ReadBool('Share', 'ShareUnknown', True);
      MinShare := Ini.ReadInteger('Share', 'MinShare', 0);
      MinShare_Delay := Ini.ReadInteger('Share', 'MinShareDelay', 300000);
      MinShare_Ban := Ini.ReadBool('Share', 'MinShareBan', True);
      MinShare_Banip := Ini.ReadBool('Share', 'MinShareBanIP', True);
      MinShare_Bantime := Ini.ReadInteger('Share', 'MinShareBanTime', 600);
      MinShare_Size := Int64(Ini.ReadInteger('Share', 'MinShareSize', 0)) *
        MegaByte;
      MinShare_Fullonly := Ini.ReadBool('Share', 'MinShareFullOnly', True);
      MinShare_Only10 := Ini.ReadBool('Share', 'MinShareKick10', True);
      MinShare_Kickchat := Ini.ReadBool('Share', 'MinShareKickChat', False);
      // if Language <> 'english' then
      // begin
      LogStartup('MainForm::LoadConfig: Loading custom language - ' + Language);
      LoadLanguage(Language, lmRest);
      // end;
      Napigator_Host := Ini.ReadString('Napigator', 'Host',
        'stat.napigator.com');
      Napigator_Port := Ini.ReadString('Napigator', 'Port', '8890');
      Napigator_User := Ini.ReadString('Napigator', 'User', '');
      Napigator_Password := Ini.ReadString('Napigator', 'Password', '');
      Napigator_Enabled := Ini.ReadBool('Napigator', 'Enabled', False);
      Napigator_MyPort := Ini.ReadInteger('Napigator', 'ReportPort',
        Server_Port[0]);
      Napigator_Myip := Ini.ReadString('Napigator', 'ReportIP', '');
      Napigator_Autodisconnect := Ini.ReadBool('Napigator', 'AutoDisconnect',
        False);
      Napigator_Delay := Ini.ReadInteger('Napigator', 'Delay', 60000);
      Napigator_Fake_Ip := Ini.ReadBool('Napigator', 'FakeIP', False);
      if Napigator_Delay < 60000 then
        Napigator_Delay := 60000;
      Dagsta_Host := Ini.ReadString('Dagsta', 'Host', 'dagsta.ath.cx');
      Dagsta_Port := Ini.ReadString('Dagsta', 'Port', '8000');
      Dagsta_User := Ini.ReadString('Dagsta', 'User', '');
      Dagsta_Password := Ini.ReadString('Dagsta', 'Password', '');
      Dagsta_Enabled := Ini.ReadBool('Dagsta', 'Enabled', False);
      Dagsta_MyPort := Ini.ReadInteger('Dagsta', 'ReportPort', Server_Port[0]);
      Dagsta_Myip := Ini.ReadString('Dagsta', 'ReportIP', '');
      Dagsta_Autodisconnect := Ini.ReadBool('Dagsta', 'AutoDisconnect', False);
      Dagsta_Delay := Ini.ReadInteger('Dagsta', 'Delay', 60000);
      if Dagsta_Delay < 60000 then
        Dagsta_Delay := 60000;
      B := False;
      for I := 0 to MAX_LISTEN_SOCKET do
        if Server_Port[I] > 0 then
          if Server_Port[I] = Napigator_MyPort then
            B := True;
      {if Meta_Enabled and (Meta_Port=Napigator_MyPort) then
       B := True;}
      if Enable_Metaserver then
        for I := 0 to Length(MetaPort_List) - 1 do
          if MetaPort_List[I] = Napigator_MyPort then
            B := True;
      if not B then
        Napigator_MyPort := Server_Port[0];
      B := False;
      for I := 0 to MAX_LISTEN_SOCKET do
        if Server_Port[I] > 0 then
          if Server_Port[I] = Dagsta_MyPort then
            B := True;
      {if Meta_Enabled and (Meta_Port=Dagsta_MyPort) then
       B := True;}
      if Enable_Metaserver then
        for I := 0 to Length(MetaPort_List) - 1 do
          if MetaPort_List[I] = Dagsta_MyPort then
            B := True;
      if not B then
        Dagsta_MyPort := Server_Port[0];
      LogStartup('MainForm::LoadConfig: Loading blocked clients');
      for I := 0 to softUnknown do
        Blocked_Clients[I] := False;
      Blocked_Clients[softNapster] := Ini.ReadBool('Blocked', 'Napster', False);
      Blocked_Clients[softAudioGnome] := Ini.ReadBool('Blocked', 'AudioGnome',
        False);
      Blocked_Clients[softWinMXNormal] := Ini.ReadBool('Blocked', 'WinMX',
        False);
      Blocked_Clients[softWinMXHidden] := Ini.ReadBool('Blocked', 'WinMXFake',
        False);
      Blocked_Clients[softFloodster] := Ini.ReadBool('Blocked', 'Floodster',
        True);
      Blocked_Clients[softGnomePlus] := Ini.ReadBool('Blocked', 'GnomePlus+',
        False);
      Blocked_Clients[softAmster] := Ini.ReadBool('Blocked', 'Amster', False);
      Blocked_Clients[softFileNavigator] := Ini.ReadBool('Blocked',
        'FileNavigator', False);
      Blocked_Clients[softCQEX] := Ini.ReadBool('Blocked', 'CQ_EX', False);
      Blocked_Clients[softSunshineUN] := Ini.ReadBool('Blocked', 'SunshineUN',
        False);
      Blocked_Clients[softTekNap] := Ini.ReadBool('Blocked', 'TekNap', False);
      Blocked_Clients[softNap] := Ini.ReadBool('Blocked', 'Nap', False);
      Blocked_Clients[softMacNap] := Ini.ReadBool('Blocked', 'MacNap', False);
      Blocked_Clients[softMP3Rage] := Ini.ReadBool('Blocked', 'MP3Rage', False);
      Blocked_Clients[softXNap] := Ini.ReadBool('Blocked', 'XNap', False);
      Blocked_Clients[softSpotlight] := Ini.ReadBool('Blocked', 'Spotlight',
        False);
      Blocked_Clients[softNFS] := Ini.ReadBool('Blocked', 'NFS', False);
      Blocked_Clients[softDMNapster] := Ini.ReadBool('Blocked', 'DMNapster',
        False);
      Blocked_Clients[softKNapster] := Ini.ReadBool('Blocked', 'KNapster',
        False);
      Blocked_Clients[softLopster] := Ini.ReadBool('Blocked', 'Lopster', False);
      Blocked_Clients[softRapigator] := Ini.ReadBool('Blocked', 'Rapigator',
        False);
      Blocked_Clients[softSwaptor] := Ini.ReadBool('Blocked', 'Swaptor', False);
      Blocked_Clients[softDagsta] := Ini.ReadBool('Blocked', 'Dagsta', False);
      Blocked_Clients[softDrumBeat] := Ini.ReadBool('Blocked', 'Drumbeat',
        True);
      Blocked_Clients[softMlDonkey] := Ini.ReadBool('Blocked', 'MLDonkey',
        True);
      Blocked_Clients[softOpennap] := Ini.ReadBool('Blocked', 'Opennap', True);
      Blocked_Clients[softNapigator] := Ini.ReadBool('Blocked', 'Napigator',
        False);
      Blocked_Clients[softNap08] := Ini.ReadBool('Blocked', 'Nap08', True);
      Blocked_Clients[softWinMXJap] := Ini.ReadBool('Blocked', 'WinMXJap',
        False);
      Blocked_Clients[softUnknown] := Ini.ReadBool('Blocked', 'Other', False);
      Blocked_Message := Ini.ReadString('Blocked', 'CustomMessage',
        RS_MainForm_ServerFull);
      Blocked_Messagetype := TBlockedMessageType(Ini.ReadInteger('Blocked',
        'UseCustomMessage', 0));
      Limit_Mx := Ini.ReadBool('Blocked', 'LimitMX', False);
      Quota_Mx := Ini.ReadInteger('Blocked', 'QuotaMX', 70);
      // Mx_UsePing := Ini.ReadBool('Blocked', 'UsePing', False);
      Mx_UsePing := True; // Fred- No other Detection method Exists atm (b108)
      Mx_Ban := Ini.ReadInteger('Blocked', 'MXBanTime', 86400);
      Ban_FakeMX := Ini.ReadBool('Blocked', 'BanFakeMX', False);
      Mx_Users := 0;
      for I := 0 to Max_Custom_Block do
        Blocked_Custom[I] := Ini.ReadString('Blocked', 'CustomClient' +
          IntToStr(I), '');
      for I := 0 to Max_Announcement do
        Ann_Messages[I] := '';
      Old_Report_Enabled := Ini.ReadBool('OldReport', 'Enabled', False);
      Old_Report_Port := Ini.ReadInteger('OldReport', 'Port', 8889);
      Old_Report_Socket := INVALID_SOCKET;
      New_Report_Enabled := Ini.ReadBool('NewReport', 'Enabled', False);
      New_Report_Port := Ini.ReadInteger('NewReport', 'Port', 1228);
      New_Report_Socket := INVALID_SOCKET;
      New_Report_Hide_Hub := Ini.ReadBool('NewReport', 'HideHub', True);
      LogStartup('MainForm::LoadConfig: Loading announcements');
      StrHash_Reset(Cons_Friends); // Use as Temporary list while loading Data
      StrHash_LoadFromFile(Cons_Friends, ApplicationDir + 'announcements');
      T := Cons_Friends.First;
      I := 0;
      while T <> nil do
      begin
        Ann_Messages[I] := Trim(T^.Data);
        if Trim(T^.Data) <> '' then
          Inc(I);
        T := T^.Next;
      end;
      StrHash_Clear(Cons_Friends);
      Ann_Enabled := Ini.ReadBool('Announcements', 'Enabled', False);
      Ann_User := Ini.ReadString('Announcements', 'User',
        RS_MainForm_AnnounceBot);
      Ann_Delay := Ini.ReadInteger('Announcements', 'Timer', 60);
      // Other2
      SearchBlock_ChkFiles := Ini.ReadBool('Other2', 'SearchBlockByFiles',
        False);
      SearchBlock_ChkSize := Ini.ReadBool('Other2', 'SearchBlockBySize', False);
      SearchBlock_Hard := Ini.ReadBool('Other2', 'SearchBlockHard', False);
      SearchBlock_Files := Ini.ReadInteger('Other2', 'SearchBlockFiles', 0);
      SearchBlock_Size := StrToInt64Def(Ini.ReadString('Other2',
        'SearchBlockSize', '0'), 0);
      DomBlock_ChkFiles := Ini.ReadBool('Other2', 'DomBlockByFiles', False);
      DomBlock_ChkSize := Ini.ReadBool('Other2', 'DomBlockBySize', False);
      DomBlock_Hard := Ini.ReadBool('Other2', 'DomBlockHard', False);
      DomBlock_Files := Ini.ReadInteger('Other2', 'DomBlockFiles', 0);
      DomBlock_Size := StrToInt64Def(Ini.ReadString('Other2', 'DomBlockSize',
        '0'), 0);
      DLFloodBlock_Count := Ini.ReadInteger('Other2', 'DLFloodBlockCount', 0);
      DLFloodBlock_Bantime := Ini.ReadInteger('Other2', 'DLFloodBlockBanTime', 60
        * 60 * 1000);
      Str := Ini.ReadString('Other2', 'DLFloodBlockMethod', 'block');
      if Str = 'leech' then
        DLFloodBlock_Method := Leech
      else if Str = 'ban' then
        DLFloodBlock_Method := Ban
      else
        DLFloodBlock_Method := Block;
      WQFloodBlock_Count := Ini.ReadInteger('Other2', 'WQFloodBlockCount', 0);
      WQFloodBlock_Bantime := Ini.ReadInteger('Other2', 'WQFloodBlockBanTime', 60
        * 60 * 1000);
      Str := Ini.ReadString('Other2', 'WQFloodBlockMethod', 'block');
      if Str = 'leech' then
        WQFloodBlock_Method := Leech
      else if Str = 'ban' then
        WQFloodBlock_Method := Ban
      else
        WQFloodBlock_Method := Block;
      Nocount_Text := Ini.ReadBool('Other2', 'NoCountText', False);
      Autoban_Incomplete := Ini.ReadBool('Other2', 'AutoBanINCOMPLETE', False);
      Disable_FakeExt := Ini.ReadBool('Other2', 'DisableFakeExt', False);
      Fakeext := Ini.ReadString('Other2', 'FakeExt', RS_MainForm_FakeExt);
      StrHash_Reset(Fakeext_List);
      SplitString(AnsiLowerCase(Fakeext), Fakeext_List);
      Enable_TrapPort := Ini.ReadBool('Other2', 'EnableTrapPort', False);
      Str := Ini.ReadString('Other2', 'TrapPort', '8888 8875 7743');
      SplitString(Str, List);
      for I := 0 to List.Count - 1 do
        Trap_Port[I] := StrToIntDef(List.Strings[I], 0);
      Block_TransferPort := Ini.ReadBool('Other2', 'BlockTransferPort', False);
      Blocked_TransferPort := Ini.ReadString('Other2', 'BlockedTransferPort',
        '6699 7743');
      StrHash_Reset(Blocked_TransferPort_List);
      SplitString(Blocked_TransferPort, Blocked_TransferPort_List);
      Share_MatchedFile_Only := Ini.ReadBool('Other2', 'ShareMatchOnly', False);
      for I := 0 to MAX_LOGINIM do
        Loginim[I] := '';
      Enable_Loginim := Ini.ReadBool('Other2', 'EnableLoginIM', False);
      LoginIMBot := Ini.ReadString('Other2', 'LoginIMBot',
        RS_MainForm_LoginIMBot);
      StrHash_Reset(Cons_Friends); // Use as Temporary list while loading Data
      StrHash_LoadFromFile(Cons_Friends, ApplicationDir + 'loginim');
      T := Cons_Friends.First;
      I := 0;
      while T <> nil do
      begin
        Loginim[I] := Trim(T^.Data);
        if Trim(T^.Data) <> '' then
          Inc(I);
        T := T^.Next;
      end;
      StrHash_Clear(Cons_Friends);
      Force_Enter := Ini.ReadBool('Other2', 'ForceEnter', False);
      Force_Enter_Channel := Ini.ReadString('Other2', 'ForceEnterChannel',
        RS_MainForm_ForceEnterChannel);
      StrHash_Reset(Force_Enter_Channel_List);
      SplitString(Force_Enter_Channel, Force_Enter_Channel_List);
      Allow_2ByteName := Ini.ReadBool('Other2', 'Allow2ByteName', False);
      Check_Loginpass := Ini.ReadBool('Other2', 'CheckLoginPass', False);
      Loginpass := Ini.ReadString('Other2', 'LoginPass', '');
      Enable_Msgserv := Ini.ReadBool('Other2', 'EnableMsgServ', False);
      StrHash_Reset(DB_MsgServ);
      // StrHash_LoadFromFile(DB_MsgServ, ApplicationDir + 'dengon');
      MataParaDecrypt(DB_MsgServ, DefaultCryptPass, ApplicationDir + 'dengon');
      Restrict_Hitperuser := Ini.ReadBool('Other2', 'RestrictHitPerUser',
        False);
      MaxHitPerUser := Ini.ReadInteger('Other2', 'MaxHitPerUser', 0);
      MinShare_NoBlockAct := Ini.ReadBool('Other2', 'MinShareNoBlockAct',
        False);
      Blocked_Clients[softNapchan] := Ini.ReadBool('Blocked', 'Napchan', False);
      Blocked_Clients[softUtatane] := Ini.ReadBool('Blocked', 'Utatane', False);
      Blocked_Clients[soft2get] := Ini.ReadBool('Blocked', '2get', False);
      Blocked_Clients[softRegnessem] := Ini.ReadBool('Blocked', 'Regnessem',
        False);
      Kill_Idleuser := Ini.ReadBool('Other2', 'KillIdleUser', False);
      Kill_Idleuser_Time := Ini.ReadInteger('Other2', 'KillIdleUserTime', 180);
      Listall_for_Users := Ini.ReadBool('Other2', 'ListAllForUsers', True);
      Block_Weird_XnapFile := Ini.ReadBool('Other2', 'BlockWeirdXNapFile',
        False);
      Suggest_DBrowse := Ini.ReadBool('Other2', 'SuggestDirectBrowse', False);
      Log_Folder := Ini.ReadString('Other2', 'LogFolder', ApplicationDir);
      Max_Resolving_Count := Ini.ReadInteger('Other2', 'MaxResolvingCount', 3);
      Allow_Rtf_Code := Ini.ReadBool('Other2', 'AllowRTFCode', False);
      Enable_Metaserver := Ini.ReadBool('Other2', 'EnableMetaServer', False);
      MetaPort := Ini.ReadString('Other2', 'MetaPort', '8875');
      SplitString(MetaPort, List);
      SetLength(MetaPort_List, List.Count);
      for I := 0 to List.Count - 1 do
        MetaPort_List[I] := StrToIntDef(List.Strings[I], -1);
      Redirected_Servers := TNapCmdList.Create;
      Redirected_Server := Ini.ReadString('Other2', 'RedirectedServer', '');
      Redirected_Server_Chk := Ini.ReadString('Other2',
        'RedirectedServerCheckList', '0');
      List2 := TMyStringList.Create;
      SplitString(Redirected_Server, List);
      SplitString(Redirected_Server_Chk, List2);
      for I := 0 to List.Count - 1 do
        Redirected_Servers.AddCmd(StrToIntDef(List2.Strings[I], Integer(True)),
          List.Strings[I]);
      List2.Free;
      Disable_Nullip := Ini.ReadBool('Other2', 'DisableNullIP', False);

      // set up Console
      LogStartup('MainForm::LoadConfig: Setting up console user');
      Cons_Channels := TMyList.Create;
      Cons_Chat := TMyList.Create;
      Cons_Whois := TMyList.Create;
      Cons_Browse := TMyList.Create;
      StrHash_Reset(Cons_Blocks);
      StrHash_Reset(Cons_Ignored);
      Cons_List := consFriends;
      Cons := TLocalUser.Create;
      Cons.LocalState := Cons.LocalState + [locPingable];
      Cons.Last_Seen := GetTickCount;
      Rec.UserName := Ini.ReadString('Console', 'User',
        RS_MainForm_ConsoleName);
      Rec.NameCrc := StringCRC(Rec.UserName, True);
      Rec.State := Int2UserState(Ini.ReadInteger('Console', 'UserMode', 0),
        False);
      Rec.Speed := TNapSpeed(Ini.ReadInteger('Console', 'Speed', 0));
      Restart_User := Rec.UserName;
      Rec.Password := Console_Pass;
      Rec.Software := Console_Soft;
      Rec.Level := napUserConsole;
      Rec.Ip := 0;
      Rec.DataPort := 0;
      Rec.Uploads := 0;
      Rec.Downloads := 0;
      Rec.Total_Up := 0;
      Rec.Total_Down := 0;
      Rec.Max_Up := 0;
      Rec.Queue := 0;
      Rec.Shared := 0;
      Rec.Server := nil;
      Rec.Last_Seen_T := Current_Time_T;
      Rec.Local := Cons;
      Cons.Data := DB_Online.AddUser(Rec);
      LogStartup('MainForm::LoadConfig: Loading hotlist and ignored list');
      StrHash_Reset(Cons.Hotlist);
      StrHash_LoadFromFile(Cons.Hotlist, ApplicationDir + 'hotlist');
      StrHash_Reset(Cons.Ignored);
      StrHash_LoadFromFile(Cons.Ignored, ApplicationDir + 'ignored');
      DB_Local.Add(Cons);
      Inc(Local_Users);
      Inc(Total_Users);
      Inc(Local_Users_Max);
      Inc(Total_Users_Max);
      Ini.UpdateFile;
    finally
      List.Free;
    end;
  finally
    Ini.Free;
  end;
  LogStartup('MainForm::LoadConfig: end;');
end;

procedure TSlavaNapWindow.SaveConfig;
var
  Ini: TMemIniFile;
  I: Integer;
  List: TMyStringList;
  procedure PutInt64(Section, Value: string; Val: Int64);
  begin
    Ini.WriteString(Section, Value, IntToStr(Val));
  end;
begin
  Ini := TMemIniFile.Create(ApplicationDir + 'config');
  try
    Ini.WriteString('Server', 'Version', SLAVANAP_VERSION);
    // interface
    if WindowState = wsNormal then
    begin
      Ini.WriteInteger('Interface', 'Left', Left);
      Ini.WriteInteger('Interface', 'Top', Top);
      Ini.WriteInteger('Interface', 'Width', Width);
      Ini.WriteInteger('Interface', 'Height', Height);
      Ini.WriteInteger('Interface', 'Splitter', Panel_Console.Height);
    end;
    Ini.WriteInteger('Interface', 'State', Ord(WindowState));
    Ini.WriteBool('Interface', 'ShowToolBar', not ToolBar.Rolled);
    Ini.WriteBool('Interface', 'HideStatus2', Bar_Bottom2.Rolled);
    Ini.WriteBool('Interface', 'HideStatus3', Bar_Bottom3.Rolled);
    Ini.WriteBool('Interface', 'HideStatus4', Bar_Bottom4.Rolled);
    Ini.WriteBool('Interface', 'HideStatus5', Bar_Bottom5.Rolled);
    Ini.WriteBool('Interface', 'HideRegisterBtn', Tb_Register.Rolled);
    Ini.WriteBool('Interface', 'ShowTray', Tray.Active);
    Ini.WriteBool('Interface', 'SwitchChat', Switch_Chat);
    Ini.WriteString('Interface', 'UsersReason', Edit_Users_Reason.Text);
    Ini.WriteBool('Interface', 'CBUsersModes', Cb_Users_Mods.Checked);
    Ini.WriteBool('Interface', 'CBUsersUsers', Cb_Users_Users.Checked);
    Ini.WriteBool('Interface', 'CBUsersLeeched', Cb_Users_Leeches.Checked);
    Ini.WriteBool('Interface', 'CBUsersMuzzled', Cb_Users_Muzzled.Checked);
    Ini.WriteBool('Interface', 'CBUsersLocal', Cb_Users_Local.Checked);
    Ini.WriteBool('Interface', 'CBUsersRemote', Cb_Users_Remote.Checked);
    Ini.WriteString('Interface', 'UsersFilter', Edit_Users_Filter.Text);
    Ini.WriteString('Interface', 'RegFilter', Edit_Reg_Filter.Text);
    Ini.WriteString('Interface', 'RegReason', Edit_Reg_Reason.Text);
    Ini.WriteString('Interface', 'ChReason', Edit_Ch_Reason.Text);
    Ini.WriteString('Interface', 'BanReason', Edit_Ban_Reason.Text);
    Ini.WriteString('Interface', 'UnBanReason', Edit_Unban_Reason.Text);
    Ini.WriteInteger('Interface', 'SortUsers', List_Users.Tag);
    Ini.WriteInteger('Interface', 'SortRegistered', List_Registered.Tag);
    Ini.WriteInteger('Interface', 'SortServers', List_Servers.Tag);
    Ini.WriteInteger('Interface', 'SortChannels', List_Channels.Tag);
    Ini.WriteInteger('Interface', 'SortBans', List_Bans.Tag);
    Ini.WriteInteger('Interface', 'SortLists', List_Lists.Tag);
    Ini.WriteInteger('Interface', 'SortHotlist', List_Hotlist.Tag);
    Ini.WriteBool('Interface', 'RefreshUsers', Cb_Users_Refresh.Checked);
    Ini.WriteInteger('Interface', 'RefreshUsersDelay',
      Edit_Users_Refresh.Value);
    Ini.WriteBool('Interface', 'RefreshServers', Cb_Servers_Refresh.Checked);
    Ini.WriteInteger('Interface', 'RefreshServersDelay',
      Edit_Servers_Refresh.Value);
    Ini.WriteBool('Interface', 'IsAway', Cb_Log_Away.Checked);
    Ini.WriteBool('Interface', 'AwayPopup', Cb_Log_Awaypopup.Checked);
    Ini.WriteString('Interface', 'AwayMessage', Edit_Log_Away.Text);
    Ini.WriteBool('Interface', 'UsersListHideLevel', not
      IsColumnVisible(List_Users, UL_LEVEL + 1));
    Ini.WriteBool('Interface', 'UsersListHideShared', not
      IsColumnVisible(List_Users, UL_SHARED + 1));
    Ini.WriteBool('Interface', 'UsersListHideSize', not
      IsColumnVisible(List_Users, UL_SIZE + 1));
    Ini.WriteBool('Interface', 'UsersListHideAverage', not
      IsColumnVisible(List_Users, UL_AVERAGE + 1));
    Ini.WriteBool('Interface', 'UsersListHideSoft', not
      IsColumnVisible(List_Users, UL_SOFT + 1));
    Ini.WriteBool('Interface', 'UsersListHideSpeed', not
      IsColumnVisible(List_Users, UL_SPEED + 1));
    Ini.WriteBool('Interface', 'UsersListHideIP', not
      IsColumnVisible(List_Users, UL_IP + 1));
    Ini.WriteBool('Interface', 'UsersListHideRemoteHost', not
      IsColumnVisible(List_Users, UL_REMOTEHOST + 1));
    Ini.WriteBool('Interface', 'UsersListHidePort', not
      IsColumnVisible(List_Users, UL_PORT + 1));
    Ini.WriteBool('Interface', 'UsersListHideTime', not
      IsColumnVisible(List_Users, UL_TIME + 1));
    Ini.WriteBool('Interface', 'UsersListHideUp', not
      IsColumnVisible(List_Users, UL_UP + 1));
    Ini.WriteBool('Interface', 'UsersListHideDown', not
      IsColumnVisible(List_Users, UL_DOWN + 1));
    Ini.WriteBool('Interface', 'UsersListHideTransfers', not
      IsColumnVisible(List_Users, UL_TRANSFERS + 1));
    Ini.WriteBool('Interface', 'UsersListHideTotalUp', not
      IsColumnVisible(List_Users, UL_TUP + 1));
    Ini.WriteBool('Interface', 'UsersListHideTotalDown', not
      IsColumnVisible(List_Users, UL_TDOWN + 1));
    Ini.WriteBool('Interface', 'UsersListHideTotal', not
      IsColumnVisible(List_Users, UL_TTRANSFERS + 1));
    Ini.WriteBool('Interface', 'UsersListHideServer', not
      IsColumnVisible(List_Users, UL_SERVER + 1));
    Ini.WriteBool('Interface', 'UsersListHideULRequests', not
      IsColumnVisible(List_Users, UL_ULREQUESTS + 1));
    Ini.WriteBool('Interface', 'UsersListHideDLRequests', not
      IsColumnVisible(List_Users, UL_DLREQUESTS + 1));
    Ini.WriteBool('Interface', 'UsersListHideSearchReqs', not
      IsColumnVisible(List_Users, UL_SEARCHREQS + 1));
    Ini.WriteBool('Interface', 'UsersListHideBlockFiles', not
      IsColumnVisible(List_Users, UL_BLOCKFILES + 1));
    // Colors
    Ini.WriteInteger('Colors', 'clBackground', slBackground);
    Ini.WriteInteger('Colors', 'clText', slText);
    Ini.WriteInteger('Colors', 'clError', slError);
    Ini.WriteInteger('Colors', 'clWallop', slWallop);
    Ini.WriteInteger('Colors', 'clAnnounce', slAnnounce);
    Ini.WriteInteger('Colors', 'clWhowas', slWhowas);
    Ini.WriteInteger('Colors', 'clPong', slPong);
    Ini.WriteInteger('Colors', 'clOffline', slOffline);
    Ini.WriteInteger('Colors', 'clOnline', slOnline);
    Ini.WriteInteger('Colors', 'clDebugData', slDebugData);
    Ini.WriteInteger('Colors', 'clNapigator', slNapigator);
    Ini.WriteInteger('Colors', 'clDagsta', slDagsta);
    Ini.WriteInteger('Colors', 'clSearch', slSearch);
    Ini.WriteInteger('Colors', 'clBrowse', slBrowse);
    Ini.WriteInteger('Colors', 'clTransfer', slTransfer);
    Ini.WriteInteger('Colors', 'clTopic', slTopic);
    Ini.WriteInteger('Colors', 'clChannelMessage', slChannelMessage);
    Ini.WriteInteger('Colors', 'clChannelMyMessage', slChannelMyMessage);
    Ini.WriteInteger('Colors', 'clChannelEmote', slChannelEmote);
    Ini.WriteInteger('Colors', 'clChannelMyEmote', slChannelMyEmote);
    Ini.WriteInteger('Colors', 'clChannelJoin', slChannelJoin);
    Ini.WriteInteger('Colors', 'clChannelPart', slChannelPart);
    Ini.WriteInteger('Colors', 'clChatMessage', slChatMessage);
    Ini.WriteInteger('Colors', 'clChatMyMessage', slChatMyMessage);
    // Server data
  //  Str := '';
  //  for I := 0 to MAX_LISTEN_SOCKET do
  //   if Server_Port[I] <> 0 then
  //    Str := Str + ' ' + IntToStr(Server_Port[I]);
  //  Ini.WriteString('Server', 'Ports', Trim(Str));
  //  Ini.WriteString('Server', 'ReportHost', ServerName_I);
    Ini.WriteString('Server', 'SocketsInterface', Listen_Interface);
    Ini.WriteBool('Server', 'UserSocketsDefault', Sockets_Users_default);
    Ini.WriteInteger('Server', 'UserSocketsSend', Sockets_Users_Send);
    Ini.WriteInteger('Server', 'UserSocketsRecv', Sockets_Users_Recv);
    Ini.WriteBool('Server', 'ServerSocketsDefault', Sockets_Servers_default);
    Ini.WriteInteger('Server', 'ServerSocketsSend', Sockets_Servers_Send);
    Ini.WriteInteger('Server', 'ServerSocketsRecv', Sockets_Servers_Recv);
    if Win98 then
      Ini.WriteInteger('Server', 'CPUUsage4', Cpu_Usage)
    else
      Ini.WriteInteger('Server', 'CPUUsage5', Cpu_Usage);
    Ini.WriteBool('Server', 'CPUDisable', Cpu_Disable);
    Ini.WriteInteger('Interface', 'CloseWindow', Ord(B3_Canclose));
    try
      if Running then
        if Cons <> nil then
        begin
          Ini.WriteInteger('Console', 'Speed', Ord(Cons.Data^.Speed));
          Ini.WriteInteger('Console', 'UserMode',
            UserState2Int(Cons.Data^.State));
        end;
    except
    end;
    Ini.WriteBool('Log', 'SaveToFile', Log_To_File);
    Ini.WriteBool('Log', 'LogConsoleData', Log_Console_Data);
    Ini.WriteBool('Log', 'LogCommands', Log_Commands);
    Ini.WriteBool('Log', 'Napigator', Log_Napigator);
    Ini.WriteBool('Log', 'Dagsta', Log_Dagsta);
    Ini.WriteBool('Log', 'Login', Log_Login);
    Ini.WriteBool('Log', 'Search', Log_Search);
    Ini.WriteBool('Log', 'Browse', Log_Browse);
    Ini.WriteBool('Log', 'Transfers', Log_Transfers);
    //  Ini.WriteBool('Log', 'Links', Log_Links);
    Ini.WriteBool('Log', 'ServerCommands', Log_Servercommands);
    Ini.WriteBool('Log', 'WriteStats', Save_Stats);
    Ini.WriteBool('Log', 'ClearServerStats', Clear_Serverstats);
    Ini.WriteBool('Log', 'ClearClientStats', Clear_Clientstats);
    Ini.WriteBool('Server', 'NoStatsAlias', True_Stats);
    Ini.WriteInteger('Server', 'TimeoutLogin', TimeOut_Login);
    Ini.WriteBool('Server', 'RegisteredOnly', Registered_Only);
    Ini.WriteBool('Servers', 'AcceptRemoteUserRegistrations',
      Accept_Remote_Users);
    Ini.WriteString('Server', 'Language', Language);
    Ini.WriteInteger('Server', 'MaxConnections', Max_Users);
    Ini.WriteInteger('Server', 'MaxUsersPerMinute', Max_Users_Per_Minute);
    Ini.WriteBool('Server', 'AllowRegister', Allow_Register);
    Ini.WriteInteger('Server', 'AllowLink', Ord(Allow_Link));
    Ini.WriteBool('Server', 'LinkOnly1', AutoLink_Only1);
    Ini.WriteString('Server', 'RegisteredUser', Cons_Reg_User);
    Ini.WriteBool('Server', 'ReconnectDelay', Reconnect_Delay);
    Ini.WriteString('Server', 'AllowedServers', Allowed_Servers);
    Ini.WriteBool('Server', 'RestrictOutgoingConnections', Restrict_Outgoing);
    Ini.WriteString('Server', 'RestrictedList', Outgoing_List);
    Ini.WriteBool('Server', 'RemoteAdminOK', Remote_Admin_Ok);
    Ini.WriteString('Server', 'RemoteAdminPass', Remote_Adminpass);
    Ini.WriteInteger('Server', 'MemoryLimit', Memory_Limit);
    Ini.WriteInteger('Server', 'Stats', Stats_Delay);
    Ini.WriteInteger('Server', 'MaxHotList', Max_Hotlist);
    Ini.WriteInteger('Server', 'MaxIgnoreList', Max_Ignorelist);
    Ini.WriteInteger('Server', 'MaxClones', Max_Clones);
    Ini.WriteInteger('Server', 'MaxSearchesPM', Flood_Max_Searches);
    Ini.WriteInteger('Server', 'TimeoutRemoteSearch', TimeOut_Remote_Search);
    Ini.WriteBool('Server', 'SearchLagNoForwardRequests',
      Search_Noforward_Requests);
    Ini.WriteBool('Server', 'SearchLagNoForwardResults',
      Search_Noforward_Results);
    Ini.WriteBool('Server', 'BrowseLagNoForwardRequests',
      Browse_Noforward_Requests);
    Ini.WriteBool('Server', 'BrowseLagNoForwardResults',
      Browse_Noforward_Results);
    Ini.WriteInteger('Server', 'DefSearchResults', DefSearchResults);
    Ini.WriteInteger('Server', 'MaxSearchResults', MaxSearchResults);
    Ini.WriteInteger('Server', 'MaxRemoteSearchResults',
      MaxRemoteSearchResults);
    Ini.WriteBool('Server', 'DisableRemoteSearch', DisableRemoteSearch);
    Ini.WriteInteger('Server', 'MaxBrowseResults', MaxBrowseResults);
    Ini.WriteInteger('Server', 'MaxRemoteBrowseResults', MaxRemoteBrowse);
    Ini.WriteBool('Server', 'NetworkHub', Network_Hub);
    Ini.WriteBool('Server', 'SyncRegistered', Hub_Syncreg);
    Ini.WriteBool('Server', 'SyncBans', Hub_Syncban);
    Ini.WriteBool('Server', 'SyncBlockList', Hub_SyncBlock);
    {Ini.WriteBool('Server', 'MetaServer', Meta_Enabled);
    Ini.WriteInteger('Server', 'MetaPort', Meta_Port);}
    Ini.WriteBool('Server', 'LimitServers', Max_Servers_Enabled);
    Ini.WriteInteger('Server', 'MaxServers', Max_Servers);
    Ini.WriteBool('Server', 'WallopServerBans', Wallop_Serverban);
    Ini.WriteBool('Server', 'RedirectCQEX', Redirect_Cqex);
    Ini.WriteInteger('Server', 'MaxBandwidthUp', Bandwidth_MaxUp);
    Ini.WriteInteger('Server', 'MaxBandwidthDown', Bandwidth_MaxDown);
    Ini.WriteBool('Server', 'LimitServersBandwidth', Bandwidth_Limitservers);
    Ini.WriteString('Server', 'BanMail', BanMail);
    Ini.WriteString('Server', 'RedirectURL', Redirect_Url);
    Ini.WriteBool('Share', 'Inform', ShareInform);
    Ini.WriteBool('Share', 'Allow', Allow_Share);
    Ini.WriteInteger('Share', 'MaxShare', MaxShare);
    Ini.WriteInteger('Share', 'MinFileName', MinFileName);
    Ini.WriteBool('Share', 'AutoFriendAdd', Auto_FriendAdd);
    Ini.WriteInteger('Share', 'AutoFriendAddMin', Share_Auto_FriendAdd_Minimum);
    Ini.WriteInteger('Share', 'MaxIndex', MaxShareIndex);
    Ini.WriteInteger('Share', 'MinDuration', MinDuration);
    PutInt64('Share', 'ServerFilesLimit', MaxShare_Total);
    Ini.WriteInteger('Share', 'MaxAudio', MaxShare_Audio);
    PutInt64('Share', 'MinSizeAudio', MinFileSize_Audio);
    PutInt64('Share', 'MaxSizeAudio', MaxFileSize_Audio);
    Ini.WriteInteger('Share', 'MaxVideo', MaxShare_Video);
    PutInt64('Share', 'MinSizeVideo', MinFileSize_Video);
    PutInt64('Share', 'MaxSizeVideo', MaxFileSize_Video);
    Ini.WriteInteger('Share', 'MaxImages', MaxShare_Image);
    PutInt64('Share', 'MinSizeImage', MinFileSize_Image);
    PutInt64('Share', 'MaxSizeImage', MaxFileSize_Image);
    Ini.WriteInteger('Share', 'MaxApps', MaxShare_App);
    PutInt64('Share', 'MinSizeApp', MinFileSize_App);
    PutInt64('Share', 'MaxSizeApp', MaxFileSize_App);
    Ini.WriteInteger('Share', 'MaxCD', MaxShare_Cd);
    PutInt64('Share', 'MinSizeCD', MinFileSize_Cd);
    PutInt64('Share', 'MaxSizeCD', MaxFileSize_Cd);
    Ini.WriteInteger('Share', 'MaxText', MaxShare_Text);
    PutInt64('Share', 'MinSizeText', MinFileSize_Text);
    PutInt64('Share', 'MaxSizeText', MaxFileSize_Text);
    Ini.WriteInteger('Share', 'MaxMP3', MaxShare_Mp3);
    PutInt64('Share', 'MinSizeMP3', MinFileSize_Mp3);
    PutInt64('Share', 'MaxSizeMP3', MaxFileSize_Mp3);
    Ini.WriteBool('Share', 'NoModem', Share_Nomodem);
    Ini.WriteBool('Share', 'CheckDup', Share_Checkdup);
    Ini.WriteBool('Share', 'Share320', Share_320);
    Ini.WriteBool('Share', 'Share256', Share_256);
    Ini.WriteBool('Share', 'Share224', Share_224);
    Ini.WriteBool('Share', 'Share192', Share_192);
    Ini.WriteBool('Share', 'Share160', Share_160);
    Ini.WriteBool('Share', 'Share128', Share_128);
    Ini.WriteBool('Share', 'Share112', Share_112);
    Ini.WriteBool('Share', 'Share96', Share_96);
    Ini.WriteBool('Share', 'Share80', Share_80);
    Ini.WriteBool('Share', 'Share64', Share_64);
    Ini.WriteBool('Share', 'Share56', Share_56);
    Ini.WriteBool('Share', 'Share48', Share_48);
    Ini.WriteBool('Share', 'Share40', Share_40);
    Ini.WriteBool('Share', 'Share32', Share_32);
    Ini.WriteBool('Share', 'Share24', Share_24);
    Ini.WriteBool('Share', 'ShareUnknown', Share_Unknown);
    Ini.WriteInteger('Share', 'MinShare', MinShare);
    Ini.WriteInteger('Share', 'MinShareDelay', MinShare_Delay);
    Ini.WriteBool('Share', 'MinShareBan', MinShare_Ban);
    Ini.WriteBool('Share', 'MinShareBanIP', MinShare_Banip);
    Ini.WriteInteger('Share', 'MinShareBanTime', MinShare_Bantime);
    Ini.WriteInteger('Share', 'MinShareSize', MinShare_Size div MegaByte);
    Ini.WriteBool('Share', 'MinShareFullOnly', MinShare_Fullonly);
    Ini.WriteBool('Share', 'MinShareKick10', MinShare_Only10);
    Ini.WriteBool('Share', 'MinShareKickChat', MinShare_Kickchat);
    Ini.WriteString('Share', 'MP3 Extensions', Ext_Mp3);
    Ini.WriteString('Share', 'Audio Extensions', Ext_Audio);
    Ini.WriteString('Share', 'Video Extensions', Ext_Video);
    Ini.WriteString('Share', 'Text Extensions', Ext_Text);
    Ini.WriteString('Share', 'Image Extensions', Ext_Image);
    Ini.WriteString('Share', 'App Extensions', Ext_App);
    Ini.WriteString('Share', 'CD Extensions', Ext_Cd);
    Ini.WriteBool('BlockList', 'AllowShare', Block_AllowShare);
    Ini.WriteBool('BlockList', 'AllowShareAdmins', Block_AllowShare_Admins);
    Ini.WriteBool('BlockList', 'CheckMods', Block_CheckMods);
    Ini.WriteBool('Channels', 'AllowCreate', Allow_Create_Channels);
    Ini.WriteInteger('Channels', 'MaxChannels', Max_Channels);
    Ini.WriteInteger('Channels', 'MaxChannelsTotal', Max_Channels_Total);
    Ini.WriteBool('Channels', 'BlockCQEXColors', Block_Cqex_Chat);
    Ini.WriteBool('Channels', 'OldOpSay', Old_Opsay);
    Ini.WriteInteger('Channels', 'MaxPrivateMessage', Max_Privmsg_Len);
    Ini.WriteInteger('Channels', 'MaxChatMessage', Max_Channelmsg_Len);
    Ini.WriteBool('Channels', 'ShowOperators', Show_Operators);
    Ini.WriteBool('Channels', 'PreventShouting', Prevent_Shouting);
    Ini.WriteBool('Channels', 'ChatFlash', Chat_Flash);
    Ini.WriteBool('Channels', 'ChatMinimize', Chat_Mini);
    Ini.WriteBool('Channels', 'WallopAsMessage', Wallop_Im);
    Ini.WriteBool('Channels', 'WallopSound', Wallop_Sound);
    Ini.WriteBool('Channels', 'ChatSound', Cb_Log_Sound.Checked);
    Ini.WriteBool('Server', 'FriendSound', Cb_List_Sound.Checked);
    Ini.WriteBool('Server', 'HotlistSound', Cb_Hotlist_Sound.Checked);
    Ini.WriteInteger('Channels', 'FloodRepeat', Flood_Max_User_Message);
    Ini.WriteInteger('Channels', 'FloodSame', Flood_Max_Same_Message);
    Ini.WriteBool('Channels', 'FloodWarning', Flood_Warning);
    Ini.WriteBool('Channels', 'FloodEnabled', Flood_Enable);
    Ini.WriteString('Napigator', 'Host', Napigator_Host);
    Ini.WriteString('Napigator', 'Port', Napigator_Port);
    Ini.WriteString('Napigator', 'User', Napigator_User);
    Ini.WriteString('Napigator', 'Password', Napigator_Password);
    Ini.WriteBool('Napigator', 'Enabled', Napigator_Enabled);
    Ini.WriteInteger('Napigator', 'ReportPort', Napigator_MyPort);
    Ini.WriteString('Napigator', 'ReportIP', Napigator_Myip);
    Ini.WriteBool('Napigator', 'AutoDisconnect', Napigator_Autodisconnect);
    Ini.WriteInteger('Napigator', 'Delay', Napigator_Delay);
    Ini.WriteString('Dagsta', 'Host', Dagsta_Host);
    Ini.WriteString('Dagsta', 'Port', Dagsta_Port);
    Ini.WriteString('Dagsta', 'User', Dagsta_User);
    Ini.WriteString('Dagsta', 'Password', Dagsta_Password);
    Ini.WriteBool('Dagsta', 'Enabled', Dagsta_Enabled);
    Ini.WriteInteger('Dagsta', 'ReportPort', Dagsta_MyPort);
    Ini.WriteString('Dagsta', 'ReportIP', Dagsta_Myip);
    Ini.WriteBool('Dagsta', 'AutoDisconnect', Dagsta_Autodisconnect);
    Ini.WriteInteger('Dagsta', 'Delay', Dagsta_Delay);
    Ini.WriteString('Levels', 'Leech', Levels[0]);
    Ini.WriteString('Levels', 'User', Levels[1]);
    Ini.WriteString('Levels', 'Moderator', Levels[2]);
    Ini.WriteString('Levels', 'Admin', Levels[3]);
    Ini.WriteString('Levels', 'Elite', Levels[4]);
    Ini.WriteString('Levels', 'Console', Levels[5]);
    Ini.WriteBool('Blocked', 'Napster', Blocked_Clients[softNapster]);
    Ini.WriteBool('Blocked', 'AudioGnome', Blocked_Clients[softAudioGnome]);
    Ini.WriteBool('Blocked', 'WinMX', Blocked_Clients[softWinMXNormal]);
    Ini.WriteBool('Blocked', 'WinMXFake', Blocked_Clients[softWinMXHidden]);
    Ini.WriteBool('Blocked', 'Floodster', Blocked_Clients[softFloodster]);
    Ini.WriteBool('Blocked', 'GnomePlus+', Blocked_Clients[softGnomePlus]);
    Ini.WriteBool('Blocked', 'Amster', Blocked_Clients[softAmster]);
    Ini.WriteBool('Blocked', 'FileNavigator',
      Blocked_Clients[softFileNavigator]);
    Ini.WriteBool('Blocked', 'CQ_EX', Blocked_Clients[softCQEX]);
    Ini.WriteBool('Blocked', 'SunshineUN', Blocked_Clients[softSunshineUN]);
    Ini.WriteBool('Blocked', 'TekNap', Blocked_Clients[softTekNap]);
    Ini.WriteBool('Blocked', 'Nap', Blocked_Clients[softNap]);
    Ini.WriteBool('Blocked', 'MacNap', Blocked_Clients[softMacNap]);
    Ini.WriteBool('Blocked', 'MP3Rage', Blocked_Clients[softMP3Rage]);
    Ini.WriteBool('Blocked', 'XNap', Blocked_Clients[softXNap]);
    Ini.WriteBool('Blocked', 'Spotlight', Blocked_Clients[softSpotlight]);
    Ini.WriteBool('Blocked', 'NFS', Blocked_Clients[softNFS]);
    Ini.WriteBool('Blocked', 'DMNapster', Blocked_Clients[softDMNapster]);
    Ini.WriteBool('Blocked', 'KNapster', Blocked_Clients[softKNapster]);
    Ini.WriteBool('Blocked', 'Lopster', Blocked_Clients[softLopster]);
    Ini.WriteBool('Blocked', 'Rapigator', Blocked_Clients[softRapigator]);
    Ini.WriteBool('Blocked', 'Swaptor', Blocked_Clients[softSwaptor]);
    Ini.WriteBool('Blocked', 'Dagsta', Blocked_Clients[softDagsta]);
    Ini.WriteBool('Blocked', 'Drumbeat', Blocked_Clients[softDrumBeat]);
    Ini.WriteBool('Blocked', 'MLDonkey', Blocked_Clients[softMlDonkey]);
    Ini.WriteBool('Blocked', 'Opennap', Blocked_Clients[softOpennap]);
    Ini.WriteBool('Blocked', 'Napigator', Blocked_Clients[softNapigator]);
    Ini.WriteBool('Blocked', 'Nap08', Blocked_Clients[softNap08]);
    Ini.WriteBool('Blocked', 'WinMXJap', Blocked_Clients[softWinMXJap]);
    Ini.WriteBool('Blocked', 'Other', Blocked_Clients[softUnknown]);
    Ini.WriteString('Blocked', 'CustomMessage', Blocked_Message);
    Ini.WriteInteger('Blocked', 'UseCustomMessage', Ord(Blocked_Messagetype));
    Ini.WriteBool('Blocked', 'LimitMX', Limit_Mx);
    Ini.WriteInteger('Blocked', 'QuotaMX', Quota_Mx);
    Ini.WriteBool('Blocked', 'UsePing', Mx_UsePing);
    Ini.WriteInteger('Blocked', 'MXBanTime', Mx_Ban);
    Ini.WriteBool('Blocked', 'BanFakeMX', Ban_FakeMX);
    for I := 0 to Max_Custom_Block do
      Ini.WriteString('Blocked', 'CustomClient' + IntToStr(I),
        Blocked_Custom[I]);
    Ini.WriteBool('Announcements', 'Enabled', Ann_Enabled);
    Ini.WriteString('Announcements', 'User', Ann_User);
    Ini.WriteInteger('Announcements', 'Timer', Ann_Delay);
    List := TMyStringList.Create;
    for I := 0 to Max_Announcement do
      if Ann_Messages[I] <> '' then
        List.Add(Ann_Messages[I]);
    try
      List.SaveToFile(ApplicationDir + 'announcements');
    except
    end;
    List.Free;
    Ini.WriteBool('OldReport', 'Enabled', Old_Report_Enabled);
    Ini.WriteInteger('OldReport', 'Port', Old_Report_Port);
    Ini.WriteBool('NewReport', 'Enabled', New_Report_Enabled);
    Ini.WriteInteger('NewReport', 'Port', New_Report_Port);
    Ini.WriteBool('NewReport', 'HideHub', New_Report_Hide_Hub);
    // Other2
    Ini.WriteBool('Other2', 'SearchBlockByFiles', SearchBlock_ChkFiles);
    Ini.WriteBool('Other2', 'SearchBlockBySize', SearchBlock_ChkSize);
    Ini.WriteBool('Other2', 'SearchBlockHard', SearchBlock_Hard);
    Ini.WriteInteger('Other2', 'SearchBlockFiles', SearchBlock_Files);
    Ini.WriteString('Other2', 'SearchBlockSize', IntToStr(SearchBlock_Size));
    Ini.WriteBool('Other2', 'DomBlockByFiles', DomBlock_ChkFiles);
    Ini.WriteBool('Other2', 'DomBlockBySize', DomBlock_ChkSize);
    Ini.WriteBool('Other2', 'DomBlockHard', DomBlock_Hard);
    Ini.WriteInteger('Other2', 'DomBlockFiles', DomBlock_Files);
    Ini.WriteString('Other2', 'DomBlockSize', IntToStr(DomBlock_Size));
    Ini.WriteInteger('Other2', 'DLFloodBlockCount', DLFloodBlock_Count);
    Ini.WriteInteger('Other2', 'DLFloodBlockBanTime', DLFloodBlock_Bantime);
    case DLFloodBlock_Method of
      Block: Ini.WriteString('Other2', 'DLFloodBlockMethod', 'Block');
      Leech: Ini.WriteString('Other2', 'DLFloodBlockMethod', 'Leech');
      Ban: Ini.WriteString('Other2', 'DLFloodBlockMethod', 'Ban');
    end;
    Ini.WriteInteger('Other2', 'WQFloodBlockCount', WQFloodBlock_Count);
    Ini.WriteInteger('Other2', 'WQFloodBlockBanTime', WQFloodBlock_Bantime);
    case WQFloodBlock_Method of
      Block: Ini.WriteString('Other2', 'WQFloodBlockMethod', 'Block');
      Leech: Ini.WriteString('Other2', 'WQFloodBlockMethod', 'Leech');
      Ban: Ini.WriteString('Other2', 'WQFloodBlockMethod', 'Ban');
    end;
    Ini.WriteBool('Other2', 'NoCountText', Nocount_Text);
    Ini.WriteBool('Other2', 'AutoBanINCOMPLETE', Autoban_Incomplete);
    Ini.WriteBool('Other2', 'DisableFakeExt', Disable_FakeExt);
    Ini.WriteString('Other2', 'FakeExt', Fakeext);
    Ini.WriteBool('Other2', 'EnableTrapPort', Enable_TrapPort);
    Ini.WriteBool('Other2', 'BlockTransferPort', Block_TransferPort);
    Ini.WriteString('Other2', 'BlockedTransferPort', Blocked_TransferPort);
    Ini.WriteBool('Other2', 'ShareMatchOnly', Share_MatchedFile_Only);
    Ini.WriteBool('Other2', 'EnableLoginIM', Enable_Loginim);
    Ini.WriteString('Other2', 'LoginIMBot', LoginIMBot);
    List := TMyStringList.Create;
    for I := 0 to MAX_LOGINIM do
      if LoginIm[I] <> '' then
        List.Add(Loginim[I]);
    try
      List.SaveToFile(ApplicationDir + 'loginim');
    except
    end;
    List.Free;
    Ini.WriteBool('Other2', 'ForceEnter', Force_Enter);
    Ini.WriteString('Other2', 'ForceEnterChannel', Force_Enter_Channel);
    Ini.WriteBool('Other2', 'Allow2ByteName', Allow_2ByteName);
    Ini.WriteBool('Other2', 'CheckLoginPass', Check_Loginpass);
    Ini.WriteString('Other2', 'LoginPass', Loginpass);
    Ini.WriteBool('Other2', 'EnableMsgServ', Enable_Msgserv);
    Ini.WriteBool('Other2', 'RestrictHitPerUser', Restrict_Hitperuser);
    Ini.WriteInteger('Other2', 'MaxHitPerUser', MaxHitPerUser);
    Ini.WriteBool('Other2', 'MinShareNoBlockAct', MinShare_NoBlockAct);
    Ini.WriteBool('Blocked', 'Napchan', Blocked_Clients[softNapchan]);
    Ini.WriteBool('Blocked', 'Utatane', Blocked_Clients[softUtatane]);
    Ini.WriteBool('Blocked', '2get', Blocked_Clients[soft2get]);
    Ini.WriteBool('Blocked', 'Regnessem', Blocked_Clients[softRegnessem]);
    Ini.WriteBool('Other2', 'KillIdleUser', Kill_Idleuser);
    Ini.WriteInteger('Other2', 'KillIdleUserTime', Kill_Idleuser_Time);
    Ini.WriteBool('Other2', 'ListAllForUsers', Listall_for_Users);
    Ini.WriteBool('Other2', 'BlockWeirdXNapFile', Block_Weird_XnapFile);
    Ini.WriteBool('Other2', 'SuggestDirectBrowse', Suggest_DBrowse);
    Ini.WriteString('Other2', 'LogFolder', Log_Folder);
    Ini.WriteInteger('Other2', 'MaxResolvingCount', Max_Resolving_Count);
    Ini.WriteBool('Other2', 'AllowRTFCode', Allow_Rtf_Code);
    Ini.WriteBool('Other2', 'EnableMetaServer', Enable_Metaserver);
    Ini.WriteString('Other2', 'MetaPort', MetaPort);
    Ini.WriteString('Other2', 'RedirectedServer', Redirected_Server);
    Ini.WriteString('Other2', 'RedirectedServerCheckList',
      Redirected_Server_Chk);
    Ini.WriteBool('Other2', 'DisableNullIP', Disable_Nullip);
    Ini.UpdateFile;
  finally
    Ini.Free;
  end;
end;

procedure TSlavaNapWindow.ChangeInterface(LoadMode: ConfigLoadMode = lmAll);
var
  I, J: Integer;
  function SetWidth(Btn: TSpeedButton; L: Integer): Integer;
  var
    I: Integer;
  begin
    I := Canvas.TextWidth(Btn.Caption);
    Btn.Width := I + 20;
    Btn.Left := L;
    Result := L + I + 20;
  end;
begin
  if LoadMode <> lmRest then
  begin
    SetFont(Self.Font);
    SetFont(Lbl_Log.Font, 8);
    SetFont(Lbl_Users.Font, 8);
    SetFont(Lbl_Registered.Font, 8);
    SetFont(Lbl_Servers.Font, 8);
    SetFont(Lbl_Channels.Font, 8);
    SetFont(Lbl_Bans.Font, 8);
    SetFont(Lbl_List.Font, 8);
    SetFont(Lbl_Hotlist.Font, 8);
    SetFont(Log_Main.Font);
    Log_Main.SelectAll;
    Log_Main.SelAttributes.Size := Log_Main.Font.Size;
    Log_Main.SelLength := 0;
    StatusBar1.Panels[1].Width := 0;
    // Menu
    Mnu_Server.Caption := GetLangI(LNG_MENU_SERVER);
    Mnu_Settings.Caption := GetLangI(LNG_MENU_SETTINGS);
    Mnu_Languages.Caption := GetLangI(LNG_MENU_LANGUAGES);
    Mnu_Save.Caption := GetLangI(LNG_MENU_SAVE);
    Mnu_Restart.Caption := GetLangI(LNG_MENU_RESTART);
    Mnu_Close.Caption := GetLangI(LNG_MENU_EXIT);
    Mnu_Log.Caption := GetLangI(LNG_MENU_LOG);
    Mnu_Log_Clear2.Caption := GetLangI(LNG_MENU_CLEAR);
    Mnu_Log_Login.Caption := GetLangI(LNG_MENU_LOGIN);
    Mnu_Log_Search.Caption := GetLangI(LNG_MENU_SEARCH);
    Mnu_Log_Browse.Caption := GetLangI(LNG_MENU_BROWSE);
    Mnu_Log_Transfers.Caption := GetLangI(LNG_MENU_TRANSFER);
    Mnu_Log_Napigator.Caption := GetLangI(LNG_MENU_NAPIGATOR);
    Mnu_Log_Dagsta.Caption := GetLangI(LNG_MENU_DAGSTA);
    Mnu_Log_Reset.Caption := GetLangI(LNG_MENU_RESET);
    Mnu_Window.Caption := GetLangI(LNG_MENU_WINDOW);
    Mnu_Win_Log.Caption := GetLangI(LNG_MENU_LOGWIN);
    Mnu_Win_Users.Caption := GetLangI(LNG_MENU_USERS);
    Mnu_Win_Registered.Caption := GetLangI(LNG_MENU_REGISTERED);
    Mnu_Win_Servers.Caption := GetLangI(LNG_MENU_SERVERS);
    Mnu_Win_Channels.Caption := GetLangI(LNG_MENU_CHANNELS);
    Mnu_Win_Bans.Caption := GetLangI(LNG_MENU_BANS);
    Mnu_Win_Hotlist.Caption := GetLangI(LNG_MENU_HOTLIST);
    Mnu_Win_Friends.Caption := GetLangI(LNG_MENU_FRIENDS);
    Mnu_Win_Ignored.Caption := GetLangI(LNG_MENU_IGNORE);
    Mnu_Win_Blocked.Caption := GetLangI(LNG_MENU_BLOCK);
    Mnu_Help.Caption := GetLangI(LNG_MENU_HELP);
    Mnu_Help_Manual.Caption := GetLangI(LNG_MENU_MANUAL);
    Mnu_Help_Faq.Caption := GetLangI(LNG_MENU_FAQ);
    Mnu_Help_Forums.Caption := GetLangI(LNG_MENU_FORUMS);
    Mnu_Help_Web.Caption := GetLangI(LNG_MENU_WEB);
    Mnu_Help_About.Caption := GetLangI(LNG_MENU_ABOUT);
    // Toolbar
    I := 10;
    Btn_Tb_Log.Caption := GetLangI(LNG_TB_BTN_LOG);
    Btn_Tb_Log.Hint := GetLangI(LNG_TB_BTN_LOG_HINT);
    I := SetWidth(Btn_Tb_Log, I);
    Btn_Tb_Users.Caption := GetLangI(LNG_TB_BTN_USERS);
    Btn_Tb_Users.Hint := GetLangI(LNG_TB_BTN_USERS_HINT);
    I := SetWidth(Btn_Tb_Users, I);
    Btn_Tb_Registered.Caption := GetLangI(LNG_TB_BTN_REGISTERED);
    Btn_Tb_Registered.Hint := GetLangI(LNG_TB_BTN_REGISTERED_HINT);
    I := SetWidth(Btn_Tb_Registered, I);
    Btn_Tb_Servers.Caption := GetLangI(LNG_TB_BTN_SERVERS);
    Btn_Tb_Servers.Hint := GetLangI(LNG_TB_BTN_SERVERS_HINT);
    I := SetWidth(Btn_Tb_Servers, I);
    Btn_Tb_Channels.Caption := GetLangI(LNG_TB_BTN_CHANNELS);
    Btn_Tb_Channels.Hint := GetLangI(LNG_TB_BTN_CHANNELS_HINT);
    I := SetWidth(Btn_Tb_Channels, I);
    Btn_Tb_Bans.Caption := GetLangI(LNG_TB_BTN_BANS);
    Btn_Tb_Bans.Hint := GetLangI(LNG_TB_BTN_BANS_HINT);
    I := SetWidth(Btn_Tb_Bans, I);
    Btn_Tb_Friends.Caption := GetLangI(LNG_TB_BTN_FRIENDS);
    Btn_Tb_Friends.Hint := GetLangI(LNG_TB_BTN_FRIENDS_HINT);
    I := SetWidth(Btn_Tb_Friends, I);
    Btn_Tb_Hotlist.Caption := GetLangI(LNG_TB_BTN_HOTLIST);
    Btn_Tb_Hotlist.Hint := GetLangI(LNG_TB_BTN_HOTLIST_HINT);
    I := Setwidth(Btn_Tb_Hotlist, I);
    Btn_Tb_Ignored.Caption := GetLangI(LNG_TB_BTN_IGNORE);
    Btn_Tb_Ignored.Hint := GetLangI(LNG_TB_BTN_IGNORE_HINT);
    I := SetWidth(Btn_Tb_Ignored, I);
    Btn_Tb_Blocks.Caption := GetLangI(LNG_TB_BTN_BLOCKS);
    Btn_Tb_Blocks.Hint := GetLangI(LNG_TB_BTN_BLOCKS_HINT);
    //   I := SetWidth(Btn_Tb_Blocks, I);
    SetWidth(Btn_Tb_Blocks, I);
    // Log Window
    Lbl_Log.Caption := GetLangI(LNG_LOG_LABEL);
    I := Btn_Log_Clear.Left;
    Btn_Log_Clear.Caption := GetLangI(LNG_LOG_CLEAR);
    Btn_Log_Clear.Width := Canvas.TextWidth(Btn_Log_Clear.Caption) + 20;
    Inc(I, Btn_Log_Clear.Width);
    Btn_Log_Mode.Left := I;
    Btn_Log_Mode.Caption := GetLangI(LNG_LOG_MODE);
    Btn_Log_Mode.Width := Canvas.TextWidth(Btn_Log_Mode.Caption) + 20;
    Inc(I, Btn_Log_Mode.Width);
    Btn_Log_Pause.Left := I;
    Btn_Log_Pause.Caption := GetLangI(LNG_LOG_PAUSE);
    Btn_Log_Pause.Width := Canvas.TextWidth(Btn_Log_Pause.Caption) + 20;
    I := Cb_Log_Sound.Left;
    Cb_Log_Sound.Caption := GetLangI(LNG_LOG_CB_SOUND);
    Cb_Log_Sound.Width := Canvas.TextWidth(Cb_Log_Sound.Caption) + 25;
    Inc(I, Cb_Log_Sound.Width + 10);
    Cb_Log_Away.Left := I;
    Cb_Log_Away.Caption := GetLangI(LNG_LOG_CB_AWAY);
    Cb_Log_Away.Width := Canvas.TextWidth(Cb_Log_Away.Caption) + 25;
    Inc(I, Cb_Log_Away.Width + 5);
    Lbl_Log_Away.Left := I;
    Lbl_Log_Away.Caption := GetLangI(LNG_LOG_LBL_AWAY);
    Inc(I, Lbl_Log_Away.Width + 5);
    Edit_Log_Away.Left := I;
    Inc(I, Edit_Log_Away.Width + 10);
    Cb_Log_Awaypopup.Left := I;
    Cb_Log_Awaypopup.Caption := GetLangI(LNG_LOG_CB_AWAYPOPUP);
    Cb_Log_Awaypopup.Width := Canvas.TextWidth(Cb_Log_Awaypopup.Caption) + 25;
    Last_Away_User := '';
    Last_Away_Time := GetTickCount;
    if LoadMode = lmInitial then Exit; // 起動時間の短縮のため
  end;

  // Popup menus
  Mnu_Tray_Settings.Caption := GetLangI(LNG_MENU_SETTINGS);
  Mnu_Tray_Restart.Caption := GetLangI(LNG_MENU_RESTART);
  Mnu_Tray_Exit.Caption := GetLangI(LNG_MENU_EXIT);
  Mnu_Log_Clear.Caption := GetLangI(LNG_MENU_CLEAR);
  Mnu_Log_Copy.Caption := GetLangI(LNG_MENU_COPY);
  Mnu_Users_Refresh.Caption := GetLangI(LNG_LIST_MENU_REFRESH);
  Mnu_Users_Kick.Caption := GetLangI(LNG_LIST_MENU_KILL);
  Mnu_Users_Nuke.Caption := GetLangI(LNG_LIST_MENU_NUKE);
  Mnu_Users_Muzzle.Caption := GetLangI(LNG_LIST_MENU_MUZZLE);
  Mnu_Users_Ban.Caption := GetLangI(LNG_LIST_MENU_BAN);
  Mnu_Users_Banip.Caption := GetLangI(LNG_LIST_MENU_BANIP);
  Mnu_Users_Kickban.Caption := GetLangI(LNG_LIST_MENU_KICKBAN);
  Mnu_Users_Kickbanip.Caption := GetLangI(LNG_LIST_MENU_KICKBANIP);
  Mnu_Users_Register.Caption := GetLangI(LNG_LIST_MENU_REGISTER);
  Mnu_Users_Level.Caption := GetLangI(LNG_LIST_MENU_LEVEL);
  Mnu_Users_Speed.Caption := GetLangI(LNG_LIST_MENU_SPEED);
  Mnu_Users_Speed0.Caption := Speed2Str(napSpeedUnknown);
  Mnu_Users_Speed1.Caption := Speed2Str(napSpeed14);
  Mnu_Users_Speed2.Caption := Speed2Str(napSpeed28);
  Mnu_Users_Speed3.Caption := Speed2Str(napSpeed33);
  Mnu_Users_Speed4.Caption := Speed2Str(napSpeed56);
  Mnu_Users_Speed5.Caption := Speed2Str(napSpeed64ISDN);
  Mnu_Users_Speed6.Caption := Speed2Str(napSpeed128ISDN);
  Mnu_Users_Speed7.Caption := Speed2Str(napSpeedCable);
  Mnu_Users_Speed8.Caption := Speed2Str(napSpeedDSL);
  Mnu_Users_Speed9.Caption := Speed2Str(napSpeedT1);
  Mnu_Users_Speed10.Caption := Speed2Str(napSpeedT3);
  Mnu_Users_Im.Caption := GetLangI(LNG_LIST_MENU_IM);
  Mnu_Users_Whois.Caption := GetLangI(LNG_LIST_MENU_WHOIS);
  Mnu_Users_Browse.Caption := RS_MainForm_LNG_LIST_MENU_BROWSE;
  Mnu_Users_Selall.Caption := GetLangI(LNG_LIST_MENU_SELALL);
  Mnu_Users_Selnone.Caption := GetLangI(LNG_LIST_MENU_SELNONE);
  Mnu_Users_CopyName.Caption := GetLangI(LNG_LIST_MENU_COPYNAME);
  Mnu_Users_Friend.Caption := GetLangI(LNG_LIST_MENU_FRIEND);
  Mnu_Users_Hotlist.Caption := GetLangI(LNG_LIST_MENU_HOTLIST);
  Mnu_Users_Ignore.Caption := GetLangI(LNG_LIST_MENU_IGNORE);
  Mnu_Reg_Refresh.Caption := GetLangI(LNG_REG_MENU_REFRESH);
  Mnu_Reg_Unregister.Caption := GetLangI(LNG_REG_MENU_UNREGISTER);
  Mnu_Reg_Nuke.Caption := GetLangI(LNG_REG_MENU_NUKE);
  Mnu_Reg_Ban.Caption := GetLangI(LNG_REG_MENU_BAN);
  Mnu_Reg_Banip.Caption := GetLangI(LNG_REG_MENU_BANIP);
  Mnu_Reg_Level.Caption := GetLangI(LNG_REG_MENU_LEVEL);
  Mnu_Reg_Selall.Caption := GetLangI(LNG_REG_MENU_SELALL);
  Mnu_Reg_Selnone.Caption := GetLangI(LNG_REG_MENU_SELNONE);
  Mnu_Reg_CopyName.Caption := GetLangI(LNG_REG_MENU_COPYNAME);
  Mnu_Ch_Refresh.Caption := GetLangI(LNG_CMENU_REFRESH);
  Mnu_Ch_Join.Caption := GetLangI(LNG_CMENU_JOIN);
  Mnu_Ch_Delete.Caption := GetLangI(LNG_CMENU_DELETE);
  Mnu_Ch_Clear.Caption := GetLangI(LNG_CMENU_CLEAR);
  Mnu_Ch_Add.Caption := GetLangI(LNG_CMENU_ADD);
  Mnu_Ch_Props.Caption := GetLangI(LNG_CMENU_PROPS);
  Mnu_Ch_Topic.Caption := GetLangI(LNG_CMENU_TOPIC);
  Mnu_Ch_Selall.Caption := GetLangI(LNG_CMENU_SELECTALL);
  Mnu_Ch_Selnone.Caption := GetLangI(LNG_CMENU_SELECTNONE);
  Mnu_Ch_CopyName.Caption := GetLangI(LNG_CMENU_COPYNAME);
  Mnu_Ch_Clearbans.Caption := GetLangI(LNG_CMENU_CLEARBANS);
  Mnu_Srv_Refresh.Caption := GetLangI(LNG_SMENU_REFRESH);
  Mnu_Srv_Connect.Caption := GetLangI(LNG_SMENU_CONNECT2);
  Mnu_Srv_Disconnect.Caption := GetLangI(LNG_SMENU_DISCONNECT);
  Mnu_Srv_Delete.Caption := GetLangI(LNG_SMENU_DELETE);
  Mnu_Srv_Comp.Caption := GetLangI(LNG_SMENU_COMP);
  Mnu_Srv_Comp0.Caption := GetLangI(LNG_SMENU_COMP0);
  Mnu_Srv_Comp1.Caption := GetLangI(LNG_SMENU_COMP1);
  Mnu_Srv_Comp2.Caption := GetLangI(LNG_SMENU_COMP2);
  Mnu_Srv_Comp3.Caption := GetLangI(LNG_SMENU_COMP3);
  Mnu_Srv_Startup.Caption := GetLangI(LNG_SMENU_STARTUP);
  Mnu_Srv_Startup0.Caption := GetLangI(LNG_SMENU_STARTUP2);
  Mnu_Srv_Startup5.Caption := GetLangI(LNG_SMENU_LINK300);
  Mnu_Srv_Startup10.Caption := GetLangI(LNG_SMENU_LINK600);
  Mnu_Srv_Startup15.Caption := GetLangI(LNG_SMENU_LINK900);
  Mnu_Srv_Startup20.Caption := GetLangI(LNG_SMENU_LINK1200);
  Mnu_Srv_Startup30.Caption := GetLangI(LNG_SMENU_LINK1800);
  Mnu_Srv_Props.Caption := GetLangI(LNG_SMENU_PROPS);
  Mnu_Srv_Selall.Caption := GetLangI(LNG_SMENU_SELECTALL);
  Mnu_Srv_Selnone.Caption := GetLangI(LNG_SMENU_SELECTNONE);
  Mnu_Srv_CopyName.Caption := GetLangI(LNG_SMENU_COPYNAME);
  Mnu_Ban_Refresh.Caption := GetLangI(LNG_BMENU_REFRESH);
  Mnu_Ban_Unban.Caption := GetLangI(LNG_BMENU_UNBAN);
  Mnu_Ban_Copyuser.Caption := GetLangI(LNG_BMENU_COPYUSER);
  Mnu_Ban_Copyip.Caption := GetLangI(LNG_BMENU_COPYIP);
  Mnu_Ban_Copyban.Caption := GetLangI(LNG_BMENU_COPYBAN);
  Mnu_Ban_Copyadmin.Caption := GetLangI(LNG_BMENU_COPYADMIN);
  Mnu_Ban_Copyreason.Caption := GetLangI(LNG_BMENU_COPYREASON);
  Mnu_Ban_Selall.Caption := GetLangI(LNG_BMENU_SELALL);
  Mnu_Ban_Selnone.Caption := GetLangI(LNG_BMENU_SELNONE);
  Mnu_Hotlist_Refresh.Caption := GetLangI(LNG_HMENU_REFRESH);
  Mnu_Hotlist_Im.Caption := GetLangI(LNG_HMENU_IM);
  Mnu_Hotlist_Whois.Caption := GetLangI(LNG_HMENU_WHOIS);
  Mnu_Hotlist_Friend.Caption := GetLangI(LNG_HMENU_FRIEND);
  Mnu_Hotlist_Delete.Caption := GetLangI(LNG_HMENU_DELETE);
  Mnu_Hotlist_Selall.Caption := GetLangI(LNG_HMENU_SELALL);
  Mnu_Hotlist_Selnone.Caption := GetLangI(LNG_HMENU_SELNONE);
  Mnu_Hotlist_CopyName.Caption := GetLangI(LNG_HMENU_COPYNAME);
  Mnu_Ignored_Refresh.Caption := GetLangI(LNG_IMENU_REFRESH);
  Mnu_Ignored_Delete.Caption := GetLangI(LNG_IMENU_DELETE);
  Mnu_Ignored_Selall.Caption := GetLangI(LNG_IMENU_SELALL);
  Mnu_Ignored_Selnone.Caption := GetLangI(LNG_IMENU_SELNONE);
  Mnu_Ignored_CopyName.Caption := GetLangI(LNG_IMENU_COPYNAME);
  Mnu_Fr_Refresh.Caption := GetLangI(LNG_FMENU_REFRESH);
  Mnu_Fr_Delete.Caption := GetLangI(LNG_FMENU_DELETE);
  Mnu_Fr_Selall.Caption := GetLangI(LNG_FMENU_SELALL);
  Mnu_Fr_Selnone.Caption := GetLangI(LNG_FMENU_SELNONE);
  Mnu_Fr_CopyName.Caption := GetLangI(LNG_FMENU_COPYNAME);
  Mnu_Bl_Refresh.Caption := GetLangI(LNG_BMNU_REFRESH);
  Mnu_Bl_Delete.Caption := GetLangI(LNG_BMNU_DELETE);
  Mnu_Bl_Selall.Caption := GetLangI(LNG_BMNU_SELALL);
  Mnu_Bl_Selnone.Caption := GetLangI(LNG_BMNU_SELNONE);
  Mnu_Bl_CopyName.Caption := GetLangI(LNG_BMNU_COPYNAME);
  Mnu_Um_Level.Caption := GetLangI(LNG_LIST_MNU2_LEVEL);
  Mnu_Um_Shared.Caption := GetLangI(LNG_LIST_MNU2_SHARED);
  Mnu_Um_Soft.Caption := GetLangI(LNG_LIST_MNU2_SOFT);
  Mnu_Um_Size.Caption := RS_MainForm_LNG_LIST_MNU2_SIZE;
  Mnu_Um_Average.Caption := RS_MainForm_LNG_LIST_MNU2_AVG;
  Mnu_Um_Speed.Caption := GetLangI(LNG_LIST_MNU2_SPEED);
  Mnu_Um_Ip.Caption := GetLangI(LNG_LIST_MNU2_IP);
  Mnu_Um_RemoteHost.Caption := RS_MainForm_LNG_LIST_MNU2_REMOTEHOST;
  Mnu_Um_Port.Caption := GetLangI(LNG_LIST_MNU2_PORT);
  Mnu_Um_Time.Caption := GetLangI(LNG_LIST_MNU2_TIME);
  Mnu_Um_Up.Caption := RS_MainForm_LNG_LIST_MNU2_UP;
  Mnu_Um_Down.Caption := RS_MainForm_LNG_LIST_MNU2_DOWN;
  Mnu_Um_Transfers.Caption := GetLangI(LNG_LIST_MNU2_TRANSFERS);
  Mnu_Um_Totalup.Caption := RS_MainForm_LNG_LIST_MNU2_TOTALUP;
  Mnu_Um_Totaldown.Caption := RS_MainForm_LNG_LIST_MNU2_TOTALDOWN;
  Mnu_Um_Total.Caption := GetLangI(LNG_LIST_MNU2_TOTAL);
  Mnu_Um_Server.Caption := GetLangI(LNG_LIST_MNU2_SERVER);
  Mnu_Um_Ulrequests.Caption := RS_MainForm_LNG_LIST_MNU2_ULREQ;
  Mnu_Um_Dlrequests.Caption := RS_MainForm_LNG_LIST_MNU2_DLREQ;
  Mnu_Um_Searchreqs.Caption := RS_MainForm_LNG_LIST_MNU2_SEARCHREQ;
  Mnu_Um_BlockFiles.Caption := RS_MainForm_LNG_LIST_MNU2_BLOCKS;

  // Users tree
  with List_Users.Columns do
  begin
    Items[0].Caption := GetLangI(LNG_LIST_HEADER_NAME);
    Items[UL_LEVEL + 1].Caption := GetLangI(LNG_LIST_HEADER_LEVEL);
    Items[UL_SHARED + 1].Caption := GetLangI(LNG_LIST_HEADER_SHARED);
    Items[UL_SIZE + 1].Caption := RS_MainForm_LNG_LIST_HEADER_SIZE;
    Items[UL_AVERAGE + 1].Caption := RS_MainForm_LNG_LIST_HEADER_AVG;
    Items[UL_SOFT + 1].Caption := GetLangI(LNG_LIST_HEADER_SOFTWARE);
    Items[UL_SPEED + 1].Caption := GetLangI(LNG_LIST_HEADER_SPEED);
    Items[UL_IP + 1].Caption := GetLangI(LNG_LIST_HEADER_IP);
    Items[UL_REMOTEHOST + 1].Caption := RS_MainForm_LNG_LIST_HEADER_REMOTEHOST;
    Items[UL_PORT + 1].Caption := GetLangI(LNG_LIST_HEADER_PORT);
    Items[UL_TIME + 1].Caption := GetLangI(LNG_LIST_HEADER_TIME);
    Items[UL_UP + 1].Caption := RS_MainForm_LNG_LIST_HEADER_UP;
    Items[UL_DOWN + 1].Caption := RS_MainForm_LNG_LIST_HEADER_DOWN;
    Items[UL_TRANSFERS + 1].Caption := GetLangI(LNG_LIST_HEADER_TRANSFERS);
    Items[UL_TUP + 1].Caption := RS_MainForm_LNG_LIST_HEADER_TOTALUP;
    Items[UL_TDOWN + 1].Caption := RS_MainForm_LNG_LIST_HEADER_TOTALDOWN;
    Items[UL_TTRANSFERS + 1].Caption := GetLangI(LNG_LIST_HEADER_TOTAL);
    Items[UL_SERVER + 1].Caption := GetLangI(LNG_LIST_HEADER_SERVER);
    Items[UL_ULREQUESTS + 1].Caption := RS_MainForm_LNG_LIST_HEADER_ULREQ;
    Items[UL_DLREQUESTS + 1].Caption := RS_MainForm_LNG_LIST_HEADER_DLREQ;
    Items[UL_SEARCHREQS + 1].Caption := RS_MainForm_LNG_LIST_HEADER_SEARCHREQ;
    Items[UL_BLOCKFILES + 1].Caption := RS_MainForm_LNG_LIST_HEADER_BLOCKS;
    Items[UL_STATUS + 1].Caption := '';
  end;
  Lbl_Users.Caption := GetLangI(LNG_USERS_LABEL);
  I := Btn_Users_Mode.Left;
  Btn_Users_Mode.Caption := GetLangI(LNG_LIST_BTN_MODE);
  Btn_Users_Mode.Width := Canvas.TextWidth(Btn_Users_Mode.Caption) + 20;
  Inc(I, Btn_Users_Mode.Width);
  Btn_Users_Refresh.Left := I;
  Btn_Users_Refresh.Caption := GetLangI(LNG_LIST_BTN_REFRESH);
  Btn_Users_Refresh.Width := Canvas.TextWidth(Btn_Users_Refresh.Caption) + 20;
  Inc(I, Btn_Users_Refresh.Width + 30);
  Edit_Users_Reason.Left := I;
  Edit_Users_Reason.Width := 100;
  Edit_Users_Reason.Hint := GetLangI(LNG_LIST_REASONHINT);
  Inc(I, Edit_Users_Reason.Width);
  Edit_Users_Time.Left := I;
  Edit_Users_Time.Width := 75;
  SetBanItems(Edit_Users_Time);
  Edit_Users_Time.Hint := GetLangI(LNG_LIST_HINT_BAN);
  Inc(I, Edit_Users_Time.Width + 30);
  Cb_Users_Refresh.Caption := GetLangI(LNG_LIST_BTN_AUTOREFRESH);
  Cb_Users_Refresh.Left := I;
  Cb_Users_Refresh.Width := Canvas.TextWidth(Cb_Users_Refresh.Caption) + 30;
  Inc(I, Cb_Users_Refresh.Width);
  Edit_Users_Refresh.Left := I;
  Edit_Users_Refresh.Width := 45;
  Inc(I, Edit_Users_Refresh.Width + 5);
  Lbl_Users_Refresh.Caption := GetLangI(LNG_LIST_LBL_AUTOREFRESH);
  Lbl_Users_Refresh.Left := I;
  Lbl_Users_Refresh.Width := Canvas.TextWidth(Lbl_Users_Refresh.Caption) + 30;
  // Inc(I, Lbl_Users_Refresh.Width);

  I := Btn_Users_Muzzle.Left;
  J := Btn_Users_Refresh.Top + 21;
  Btn_Users_Muzzle.Caption := GetLangI(LNG_LIST_BTN_MUZZLE);
  Btn_Users_Muzzle.Width := Canvas.TextWidth(Btn_Users_Muzzle.Caption) + 20;
  Btn_Users_Muzzle.Left := I;
  Btn_Users_Muzzle.Top := J;
  Inc(I, Btn_Users_Muzzle.Width);
  Btn_Users_Kick.Caption := GetLangI(LNG_LIST_BTN_KICK);
  Btn_Users_Kick.Width := Canvas.Textwidth(Btn_Users_Kick.Caption) + 20;
  Btn_Users_Kick.Left := I;
  Btn_Users_Kick.Top := J;
  Inc(I, Btn_Users_Kick.Width);
  Btn_Users_Nuke.Caption := GetLangI(LNG_LIST_BTN_NUKE);
  Btn_Users_Nuke.Width := Canvas.TextWidth(Btn_Users_Nuke.Caption) + 20;
  Btn_Users_Nuke.Left := I;
  Btn_Users_Nuke.Top := J;
  Inc(I, Btn_Users_Nuke.Width);
  Btn_Users_Ban.Caption := GetLangI(LNG_LIST_BTN_BAN);
  Btn_Users_Ban.Width := Canvas.TextWidth(Btn_Users_Ban.Caption) + 20;
  Btn_Users_Ban.Left := I;
  Btn_Users_Ban.Top := J;
  Inc(I, Btn_Users_Ban.Width);
  Btn_Users_Banip.Caption := GetLangI(LNG_LIST_BTN_BANIP);
  Btn_Users_Banip.Width := Canvas.TextWidth(Btn_Users_Banip.Caption) + 20;
  Btn_Users_Banip.Left := I;
  Btn_Users_Banip.Top := J;
  Inc(I, Btn_Users_Banip.Width);
  Btn_Users_Kickban.Caption := GetLangI(LNG_LIST_BTN_KICKBAN);
  Btn_Users_Kickban.Width := Canvas.TextWidth(Btn_Users_Kickban.Caption) + 20;
  Btn_Users_Kickban.Left := I;
  Btn_Users_Kickban.Top := J;
  Inc(I, Btn_Users_Kickban.Width);
  Btn_Users_Kickbanip.Caption := GetLangI(LNG_LIST_BTN_KICKBANIP);
  Btn_Users_Kickbanip.Width := Canvas.TextWidth(Btn_Users_Kickbanip.Caption) +
    20;
  Btn_Users_Kickbanip.Left := I;
  Btn_Users_Kickbanip.Top := J;
  Inc(I, Btn_Users_Kickbanip.Width);
  Btn_Users_Register.Caption := GetLangI(LNG_LIST_BTN_REGISTER);
  Btn_Users_Register.Width := Canvas.TextWidth(Btn_Users_Register.Caption) + 20;
  Btn_Users_Register.Left := I;
  Btn_Users_Register.Top := J;

  Edit_Users_Filter.Hint := GetLangI(LNG_LIST_EDIT_FILTER_HINT);
  I := Edit_Users_Filter.Left;
  Edit_Users_Filter.Width := 50;
  Inc(I, Edit_Users_Filter.Width + 5);
  Cb_Users_Mods.Caption := GetLangI(LNG_LIST_BTN_MODS);
  Cb_Users_Mods.Left := I;
  Cb_Users_Mods.Width := Canvas.TextWidth(Cb_Users_Mods.Caption) + 30;
  Inc(I, Cb_Users_Mods.Width);
  Cb_Users_Users.Caption := GetLangI(LNG_LIST_BTN_USERS);
  Cb_Users_Users.Left := I;
  Cb_Users_Users.Width := Canvas.TextWidth(Cb_Users_Users.Caption) + 30;
  Inc(I, Cb_Users_Users.Width);
  Cb_Users_Leeches.Caption := GetLangI(LNG_LIST_BTN_LEECH);
  Cb_Users_Leeches.Left := I;
  Cb_Users_Leeches.Width := Canvas.TextWidth(Cb_Users_Leeches.Caption) + 30;
  Inc(I, Cb_Users_Leeches.Width);
  Cb_Users_Muzzled.Caption := GetLangI(LNG_LIST_BTN_MUZZLED);
  Cb_Users_Muzzled.Left := I;
  Cb_Users_Muzzled.Width := Canvas.TextWidth(Cb_Users_Muzzled.Caption) + 30;
  Inc(I, Cb_Users_Muzzled.Width);
  Cb_Users_Local.Caption := GetLangI(LNG_LIST_BTN_LOCAL);
  Cb_Users_Local.Left := I;
  Cb_Users_Local.Width := Canvas.TextWidth(Cb_Users_Local.Caption) + 30;
  Inc(I, Cb_Users_Local.Width);
  Cb_Users_Remote.Caption := GetLangI(LNG_LIST_BTN_REMOTE);
  Cb_Users_Remote.Left := I;
  Cb_Users_Remote.Width := Canvas.TextWidth(Cb_Users_Remote.Caption) + 30;
  // Inc(I, Cb_Users_Remote.Width);

   // Registered tree
  with List_Registered.Columns do
  begin
    Items[0].Caption := GetLangI(LNG_REG_USER);
    Items[1].Caption := GetLangI(LNG_REG_LEVEL);
    Items[2].Caption := GetLangI(LNG_REG_TRANSFERS2);
    Items[3].Caption := GetLangI(LNG_REG_IP);
    Items[4].Caption := GetLangI(LNG_REG_TIME);
  end;
  Lbl_Registered.Caption := GetLangI(LNG_REG_LABEL);
  I := Btn_Reg_Refresh.Left;
  Btn_Reg_Refresh.Caption := GetLangI(LNG_REG_BTN_REFRESH);
  Btn_Reg_Refresh.Width := Canvas.TextWidth(Btn_Reg_Refresh.Caption) + 20;
  Inc(I, Btn_Reg_Refresh.Width);
  Edit_Reg_Filter.Left := I;
  Edit_Reg_Filter.Width := 50;
  Edit_Reg_Filter.Hint := GetLangI(LNG_REG_EDIT_FILTER_HINT);
  Inc(I, Edit_Reg_Filter.Width + 5);
  Cb_Reg_Mods.Caption := GetLangI(LNG_REG_BTN_MODS);
  Cb_Reg_Mods.Left := I;
  Cb_Reg_Mods.Width := Canvas.TextWidth(Cb_Reg_Mods.Caption) + 30;
  Inc(I, Cb_Reg_Mods.Width);
  Cb_Reg_Users.Caption := GetLangI(LNG_REG_BTN_USERS);
  Cb_Reg_Users.Left := I;
  Cb_Reg_Users.Width := Canvas.TextWidth(Cb_Reg_Users.Caption) + 30;
  Inc(I, Cb_Reg_Users.Width);
  Cb_Reg_Leeches.Caption := GetLangI(LNG_REG_BTN_LEECH);
  Cb_Reg_Leeches.Left := I;
  Cb_Reg_Leeches.Width := Canvas.TextWidth(Cb_Reg_Leeches.Caption) + 30;
  Inc(I, Cb_Reg_Leeches.Width);
  Cb_Reg_Muzzled.Caption := GetLangI(LNG_REG_BTN_MUZZLED);
  Cb_Reg_Muzzled.Left := I;
  Cb_Reg_Muzzled.Width := Canvas.TextWidth(Cb_Reg_Muzzled.Caption) + 30;
  J := Btn_Reg_Refresh.Top + 21;
  I := Edit_Reg_Reason.Left;
  Edit_Reg_Reason.Width := 100;
  Edit_Reg_Reason.Top := J;
  Edit_Reg_Reason.Hint := GetLangI(LNG_REG_REASONHINT);
  Inc(I, Edit_Reg_Reason.Width);
  Btn_Reg_Nuke.Caption := GetLangI(LNG_REG_BTN_NUKE);
  Btn_Reg_Nuke.Left := I;
  Btn_Reg_Nuke.Top := J;
  Btn_Reg_Nuke.Width := Canvas.TextWidth(Btn_Reg_Nuke.Caption) + 20;
  Inc(I, Btn_Reg_Nuke.Width);
  Edit_Reg_Time.Left := I;
  SetBanItems(Edit_Reg_Time);
  Edit_Reg_Time.Color := clBtnFace;
  Edit_Reg_Time.Top := J;
  Edit_Reg_Time.Hint := GetLangI(LNG_REG_HINT_BAN);
  Edit_Reg_Time.Width := 75;
  Inc(I, Edit_Reg_Time.Width);
  Btn_Reg_Ban.Caption := GetLangI(LNG_REG_BTN_BAN);
  Btn_Reg_Ban.Width := Canvas.TextWidth(Btn_Reg_Ban.Caption) + 20;
  Btn_Reg_Ban.Left := I;
  Btn_Reg_Ban.Top := J;
  Inc(I, Btn_Reg_Ban.Width);
  Btn_Reg_Banip.Caption := GetLangI(LNG_REG_BTN_BANIP);
  Btn_Reg_Banip.Left := I;
  Btn_Reg_Banip.Top := J;
  Btn_Reg_Banip.Width := Canvas.TextWidth(Btn_Reg_Banip.Caption) + 20;
  Inc(I, Btn_Reg_Banip.Width);
  Btn_Reg_Unregister.Caption := GetLangI(LNG_REG_BTN_UNREGISTER);
  Btn_Reg_Unregister.Left := I;
  Btn_Reg_Unregister.Top := J;
  Btn_Reg_Unregister.Width := Canvas.TextWidth(Btn_Reg_Unregister.Caption) + 20;
  // Inc(I, Btn_Reg_Unregister.Width);
  Edit_Reg_User.Text := '';
  Edit_Reg_User.Hint := GetLangI(LNG_REG_HINT_USER);
  Edit_Reg_Password.Text := '';
  Edit_Reg_Password.Hint := GetLangI(LNG_REG_HINT_PASSWORD);
  Edit_Reg_Level.Items.Clear;
  for I := 0 to 4 do
    Edit_Reg_Level.Items.Add(Levels[I]);
  Edit_Reg_Level.ItemIndex := 1;
  Edit_Reg_Level.Hint := GetLangI(LNG_REG_HINT_LEVEL);
  Edit_Reg_Level.Color := clBtnFace;
  Edit_Reg_Level.DropDownCount := 5;
  Btn_Reg_Add.Caption := GetLangI(LNG_REG_BTN_REGISTER);
  Btn_Reg_Add.Width := Canvas.TextWidth(Btn_Reg_Add.Caption) + 20;
  // Channels tree
  with List_Channels.Columns do
  begin
    Items[0].Caption := GetLangI(LNG_CLIST_NAME);
    Items[1].Caption := GetLangI(LNG_CLIST_USERS);
    Items[2].Caption := GetLangI(LNG_CLIST_MAXUSERS);
    Items[3].Caption := GetLangI(LNG_CLIST_LEVEL);
    Items[4].Caption := GetLangI(LNG_CLIST_STATUS);
    Items[5].Caption := GetLangI(LNG_CLIST_TOPIC);
    Items[6].Caption := GetLangI(LNG_CLIST_BANS);
    Items[7].Caption := GetLangI(LNG_CLIST_OPS);
    Items[8].Caption := GetLangI(LNG_CLIST_VOICES);
  end;
  Lbl_Channels.Caption := GetLangI(LNG_CH_LABEL);
  I := Btn_Ch_Refresh.Left;
  Btn_Ch_Refresh.Caption := GetLangI(LNG_CBTN_REFRESH);
  Btn_Ch_Refresh.Width := Canvas.TextWidth(Btn_Ch_Refresh.Caption) + 20;
  Inc(I, Btn_Ch_Refresh.Width);
  Btn_Ch_Join.Left := I;
  Btn_Ch_Join.Caption := GetLangI(LNG_CBTN_JOIN);
  Btn_Ch_Join.Width := Canvas.TextWidth(Btn_Ch_Join.Caption) + 20;
  Inc(I, Btn_Ch_Join.Width);
  Btn_Ch_Props.Left := I;
  Btn_Ch_Props.Caption := GetLangI(LNG_CBTN_PROPS);
  Btn_Ch_Props.Width := Canvas.TextWidth(Btn_Ch_Props.Caption) + 20;
  Inc(I, Btn_Ch_Props.Width);
  Btn_Ch_Add.Left := I;
  Btn_Ch_Add.Caption := GetLangI(LNG_CBTN_ADD);
  Btn_Ch_Add.Width := Canvas.TextWidth(Btn_Ch_Add.Caption) + 20;
  Inc(I, Btn_Ch_Add.Width);
  Btn_Ch_Delete.Left := I;
  Btn_Ch_Delete.Caption := GetLangI(LNG_CBTN_DELETE);
  Btn_Ch_Delete.Width := Canvas.TextWidth(Btn_Ch_Delete.Caption) + 20;
  Inc(I, Btn_Ch_Delete.Width);
  Edit_Ch_Reason.Left := I;
  Edit_Ch_Reason.Width := 100;
  Edit_Ch_Reason.Hint := GetLangI(LNG_CH_REASONHINT);
  // Bans tree
  with List_Bans.Columns do
  begin
    Items[0].Caption := GetLangI(LNG_BLIST_NAME);
    Items[1].Caption := GetLangI(LNG_BLIST_IP);
    Items[2].Caption := GetLangI(LNG_BLIST_ADMIN);
    Items[3].Caption := GetLangI(LNG_BLIST_TIMESET);
    Items[4].Caption := GetLangI(LNG_BLIST_EXPIRES);
    Items[5].Caption := GetLangI(LNG_BLIST_LASTATTEMPT);
    Items[6].Caption := GetLangI(LNG_BLIST_USING);
    Items[7].Caption := GetLangI(LNG_BLIST_TRIES);
    Items[8].Caption := GetLangI(LNG_BLIST_REASON);
  end;
  Lbl_Bans.Caption := GetLangI(LNG_BANS_LABEL);
  I := Btn_Bans_Refresh.Left;
  Btn_Bans_Refresh.Caption := GetLangI(LNG_BBTN_REFRESH);
  Btn_Bans_Refresh.Width := Canvas.TextWidth(Btn_Bans_Refresh.Caption) + 20;
  Inc(I, Btn_Bans_Refresh.Width);
  Edit_Bans_User.Left := I;
  Edit_Bans_User.Width := 100;
  Edit_Bans_User.Hint := GetLangI(LNG_BANS_BANHINT);
  Inc(I, Edit_Bans_User.Width);
  Btn_Bans_Add.Caption := GetLangI(LNG_BBTN_BAN);
  Btn_Bans_Add.Width := Canvas.TextWidth(Btn_Bans_Add.Caption) + 20;
  Btn_Bans_Add.Left := I;
  Inc(I, Btn_Bans_Add.Width);
  Edit_Ban_Time.Left := I;
  SetBanItems(Edit_Ban_Time);
  Edit_Ban_Time.Color := clBtnFace;
  Inc(I, Edit_Ban_Time.Width);
  Edit_Ban_Reason.Left := I;
  Edit_Ban_Reason.Width := 121;
  Edit_Ban_Reason.Hint := GetLangI(LNG_BANS_REASONHINT);
  Inc(I, Edit_Ban_Reason.Width);
  Btn_Ban_Delete.Caption := GetLangI(LNG_BBTN_UNBAN);
  Btn_Ban_Delete.Width := Canvas.TextWidth(Btn_Ban_Delete.Caption) + 20;
  Btn_Ban_Delete.Left := I;
  Inc(I, Btn_Ban_Delete.Width);
  Edit_Unban_Reason.Left := I;
  Edit_Unban_Reason.Width := 121;
  Edit_Unban_Reason.Hint := GetLangI(LNG_BANS_UNBANREASONHINT);

  // Servers
  with List_Servers.Columns do
  begin
    Items[0].Caption := GetLangI(LNG_SLIST_HOST);
    Items[1].Caption := GetLangI(LNG_SLIST_PORT);
    Items[2].Caption := GetLangI(LNG_SLIST_STATUS);
    Items[3].Caption := GetLangI(LNG_SLIST_LAG);
    Items[4].Caption := GetLangI(LNG_SLIST_USERS);
    Items[5].Caption := GetLangI(LNG_SLIST_AUTH);
    Items[6].Caption := GetLangI(LNG_SLIST_RELINK);
    Items[7].Caption := GetLangI(LNG_SLIST_COMMENTS);
    Items[8].Caption := GetLangI(LNG_SLIST_ALIAS);
    Items[9].Caption := GetLangI(LNG_SLIST_REDIRECTS);
  end;
  Lbl_Servers.Caption := GetLangI(LNG_SERVERS_LABEL);
  I := Btn_Servers_Refresh.Left;
  Btn_Servers_Refresh.Caption := GetLangI(LNG_SBTN_REFRESH);
  Btn_Servers_Refresh.Width := Canvas.TextWidth(Btn_Servers_Refresh.Caption) +
    20;
  Inc(I, Btn_Servers_Refresh.Width);
  Btn_Servers_Connect.Left := I;
  Btn_Servers_Connect.Caption := GetLangI(LNG_SBTN_CONNECT2);
  Btn_Servers_Connect.Width := Canvas.TextWidth(Btn_Servers_Connect.Caption) +
    20;
  Inc(I, Btn_Servers_Connect.Width);
  Btn_Servers_Disconnect.Left := I;
  Btn_Servers_Disconnect.Caption := GetLangI(LNG_SBTN_DISCONNECT);
  Btn_Servers_Disconnect.Width :=
    Canvas.TextWidth(Btn_Servers_Disconnect.Caption) + 20;
  Inc(I, Btn_Servers_Disconnect.Width);
  Btn_Servers_Delete.Left := I;
  Btn_Servers_Delete.Caption := GetLangI(LNG_SBTN_DELETE);
  Btn_Servers_Delete.Width := Canvas.TextWidth(Btn_Servers_Delete.Caption) + 20;
  Inc(I, Btn_Servers_Delete.Width);
  Edit_Servers_Host.Left := I;
  Edit_Servers_Host.Hint := GetLangI(LNG_SHOST_HINT);
  Inc(I, Edit_Servers_Host.Width);
  Btn_Servers_Add.Left := I;
  Btn_Servers_Add.Caption := GetLangI(LNG_SBTN_ADD);
  Btn_Servers_Add.Width := Canvas.TextWidth(Btn_Servers_Add.Caption) + 20;
  Inc(I, Btn_Servers_Add.Width);
  Btn_Servers_Props.Left := I;
  Btn_Servers_Props.Caption := GetLangI(LNG_SBTN_PROPS);
  Btn_Servers_Props.Width := Canvas.TextWidth(Btn_Servers_Props.Caption) + 20;
  Inc(I, Btn_Servers_Props.Width);
  Cb_Servers_Refresh.Left := I;
  Cb_Servers_Refresh.Caption := GetLangI(LNG_SBTN_AUTOREFRESH);
  Cb_Servers_Refresh.Width := Canvas.TextWidth(Cb_Servers_Refresh.Caption) + 30;
  Inc(I, Cb_Servers_Refresh.Width);
  Edit_Servers_Refresh.Left := I;
  Edit_Servers_Refresh.Width := 45;
  Inc(I, Edit_Servers_Refresh.Width + 5);
  Lbl_Servers_Refresh.Left := I;
  Lbl_Servers_Refresh.Caption := GetLangI(LNG_SLBL_AUTOREFRESH);
  Lbl_Servers_Refresh.Width := Canvas.TextWidth(Lbl_Servers_Refresh.Caption) +
    30;
  // Hotlist
  with List_Hotlist.Columns do
  begin
    Items[0].Caption := GetLangI(LNG_HLIST_NAME);
    Items[1].Caption := GetLangI(LNG_HLIST_SERVER);
    Items[2].Caption := GetLangI(LNG_HLIST_SPEED);
  end;
  Lbl_Hotlist.Caption := GetLangI(LNG_LABEL_HOTLIST);
  I := Btn_Hotlist_Refresh.Left;
  Btn_Hotlist_Refresh.Caption := GetLangI(LNG_HBTN_REFRESH);
  Btn_Hotlist_Refresh.Width := Canvas.TextWidth(Btn_Hotlist_Refresh.Caption) +
    20;
  Inc(I, Btn_Hotlist_Refresh.Width);
  Btn_Hotlist_Delete.Left := I;
  Btn_Hotlist_Delete.Caption := GetLangI(LNG_HBTN_DELETE);
  Btn_Hotlist_Delete.Width := Canvas.TextWidth(Btn_Hotlist_Delete.Caption) + 20;
  Inc(I, Btn_Hotlist_Delete.Width);
  Edit_Hotlist_User.Left := I;
  Edit_Hotlist_User.Hint := GetLangI(LNG_HEDIT_HINT);
  Edit_Hotlist_User.Text := '';
  Inc(I, Edit_Hotlist_User.Width);
  Btn_Hotlist_Add.Left := I;
  Btn_Hotlist_Add.Caption := GetLangI(LNG_HBTN_ADD);
  Btn_Hotlist_Add.Width := Canvas.TextWidth(Btn_Hotlist_Add.Caption) + 20;
  Inc(I, Btn_Hotlist_Add.Width + 10);
  Cb_Hotlist_Sound.Left := I;
  Cb_Hotlist_Sound.Caption := GetLangI(LNG_HLIST_CB_SOUND);
  Cb_Hotlist_Sound.Width := Canvas.TextWidth(Cb_Hotlist_Sound.Caption) + 25;
end;

procedure TSlavaNapWindow.FormShow(Sender: TObject);
begin
  SetColors(False);
end;

procedure TSlavaNapWindow.SetColors(All_Windows: Boolean = True);
var
  I: Integer;
begin
  Log_Console.Color := slBackground;
  Log_Console.Font.Color := slText;
  Log_Main.Color := slBackground;
  Log_Main.Font.Color := slText;
  List_Users.Color := slBackground;
  List_Users.Font.Color := slText;
  List_Registered.Color := slBackground;
  List_Registered.Font.Color := slText;
  List_Servers.Color := slBackground;
  List_Servers.Font.Color := slText;
  List_Channels.Color := slBackground;
  List_Channels.Font.Color := slText;
  List_Bans.Color := slBackground;
  List_Bans.Font.Color := slText;
  List_Lists.Color := slBackground;
  List_Lists.Font.Color := slText;
  List_Hotlist.Color := slBackground;
  List_Hotlist.Font.Color := slText;
  SlavaNapLanguage.List.Color := slBackground;
  SlavaNapLanguage.List.Font.Color := slText;
  SlavaNapEdit.Edit.Color := slBackground;
  SlavaNapEdit.Edit.Font.Color := slText;
  if not All_Windows then Exit;
  if not Running then Exit;
  for I := Cons_Channels.Count - 1 downto 0 do
    TSlavaNapChannelWindow(Cons_Channels.Items[I]).ChangeColors;
  for I := Cons_Chat.Count - 1 downto 0 do
    TSlavaNapChatWindow(Cons_Chat.Items[I]).ChangeColors;
end;

procedure TSlavaNapWindow.Log_Change(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 TSlavaNapWindow.Log_URLClick(Sender: TObject; const URLText: string;
  Button: TMouseButton);
begin
  ShellExecute(Handle, 'open', PChar(URLText), nil, nil, SW_SHOWNORMAL);
end;

procedure TSlavaNapWindow.LogMain(Color: Integer; Text: string; Add_Time: Boolean
  = True);
begin
  if not PauseLog then
  begin
    try
      if Log_Main.Lines.Count > 300 then
      begin
        Log_Main.Lines.BeginUpdate;
        while Log_Main.Lines.Count > 200 do
          Log_Main.Lines.Delete(0);
        Log_Main.Lines.EndUpdate;
      end;
      Log_Main.SelLength := 0;
      Log_Main.SelStart := Length(Log_Main.Text);
      Log_Main.SelAttributes.Color := Color;
      if Add_Time then
        Log_Main.Lines.Add(GetLogTime + Text)
      else
        Log_Main.Lines.Add(Text);
      Log_Change(Log_Main);
    except
      DebugLog('Exception in TMainForm::LogMain()', True);
    end;
  end;
end;

procedure TSlavaNapWindow.LogConsole(Color: Integer; Text: string;
  Add_Time: Boolean = True);
var
  Str: string;
begin
  try
    if Log_Console.Lines.Count > 150 then
    begin
      Log_Console.Lines.BeginUpdate;
      while Log_Console.Lines.Count > 100 do
        Log_Console.Lines.Delete(0);
      Log_Console.Lines.EndUpdate;
    end;
    Log_Console.SelLength := 0;
    Log_Console.SelStart := Length(Log_Console.Text);
    Log_Console.SelAttributes.Color := Color;
    if Add_Time then
      Log_Console.Lines.Add(GetLogTime + Text)
    else
      Log_Console.Lines.Add(Text);
    Log_Change(Log_Console);
    if not Log_Console_Data then
    begin
      if Console_Log_File <> nil then
      try
        Console_Log_File.Free;
        Console_Log_File := nil;
      except
        Console_Log_File := nil;
      end;
      Exit;
    end;
    if Console_Log_File = nil then
    begin
      try
        Console_Log_File := TFileStream.Create(ApplicationDir +
          'console.log.html', fmCreate);
        Console_Log_File.Free;
      except
        Console_Log_File := nil;
        Exit;
      end;
      try
        if Log_Console_Data then
          Console_Log_File := TFileStream.Create(ApplicationDir +
            'console.log.html', fmOpenWrite or fmShareDenyWrite);
      except
        Console_Log_File := nil;
        Exit;
      end;
      Str := '<html>'#13#10'<head><title>SlavaNap console log</title></head>'#13#10'<body bgcolor='
        + Color2HTML(slBackground) + '>'#13#10;
      Console_Log_File.write(Str[1], Length(Str));
    end;
    Str := '<font color=' + Color2HTML(slText) + '>' + GetLogTime +
      '</font><font color=' + Color2HTML(Color) + '>' + Text +
      '</color><br>'#13#10;
    Console_Log_File.write(Str[1], Length(Str));
  except
  end;
end;

procedure TSlavaNapWindow.Timer1Timer(Sender: TObject);
var
  Str: string;
begin
  try
    if Bandwidth_Limited then
    begin
      if StatusBar1.Panels[0].Width = 0 then
      begin
        StatusBar1.Panels[0].Text := GetLangI(LNG_ST_BANDWIDTHLIMIT);
        StatusBar1.Panels[0].Width := Canvas.TextWidth(StatusBar1.Panels[0].Text)
          + 10;
      end;
    end
    else
      StatusBar1.Panels[0].Width := 0;
    if Win98 then
    begin
      Str := GetLangI(LNG_ST_BYTES, IntToStrDot(AllocMemSize));
      StatusBar1.Panels[1].Text := Str;
      StatusBar1.Panels[1].Width := Canvas.TextWidth(Str) + 25;
    end;
    Str := GetLangI(LNG_ST_TIME, IntToStr((GetTickCount - Start_Time) div
      60000));
    StatusBar1.Panels[2].Text := Str;
    StatusBar1.Panels[2].Width := Canvas.TextWidth(Str) + 25;
    if Num_Servers = 0 then
      Str := GetLangI(LNG_ST_NOLINK)
    else
      Str := GetLangI(LNG_ST_LINK, Num_Servers);
    StatusBar1.Panels[3].Text := ' ' + Str;
    StatusBar1.Panels[3].Width := Canvas.TextWidth(Str) + 25;
    if (Last_Bytes_in = 0) and (Last_Bytes_Out = 0) then
      Str := ''
    else
      Str := GetLangI(LNG_ST_BPS, IntToStrDot(Last_Bytes_in div 60),
        IntToStrDot(Last_Bytes_Out div 60));
    StatusBar1.Panels[4].Text := ' ' + Str;
    Str := GetLangI(LNG_ST_LOCAL, IntToStr(Local_Users) + '/' +
      IntToStr(Max_Users), IntToStrDot(Local_Files), IntToStrDot(Local_Files div
      Local_Users), IntToStrDot(Local_Bytes div GigaByte), IntToStrDot((Local_Bytes
      div GigaByte) div Local_Users));
    StatusBar2.Panels[0].Text := Str;
    // Str := GetLangI(LNG_ST_TOTAL, IntToStr(Total_Users) + '/' + IntToStr(Total_Users_Limit), IntToStrDot(Total_Files), IntToStrDot(Total_Bytes div GigaByte), IntToStrDot(Total_Files div Total_Users) + '/' + IntToStrDot((Total_Bytes div GigaByte) div Total_Users));
    Str := GetLangI(LNG_ST_TOTAL, IntToStr(Total_Users) + '/' +
      IntToStr(Total_Users_Limit), IntToStrDot(Total_Files),
      IntToStrDot(Total_Files div Total_Users), IntToStrDot(Total_Bytes div
      GigaByte), IntToStrDot((Total_Bytes div GigaByte) div Total_Users));
    StatusBar2.Panels[2].Text := Str;
    StatusBar2.Panels[0].Width := Width div 2;
    Str := GetLangI(LNG_ST_LOCALMAX, IntToStr(Local_Users_Max),
      IntToStrDot(Local_Files_Max), IntToStrDot(Local_Bytes_Max div GigaByte));
    StatusBar3.Panels[0].Text := Str;
    Str := GetLangI(LNG_ST_TOTALMAX, IntToStr(Total_Users_Max),
      IntToStrDot(Total_Files_Max), IntToStrDot(Total_Bytes_Max div GigaByte));
    StatusBar3.Panels[2].Text := Str;
    StatusBar3.Panels[0].Width := Width div 2;
    Str := GetLangI(LNG_ST_LASTTRANSFER, IntToStrDot(Last_Bytes_in),
      IntToStrDot(Last_Bytes_Out));
    StatusBar4.Panels[0].Text := Str;
    Str := GetLangI(LNG_ST_TOTALTRANSFER, IntToStrDot(Total_Bytes_in +
      Bytes_in), IntToStrDot(Total_Bytes_Out + Bytes_Out));
    StatusBar4.Panels[2].Text := Str;
    StatusBar4.Panels[0].Width := Width div 2;
    Str := GetLangI(LNG_ST_LASTDATA, IntToStr(Last_Login),
      IntToStr(Last_Searches), IntToStr(Last_Transfers), IntToStr(Last_Browses));
    StatusBar5.Panels[0].Text := Str;
    Str := GetLangI(LNG_ST_TOTALDATA, IntToStrDot(Total_Connections),
      IntToStrDot(Total_Searches + Num_Searches), IntToStrDot(Total_Transfers +
      Num_Transfers), IntToStrDot(Total_Browses + Num_Browses));
    StatusBar5.Panels[2].Text := Str;
    StatusBar5.Panels[0].Width := Width div 2;
    UpdateTray;
  except
  end;
end;

procedure TSlavaNapWindow.UpdateTray;
var
  Str: string;
  I, J, Count: Integer;
  Tray_IconInfo: TIconInfo;
  Tray_Icon: TIcon;
begin
  if Total_Users <> Local_Users then
    Str := '[' + IntToStr(Local_Users) + '/' + IntToStr(Total_Users) + '] - ' +
      SLAVANAP_VERSION_SHORT + ' b' + SLAVANAP_BUILD + ' (' + ServerName_I + ')'
  else
    Str := '[' + IntToStr(Total_Users) + '] - ' + SLAVANAP_VERSION_SHORT + ' b'
      + SLAVANAP_BUILD + ' (' + ServerName_I + ')';
  if Tray.Hint = Str then Exit;
  Tray.Hint := Str;
  Caption := Str;
  Count := Total_Users;
  if not Tray.Active then Exit;
  {Draw on the "And" mask}
  Tray_AndMask.Canvas.Brush.Color := clBlack;
  Tray_AndMask.Canvas.FillRect(Rect(0, 0, 16, 16));
  {Draw on the "XOr" mask}
  Tray_XorMask.Canvas.Brush.Color := clWhite;
  Tray_XorMask.Canvas.FillRect(Rect(0, 0, 16, 16));
  Imagelist_Icons.Draw(Tray_XOrMask.Canvas, 0, 0, 0);
  if Count < 10 then
    Imagelist_Digits.Draw(Tray_XorMask.Canvas, 10, 0, Count)
  else if Count < 100 then
  begin
    J := Count div 10;
    Imagelist_Digits.Draw(Tray_XorMask.Canvas, 5, 0, J);
    J := Count mod 10;
    Imagelist_Digits.Draw(Tray_XorMask.Canvas, 10, 0, J);
  end
  else if Count < 1000 then
  begin
    J := Count div 100;
    Imagelist_Digits.Draw(Tray_XorMask.Canvas, 0, 0, J);
    J := (Count div 10) mod 10;
    Imagelist_Digits.Draw(Tray_XorMask.Canvas, 5, 0, J);
    J := Count mod 10;
    Imagelist_Digits.Draw(Tray_XorMask.Canvas, 10, 0, J);
  end
  else
  begin
    J := (Count div 1000) mod 10;
    Imagelist_Digits4.Draw(Tray_XorMask.Canvas, 0, 0, J);
    J := (Count div 100) mod 10;
    Imagelist_Digits4.Draw(Tray_XorMask.Canvas, 4, 0, J);
    J := (Count div 10) mod 10;
    Imagelist_Digits4.Draw(Tray_XorMask.Canvas, 8, 0, J);
    J := Count mod 10;
    Imagelist_Digits4.Draw(Tray_XorMask.Canvas, 12, 0, J);
  end;
  // Check for White pixels
  for I := 0 to 16 do
    for J := 0 to 16 do
      if Tray_XOrMask.Canvas.Pixels[I, J] = clWhite then
        Tray_AndMask.Canvas.Pixels[I, J] := clWhite;
  Tray_Icon := CreateTIcon;
  Tray_IconInfo.fIcon := True;
  Tray_IconInfo.xHotspot := 0;
  Tray_IconInfo.yHotspot := 0;
  Tray_IconInfo.hbmMask := Tray_AndMask.Handle;
  Tray_IconInfo.hbmColor := Tray_XOrMask.Handle;
  Tray_Icon.Handle := CreateIconIndirect(Tray_IconInfo);
  {Assign The application Icon}
  Tray.Icon.Assign(Tray_Icon);
  FreeTIcon(Tray_Icon);
end;

procedure TSlavaNapWindow.Sh_Show(Sender: TObject);
begin
  (Sender as TTabSheet).Realign;
  // (Sender as TTabSheet).Realign;
end;

procedure TSlavaNapWindow.DrawPopupItem2(Sender: TObject; ACanvas: TCanvas;
  ARect: TRect; Selected: Boolean);
var
  I, J, K: Integer;
  R, R1: TRect;
  Str: string;
  C, C1, C2, C3, Bg, Txt: TColor;
begin
  // If you are wondering how this function works - check out tags
  // on every item in popup menu and Img_Popup (hidden TImage on this form)
  C := $00FFB080; // Main Color
  C1 := $00A02020; // Selected rect
  C2 := $00FFA060; // Line
  C3 := $0040E0FF; // Line selected
  Bg := GetSysColor(COLOR_MENU); // Default background (usually clSilver)
  Txt := GetSysColor(COLOR_MENUTEXT);
  try
    with ACanvas do
    begin
      if (Sender as TMenuItem).default then
        Font.Style := Font.Style + [fsBold]
      else
        Font.Style := Font.Style - [fsBold];
      Brush.Color := Bg;
      if Selected then
        if (Sender as TMenuItem).Caption <> '--' then
          Brush.Color := C;
      Font.Color := Txt;
      if Selected then
        if (Sender as TMenuItem).Caption <> '--' then
          Font.Color := CountColor(clBlack, C, 5, 1);
      R := ARect;
      Inc(R.Left, 19);
      FillRect(R);
      Pen.Color := Bg;
      MoveTo(R.Left, R.Top);
      LineTo(R.Left, R.Bottom + 1);
      MoveTo(R.Right - 1, R.Top);
      LineTo(R.Right - 1, R.Bottom + 1);
      if (not Selected) or ((Sender as TMenuItem).Caption = '--') then
      begin
        Brush.Color := CountColor(Bg, C, 3, 1);
        R := ARect;
        R.Right := R.Left + 18;
        R1.Left := 0;
        R1.Right := 18;
        R1.Top := (Sender as TMenuItem).Tag;
        R1.Bottom := R1.Top + (R.Bottom - R.Top);
        CopyRect(R, Img_Popup.Canvas, R1);
      end;
      if (Sender as TMenuItem).Caption <> '--' then
      begin
        J := TextHeight('W');
        J := (ARect.Bottom + ARect.Top - J) div 2;
        Str := ShortCutToText((Sender as TMenuItem).ShortCut);
        I := TextWidth(Str);
        TextOut(ARect.Right - 19 - I, J, Str);
        if (Sender as TMenuItem).Checked then
        begin
          Pen.Color := Font.Color;
          for K := 0 to 2 do
          begin
            MoveTo(ARect.Left + 5, ARect.Top + 7 + K);
            LineTo(ARect.Left + 7, ARect.Top + 9 + K);
            LineTo(ARect.Left + 12, ARect.Top + 4 + K);
          end;
        end;
        if (Sender as TMenuItem).RadioItem then
        begin
          Pen.Color := Font.Color;
          for K := 0 to 4 do
          begin
            MoveTo(ARect.Left + 7, ARect.Top + 6 + K);
            LineTo(ARect.Left + 10, ARect.Top + 6 + K);
          end;
          MoveTo(ARect.Left + 6, ARect.Top + 7);
          LineTo(ARect.Left + 6, ARect.Top + 10);
          MoveTo(ARect.Left + 10, ARect.Top + 7);
          LineTo(ARect.Left + 10, ARect.Top + 10);
        end;
        if Selected then
          with ACanvas do
          begin
            Pen.Color := C1;
            MoveTo(ARect.Left + 19, ARect.Bottom - 2);
            LineTo(ARect.Left + 19, ARect.Top);
            MoveTo(ARect.Left + 20, ARect.Top);
            LineTo(ARect.Right - 1, ARect.Top);
            Pen.Color := C1;
            MoveTo(ARect.Right - 1, ARect.Top + 1);
            LineTo(ARect.Right - 1, ARect.Bottom - 1);
            MoveTo(ARect.Right - 2, ARect.Bottom - 1);
            LineTo(ARect.Left + 19, ARect.Bottom - 1);
          end;
      end
      else
      begin
        I := C2;
        if Selected then
          I := C3;
        Pen.Color := CountColor(Bg, I, 5, 1);
        MoveTo(ARect.Left + 21, ARect.Top + 2);
        LineTo(ARect.Left + 23, ARect.Top + 2);
        Pen.Color := CountColor(Bg, I, 4, 2);
        LineTo(ARect.Left + 25, ARect.Top + 2);
        Pen.Color := CountColor(Bg, I, 3, 3);
        LineTo(ARect.Left + 27, ARect.Top + 2);
        Pen.Color := CountColor(Bg, I, 2, 4);
        LineTo(ARect.Left + 29, ARect.Top + 2);
        Pen.Color := CountColor(Bg, I, 1, 5);
        LineTo(ARect.Left + 31, ARect.Top + 2);
        Pen.Color := I;
        LineTo(ARect.Right, ARect.Top + 2);
      end;
    end;
    J := ACanvas.TextHeight('W');
    J := (ARect.Bottom + ARect.Top - J) div 2;
    if (Sender as TMenuItem).Caption <> '--' then
      with ACanvas do
        SlavaDrawText(ACanvas, (Sender as TMenuItem).Caption, Point(ARect.Left +
          24, J), Font.Color, CountColor(Font.Color, C, 2, 1),
          CountColor(Font.Color, C, 3, 1));
  except
  end;
end;

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

procedure TSlavaNapWindow.Mnu_Tray_ExitClick(Sender: TObject);
begin
  Closing := True;
  Close;
end;

procedure TSlavaNapWindow.Mnu_Tray_RestartClick(Sender: TObject);
begin
  Restarting := True;
  Closing := True;
  Close;
end;

procedure TSlavaNapWindow.Mnu_Tray_SettingsClick(Sender: TObject);
begin
  SlavaNapSettings.Show;
end;

procedure TSlavaNapWindow.Timer2Timer(Sender: TObject);
begin
  if not Running then Exit;
  SaveConfig;
  Cmd_List.AddDoubleCmd(MSG_CMD_SAVEDATA, 0, '', '');
  Mnu_Save.Enabled := False;
end;

procedure TSlavaNapWindow.Btn_Tb_LogClick(Sender: TObject);
begin
  Pages.ActivePage := Sh_Log;
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Btn_Tb_UsersClick(Sender: TObject);
begin
  Pages.ActivePage := Sh_Users;
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Btn_Tb_RegisteredClick(Sender: TObject);
begin
  Pages.ActivePage := Sh_Registered;
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Btn_Tb_ServersClick(Sender: TObject);
begin
  Pages.ActivePage := Sh_Servers;
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.ResizeHeader(List: TListView);
var
  I, W, S, D: Integer;
begin
  W := 0;
  S := 0;
  for I := 0 to List.Columns.Count - 1 do
  begin
    if (List.Columns.Items[I].Width < 0) or (List.Columns.Items[I].Width > 10000)
      then
      if IsHide[I] then
        List.Columns.Items[I].Width := 0
      else
        case I of
          0: List.Columns.Items[I].Width := 120;
          UL_LEVEL + 1: List.Columns.Items[I].Width := 80;
          UL_SHARED + 1: List.Columns.Items[I].Width := 60;
          UL_SIZE + 1: List.Columns.Items[I].Width := 60;
          UL_AVERAGE + 1: List.Columns.Items[I].Width := 60;
          UL_SOFT + 1: List.Columns.Items[I].Width := 50;
          UL_SPEED + 1: List.Columns.Items[I].Width := 75;
          UL_IP + 1: List.Columns.Items[I].Width := 80;
          UL_REMOTEHOST + 1: List.Columns.Items[I].Width := 250;
          UL_PORT + 1: List.Columns.Items[I].Width := 40;
          UL_TIME + 1: List.Columns.Items[I].Width := 60;
          UL_UP + 1: List.Columns.Items[I].Width := 30;
          UL_DOWN + 1: List.Columns.Items[I].Width := 30;
          UL_TRANSFERS + 1: List.Columns.Items[I].Width := 50;
          UL_TUP + 1: List.Columns.Items[I].Width := 50;
          UL_TDOWN + 1: List.Columns.Items[I].Width := 50;
          UL_TTRANSFERS + 1: List.Columns.Items[I].Width := 50;
          UL_SERVER + 1: List.Columns.Items[I].Width := 50;
          UL_ULREQUESTS + 1: List.Columns.Items[I].Width := 30;
          UL_DLREQUESTS + 1: List.Columns.Items[I].Width := 30;
          UL_SEARCHREQS + 1: List.Columns.Items[I].Width := 40;
          UL_BLOCKFILES + 1: List.Columns.Items[I].Width := 40;
          23: List.Columns.Items[I].Width := 50;
        else
          Break;
        end;
    Inc(W, List.Columns.Items[I].Width);
    if List.Columns.Items[I].AutoSize then
      Inc(S);
  end;
  // LogConsole(0, 'ResizeHeader: ' + List.Name + ' S=' + IntToStr(S) + ' W=' + IntToStr(W) + ' Width=' + IntToStr(List.Width));
  if (W > (List.Width - 16)) or (W < (List.Width - 32)) then
  begin
    if S = 0 then Exit;
    D := (W - List.Width + 20 + S) div S;
    if D > 0 then
    begin
      List.Columns.BeginUpdate;
      for I := 0 to List.Columns.Count - 1 do
        if List.Columns.Items[I].AutoSize then
          List.Columns.Items[I].Width := List.Columns.Items[I].Width - D;
      List.Columns.EndUpdate;
      // LogData(clWhite, 'Resizing ' + List.Name);
    end;
  end;
end;

procedure TSlavaNapWindow.ResizeTree(Sender: TObject);
begin
  if Sender Is TListView then
    ResizeHeader(Sender as TListView);
end;

procedure TSlavaNapWindow.ChangeTree(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
  if Sender Is TListView then
    ResizeHeader(Sender as TListView);
end;

function TSlavaNapWindow.CompareLevel(Str1, Str2: string): Integer;
begin
  Result := Ord(Str2Level(Str1)) - Ord(Str2Level(Str2));
end;

function TSlavaNapWindow.CompareIP(Str1, Str2: string): Integer;
var
  N1, N2: Integer;
  I, J: Integer;
  Str: string;
begin
  Result := 0;
  Str1 := Str1 + '.';
  Str2 := Str2 + '.';
  for I := 0 to 3 do
  begin
    J := Pos('.', Str1);
    if J = 0 then Exit;
    Str := Copy(Str1, 1, J - 1);
    Str1 := Copy(Str1, J + 1, Length(Str1));
    N1 := StrToIntDef(Str, 0);
    J := Pos('.', Str2);
    if J = 0 then Exit;
    Str := Copy(Str2, 1, J - 1);
    Str2 := Copy(Str2, J + 1, Length(Str2));
    N2 := StrToIntDef(Str, 0);
    if N2 <> N1 then
    begin
      Result := N1 - N2;
      Exit;
    end;
  end;
end;

function TSlavaNapWindow.CompareDate(Str1, Str2: string): Integer;
var
  D1, D2: TDateTime;
begin
  Result := 0;
  try
    D1 := StrToDateTime(Str1);
  except
    D1 := 0;
  end;
  try
    D2 := StrToDateTime(Str2);
  except
    D2 := 0;
  end;
  if D2 > D1 then
    Result := -1
  else if D2 < D1 then
    Result := 1;
end;

function TSlavaNapWindow.CompareTime(Str1, Str2: string): Integer;
var
  T1, T2: Time_T;
begin
  T1 := Str2Time(Str1);
  T2 := Str2Time(Str2);
  Result := T1 - T2;
end;

function TSlavaNapWindow.CompareDigit(Str1, Str2: string): Integer;
begin
  Result := StrToIntDef(Str1, 0) - StrToIntDef(Str2, 0);
end;

// ファイルサイズなど大きい数用。カンマ区切りの文字列でもOk

function TSlavaNapWindow.CompareDigit2(Str1, Str2: string): Integer;
var
  I: Integer;
begin
  Result := Length(Str1) - Length(Str2);
  if Result <> 0 then Exit;
  I := 0;
  while I <= Length(Str1) do
  begin
    Result := Ord(Str1[I]) - Ord(Str2[I]);
    if Result <> 0 then Exit;
    Inc(I);
  end;
end;

function TSlavaNapWindow.CompareSpeed(Str1, Str2: string): Integer;
var
  S1, S2: TNapSpeed;
begin
  S1 := Str2Speed(Str1);
  S2 := Str2Speed(Str2);
  Result := Ord(S1) - Ord(S2);
end;

function TSlavaNapWindow.CompareRemoteHost(Str1, Str2: string): Integer;
  function ReverseString(const S: string): string;
  var
    I, L: Integer;
  begin
    SetLength(Result, Length(S));
    L := Length(S);

    for I := 0 to L - 1 do
      Result[L - I] := S[I + 1];
  end;
begin
  Result := CompareStr(ReverseString(Str1), ReverseString(Str2));
end;

// Zzz

function TSlavaNapWindow.DoCompare(List: TListView; Index: Integer;
  Str1, Str2: string): Integer;
begin
  if (List = List_Registered) and (Index = 1) then
    Result := CompareLevel(Str1, Str2)
  else if (List = List_Registered) and (Index = 3) then
    Result := CompareIP(Str1, Str2)
  else if (List = List_Registered) and (Index = 4) then
    Result := CompareDate(Str1, Str2)
  else if (List = List_Users) and (Index = UL_LEVEL + 1) then
    Result := CompareLevel(Str1, Str2)
  else if (List = List_Users) and (Index = UL_SHARED + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_SIZE + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_AVERAGE + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_SPEED + 1) then
    Result := CompareSpeed(Str1, Str2)
  else if (List = List_Users) and (Index = UL_IP + 1) then
    Result := CompareIP(Str1, Str2)
  else if (List = List_Users) and (Index = UL_REMOTEHOST + 1) then
    Result := CompareRemoteHost(Str1, Str2)
  else if (List = List_Users) and (Index = UL_PORT + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_TIME + 1) then
    Result := CompareTime(Str1, Str2)
  else if (List = List_Users) and (Index = UL_UP + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_DOWN + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_TUP + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_TDOWN + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_ULREQUESTS + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_DLREQUESTS + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_SEARCHREQS + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = UL_BLOCKFILES + 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Users) and (Index = 23) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Channels) and (Index = 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Channels) aNd (Index = 2) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Channels) and (Index = 3) then
    Result := CompareLevel(Str1, Str2)
  else if (List = List_Servers) and (Index = 1) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_Bans) and (Index = 3) then
    Result := CompareDate(Str1, Str2)
  else if (List = List_Bans) and (Index = 4) then
    Result := CompareDate(Str1, Str2)
  else if (List = List_Bans) and (Index = 5) then
    Result := CompareDate(Str1, Str2)
  else if (List = List_Bans) and (Index = 7) then
    Result := CompareDigit(Str1, Str2)
  else if (List = List_HotList) and (Index = 2) then
    Result := CompareSpeed(Str1, Str2)
  else if (List.Parent.ClassType = TSlavaNapBrowseWindow) then
  begin
    if Index = 0 then
      Result := AnsiCompareStr(Str1, Str2)
    else if Index = 1 then
      Result := CompareDigit2(Str1, Str2)
    else if Index = 4 then
      Result := CompareTime(Str1, Str2)
    else
      Result := CompareDigit(Str1, Str2);
  end
  else
    Result := AnsiCompareStr(Str1, Str2);
end;

procedure TSlavaNapWindow.ListCompare(Sender: TObject; Item1,
  Item2: TListItem; Data: Integer; var Compare: Integer);
var
  Tag: Integer;
begin
  Tag := (Sender as TListView).Tag;
  if Tag > 0 then
  begin
    if Item1.SubItems.Count < Tag then
      Tag := 0;
    if Item2.SubItems.Count < Tag then
      Tag := 0;
    if Tag > 0 then
      Compare := DoCompare(Sender as TListView, Tag, Item1.SubItems[Tag - 1],
        Item2.SubItems[Tag - 1]);
  end;
  if Tag < 0 then
  begin
    Tag := -1 - Tag;
    if Item1.SubItems.Count < Tag then
      Tag := 0;
    if Item2.SubItems.Count < Tag then
      Tag := 0;
    if Tag > 0 then
      Compare := DoCompare(Sender as TListView, Tag, Item2.SubItems[Tag - 1],
        Item1.SubItems[Tag - 1])
    else
      Compare := DoCompare(Sender as TListView, 0, Item2.Caption,
        Item1.Caption);
    Exit;
  end;
  if Tag = 0 then
    Compare := DoCompare(Sender as TListView, 0, Item1.Caption, Item2.Caption);
end;

procedure TSlavaNapWindow.ListColumnClick(Sender: TObject;
  Column: TListColumn);
var
  Tag: Integer;
begin
  Tag := (Sender as TListView).Tag;
  if Tag = Column.Index then
    (Sender as TListView).Tag := -Tag - 1
  else
    (Sender as TListView).Tag := Column.Index;
  (Sender as TListView).AlphaSort;
end;

procedure TSlavaNapWindow.AppException(Sender: TObject; E: Exception);
begin
  try
    // if (Tmp_Pos <> 1480) and (Tmp_Pos <> 1482) then
    DebugLog('AppException: (Pos=' + IntToStr(Tmp_Pos) + ') ' + E.Message);
  except
  end;
end;

procedure TSlavaNapWindow.Mnu_Draw(Sender: TObject; ACanvas: TCanvas;
  ARect: TRect; Selected: Boolean);
begin
  SlavaDrawMainMenu(Self, Sender, ACanvas, ARect, Selected);
end;

procedure TSlavaNapWindow.Mnu_LanguagesClick(Sender: TObject);
begin
  SlavaNapLanguage.Show;
end;

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

procedure TSlavaNapWindow.Popup_TrayPopup(Sender: TObject);
begin
  if Visible then
    Mnu_Tray_Show.Caption := GetLangI(LNG_MENU_HIDE)
  else
    Mnu_Tray_Show.Caption := GetLangI(LNG_MENU_SHOW);
end;

procedure TSlavaNapWindow.Mnu_Tray_ShowClick(Sender: TObject);
begin
  try
    if Visible then
      Hide
    else
    begin
      Show;
      if WindowState = wsMinimized then
        WindowState := wsNormal;
    end;
  except
  end;
end;

procedure TSlavaNapWindow.Btn_Reg_RefreshClick(Sender: TObject);
begin
  if Running then
  begin
    Cmd_List.AddDoubleCmd(MSG_CMD_LIStrEGISTERED, 0, '', '');
    Btn_Reg_Refresh.Enabled := False;
    Mnu_Reg_Refresh.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Btn_Users_KickClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_KILL, 0, List_Users.Items.Item[I].Caption
        + ' ' + Edit_Users_Reason.Text, '');
  if List_Users.SelCount > 0 then
    Btn_Users_refreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Users_NukeClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_NUKE, 0, List_Users.Items.Item[I].Caption
        + ' ' + Edit_Users_Reason.Text, '');
  if List_Users.SelCount > 0 then
    Btn_Users_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Users_MuzzleClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_MUZZLEINV, 0,
        List_Users.Items.Item[I].Caption + ' ' + Edit_Users_Reason.Text, '');
  if List_Users.SelCount > 0 then
    Btn_Users_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Users_RefreshClick(Sender: TObject);
begin
  if Running then
  begin
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTUSERS, 0, '', '');
    Btn_Users_Refresh.Enabled := False;
    Mnu_Users_Refresh.Enabled := False;
  end;
end;

{procedure TSlavaNapWindow.Btn_Users_BanClick(Sender: TObject);
var
 I, T: Integer;
begin
 T := GetBanID(Edit_Users_Time);
 for I := 0 to List_Users.Items.Count - 1 do
  if List_Users.Items.Item[I].Selected then
   Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, List_Users.Items.Item[I].Caption + '!' + List_Users.Items.Item[I].SubItems[UL_IP] + ' ' + IntToStr(T) + ' ' + Edit_Users_Reason.Text, '');
end;}

procedure TSlavaNapWindow.Btn_Users_BanClick(Sender: TObject);
var
  I, T: Integer;
begin
  T := GetBanID(Edit_Users_Time);
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, List_Users.Items.Item[I].Caption
        + ' ' + IntToStr(T) + ' ' + Edit_Users_Reason.Text, '');
end;

procedure TSlavaNapWindow.Btn_Users_BanipClick(Sender: TObject);
var
  I, T: Integer;
begin
  T := GetBanID(Edit_Users_Time);
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0,
        List_Users.Items.Item[I].SubItems[UL_IP] + ' ' + IntToStr(T) + ' ' +
        List_Users.Items.Item[I].Caption + ': ' + Edit_Users_Reason.Text, '');
end;

procedure TSlavaNapWindow.Mnu_Log_ClearClick(Sender: TObject);
begin
  if Popup_Log.Tag = 1 then
    Log_Main.Lines.Clear;
  if Popup_Log.Tag = 2 then
    Log_Console.Lines.Clear;
end;

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

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

procedure TSlavaNapWindow.Mnu_Users_LevelClick(Sender: TObject);
var
  Str: string;
  I: Integer;
begin
  if Sender = Mnu_Users_Level0 then
    Str := ' 0'
  else if Sender = Mnu_Users_Level1 then
    Str := ' 1'
  else if Sender = Mnu_Users_Level2 then
    Str := ' 2'
  else if Sender = Mnu_Users_Level3 then
    Str := ' 3'
  else if Sender = Mnu_Users_Level4 then
    Str := ' 4'
  else
    Exit;
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_SETUSERLEVEL, 0,
        List_Users.Items.Item[I].Caption + Str, '');
  if List_Users.SelCount > 0 then
    Btn_Users_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Popup_UsersPopup(Sender: TObject);
begin
  Mnu_Users_Level0.Caption := Levels[0];
  Mnu_Users_Level1.Caption := Levels[1];
  Mnu_Users_Level2.Caption := Levels[2];
  Mnu_Users_Level3.Caption := Levels[3];
  Mnu_Users_Level4.Caption := Levels[4];
  case List_Users.SelCount of
    0:
      begin
        Mnu_Users_Im.Enabled := False;
        Mnu_Users_Whois.Enabled := False;
        Mnu_Users_Browse.Enabled := False;
        Mnu_Users_Announce.Enabled := False;
        Mnu_Users_hOtlist.Enabled := False;
        Mnu_Users_Friend.Enabled := False;
        Mnu_Users_Ignore.Enabled := False;
        Mnu_Users_Kick.Enabled := False;
        Mnu_Users_Nuke.Enabled := False;
        Mnu_Users_Muzzle.Enabled := False;
        Mnu_Users_Ban.Enabled := False;
        Mnu_Users_Banip.Enabled := False;
        Mnu_Users_Kickban.Enabled := False;
        Mnu_Users_Kickbanip.Enabled := False;
        Mnu_Users_Register.Enabled := False;
        Mnu_Users_Level.Enabled := False;
        Mnu_Users_Speed.Enabled := False;
        Mnu_Users_CopyName.Enabled := False;
      end;
    1:
      begin
        Mnu_Users_Im.Enabled := True;
        Mnu_Users_Whois.Enabled := True;
        Mnu_Users_Browse.Enabled := True;
        Mnu_Users_Announce.Enabled := True;
        Mnu_Users_Hotlist.Enabled := True;
        Mnu_Users_Friend.Enabled := True;
        Mnu_Users_Ignore.Enabled := True;
        Mnu_Users_Kick.Enabled := True;
        Mnu_Users_Nuke.Enabled := True;
        Mnu_Users_Muzzle.Enabled := True;
        Mnu_Users_Ban.Enabled := True;
        Mnu_Users_Banip.Enabled := True;
        Mnu_Users_Kickban.Enabled := True;
        Mnu_Users_Kickbanip.Enabled := True;
        Mnu_Users_Register.Enabled := True;
        Mnu_Users_Level.Enabled := True;
        Mnu_Users_Speed.Enabled := True;
        Mnu_Users_CopyName.Enabled := True;
      end;
  else
    Mnu_Users_Im.Enabled := False;
    Mnu_Users_Whois.Enabled := False;
    Mnu_Users_Browse.Enabled := True;
    Mnu_Users_Announce.Enabled := True;
    Mnu_Users_Hotlist.Enabled := True;
    Mnu_Users_Friend.Enabled := True;
    Mnu_Users_Ignore.Enabled := True;
    Mnu_Users_Kick.Enabled := True;
    Mnu_Users_Nuke.Enabled := True;
    Mnu_Users_Muzzle.Enabled := True;
    Mnu_Users_Ban.Enabled := True;
    Mnu_Users_Banip.Enabled := True;
    Mnu_Users_Kickban.Enabled := True;
    Mnu_Users_Kickbanip.Enabled := True;
    Mnu_Users_Register.Enabled := True;
    Mnu_Users_Level.Enabled := True;
    Mnu_Users_Speed.Enabled := True;
    Mnu_Users_CopyName.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Mnu_Users_SpeedClick(Sender: TObject);
var
  I: Integer;
  Str: string;
begin
  if Sender = Mnu_Users_Speed0 then
    I := 0
  else if Sender = Mnu_Users_Speed1 then
    I := 1
  else if Sender = Mnu_Users_Speed2 then
    I := 2
  else if Sender = Mnu_Users_Speed3 then
    I := 3
  else if Sender = Mnu_Users_Speed4 then
    I := 4
  else if Sender = Mnu_Users_Speed5 then
    I := 5
  else if Sender = Mnu_Users_Speed6 then
    I := 6
  else if Sender = Mnu_Users_Speed7 then
    I := 7
  else if Sender = Mnu_Users_Speed8 then
    I := 8
  else if Sender = Mnu_Users_Speed9 then
    I := 9
  else if Sender = Mnu_Users_Speed10 then
    I := 10
  else
    Exit;
  Str := ' ' + IntToStr(I);
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_ALTER_SPEED, 0,
        List_Users.Items.Item[I].Caption + Str, '');
  if List_Users.SelCount > 0 then
    Btn_Users_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Users_SelallClick(Sender: TObject);
var
  I: Integer;
begin
  List_Users.Items.BeginUpdate;
  for I := 0 to List_Users.Items.Count - 1 do
    List_Users.Items.Item[I].Selected := True;
  List_Users.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Users_SelnoneClick(Sender: TObject);
var
  I: Integer;
begin
  List_Users.Items.BeginUpdate;
  for I := 0 to List_Users.Items.Count - 1 do
    List_Users.Items.Item[I].Selected := False;
  List_Users.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Users_CopyNameClick(Sender: TObject);
begin
  if List_Users.SelCount <> 1 then Exit;
  if List_Users.Selected = nil then Exit;
  Clipboard.AsText := List_Users.Selected.Caption;
end;

procedure TSlavaNapWindow.Btn_Reg_NukeClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Registered.Items.Count - 1 do
    if List_Registered.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_NUKE, 0,
        List_Registered.Items.Item[I].Caption + ' ' + Edit_Reg_reAson.Text, '');
  if List_Registered.SelCount > 0 then
    Btn_Reg_RefreshClick(nil);
end;

{procedure TSlavaNapWindow.Btn_Reg_BanClick(Sender: TObject);
var
  I, J: Integer;
begin
  J := GetBanID(Edit_Reg_Time);
  for I := 0 to List_Registered.Items.Count - 1 do
  if List_Registered.Items.Item[I].Selected then
    Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, List_Registered.Items.Item[I].Caption + '!' + List_Registered.Items.Item[I].SubItems[2] + ' ' + IntToStr(J) + ' ' + Edit_Reg_Reason.Text, '');
end;}

procedure TSlavaNapWindow.Btn_Reg_BanClick(Sender: TObject);
var
  I, J: Integer;
begin
  J := GetBanID(Edit_Reg_Time);
  for I := 0 to List_Registered.Items.Count - 1 do
    if List_Registered.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0,
        List_Registered.Items.Item[I].Caption + ' ' + IntToStr(J) + ' ' +
        Edit_Reg_Reason.Text, '');
end;

procedure TSlavaNapWindow.Btn_Reg_BanipClick(Sender: TObject);
var
  I, J: Integer;
begin
  J := GetBanID(Edit_Reg_Time);
  for I := 0 to List_Registered.Items.Count - 1 do
    if List_Registered.Items.Item[I].Selected then
      // Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, List_Registered.Items.Item[I].SubItems[2] + ' ' + IntToStr(J) + ' ' + Edit_Reg_Reason.Text, '');
      Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0,
        List_Registered.Items.Item[I].SubItems[2] + ' ' + IntToStr(J) + ' ' +
        List_Registered.Items.Item[I].Caption + ': ' + Edit_Users_Reason.Text,
        '');
end;

procedure TSlavaNapWindow.Mnu_Reg_LevelClick(Sender: TObject);
var
  Str: string;
  I: Integer;
begin
  if Sender = Mnu_Reg_Level0 then
    Str := ' 0'
  else if Sender = Mnu_Reg_Level1 then
    Str := ' 1'
  else if Sender = Mnu_Reg_Level2 then
    Str := ' 2'
  else if Sender = Mnu_Reg_Level3 then
    Str := ' 3'
  else if Sender = Mnu_Reg_Level4 then
    Str := ' 4'
  else
    Exit;
  for I := 0 to List_Registered.Items.Count - 1 do
    if List_Registered.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_SETUSERLEVEL, 0,
        List_Registered.Items.Item[I].Caption + Str, '');
  if List_Registered.SelCount > 0 then
    Btn_Reg_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Reg_SelallClick(Sender: TObject);
var
  I: Integer;
begin
  List_Registered.Items.BeginUpdate;
  for I := 0 to List_Registered.Items.Count - 1 do
    List_Registered.Items.Item[I].Selected := True;
  List_Registered.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Reg_SelnoneClick(Sender: TObject);
var
  I: Integer;
begin
  List_Registered.Items.BeginUpdate;
  for I := 0 to List_Registered.Items.Count - 1 do
    List_Registered.Items.Item[I].Selected := False;
  List_Registered.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Reg_CopyNameClick(Sender: TObject);
begin
  if List_Registered.SelCount <> 1 then Exit;
  if List_Registered.Selected = nil then Exit;
  Clipboard.AsText := List_Registered.Selected.Caption;
end;

procedure TSlavaNapWindow.Popup_RegisteredPopup(Sender: TObject);
begin
  Mnu_Reg_Level0.Caption := Levels[0];
  Mnu_Reg_Level1.Caption := Levels[1];
  Mnu_Reg_Level2.Caption := Levels[2];
  Mnu_Reg_Level3.Caption := Levels[3];
  Mnu_Reg_Level4.Caption := Levels[4];
  case List_Registered.SelCount of
    0:
      begin
        Mnu_Reg_Nuke.Enabled := False;
        Mnu_Reg_Ban.Enabled := False;
        Mnu_Reg_Banip.Enabled := False;
        Mnu_Reg_Level.Enabled := False;
        Mnu_Reg_CopyName.Enabled := False;
      end;
    1:
      begin
        Mnu_Reg_Nuke.Enabled := True;
        Mnu_Reg_Ban.Enabled := True;
        Mnu_Reg_Banip.Enabled := True;
        Mnu_Reg_Level.Enabled := True;
        Mnu_Reg_CopyName.Enabled := True;
      end;
  else
    Mnu_Reg_Nuke.Enabled := True;
    Mnu_Reg_Ban.Enabled := True;
    Mnu_Reg_Banip.Enabled := True;
    Mnu_Reg_Level.Enabled := True;
    Mnu_Reg_CopyName.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Btn_Tb_ChannelsClick(Sender: TObject);
begin
  Pages.ActivePage := Sh_Channels;
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Btn_Tb_BansClick(Sender: TObject);
begin
  Pages.ActivePage := Sh_bans;
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Btn_Tb_HotlistClick(Sender: TObject);
begin
  Pages.ActivePage := Sh_Hotlist;
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.ClientResize(Sender: TObject);
begin
  StatusBar2.Width := Client.Width - StatusBar2.Left;
  StatusBar3.Width := Client.Width - StatusBar3.Left;
  StatusBar4.Width := Client.Width - StatusBar4.Left;
  StatusBar5.Width := Client.Width - StatusBar5.Left;
  // StatusBar6.Width := Client.Width-StatusBar6.Left;
  if Panel_Console.Height = 0 then Exit;
  if Client.Height = 0 then Exit;
  Panel_Console.Height := Splitter_Pos * Client.Height div 1000;
  if Panel_Console.Height < 0 then
    Panel_Console.Height := 0;
  if Client.Height > 10 then
    if (Client.Height - Panel_Console.Height) < 90 then
    begin
      if Client.Height > 90 then
        Panel_Console.Height := Client.Height - 90
      else
        Panel_Console.Height := 0;
    end;
  try
    if Pages.ActivePage = Sh_Log then
      Log_Main.Invalidate;
    Log_Console.Invalidate;
  except
  end;
end;

procedure TSlavaNapWindow.SlavaSplitter1Moved(Sender: TObject);
begin
  if Panel_Console.Height > (Client.Height - 50) then
    if Client.Height > 60 then
      Panel_Console.Height := Client.Height - 50;
  Splitter_Pos := Panel_Console.Height * 1000 div client.Height;
end;

procedure TSlavaNapWindow.Btn_Ch_RefreshClick(Sender: TObject);
begin
  if Running then
  begin
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTCHANNELS, 0, '', '');
    Btn_Ch_Refresh.Enabled := False;
    Mnu_Ch_Refresh.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Btn_Ch_DeleteClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Channels.Items.Count - 1 do
    if List_Channels.Items[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_DROP_CHANNEL, 0,
        List_Channels.Items[I].Caption + ' ' + Edit_Ch_Reason.Text, '');
  if List_Channels.SelCount > 0 then
    Btn_Ch_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Ch_AddClick(Sender: TObject);
begin
  SlavaNapEdit.Ask(SE_ADDCHANNEL);
end;

procedure TSlavaNapWindow.Popup_ChannelsPopup(Sender: TObject);
begin
  case List_Channels.SelCount of
    0:
      begin
        Mnu_Ch_Join.Enabled := False;
        Mnu_Ch_Delete.Enabled := False;
        Mnu_Ch_Clear.Enabled := False;
        Mnu_Ch_Topic.Enabled := False;
        Mnu_Ch_Props.Enabled := False;
        Mnu_Ch_CopyName.Enabled := False;
        Mnu_Ch_Clearbans.Enabled := False;
      end;
    1:
      begin
        Mnu_Ch_Join.Enabled := True;
        Mnu_Ch_Delete.Enabled := True;
        Mnu_Ch_Clear.Enabled := True;
        Mnu_Ch_Topic.Enabled := True;
        Mnu_Ch_Props.Enabled := True;
        Mnu_Ch_CopyName.Enabled := True;
        Mnu_Ch_Clearbans.Enabled := True;
      end;
  else
    Mnu_Ch_Join.Enabled := False;
    Mnu_Ch_Delete.Enabled := True;
    Mnu_Ch_Clear.Enabled := True;
    Mnu_Ch_Topic.Enabled := False;
    Mnu_Ch_Props.Enabled := False;
    Mnu_Ch_CopyName.Enabled := True;
    Mnu_Ch_Clearbans.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Btn_Ch_JoinClick(Sender: TObject);
begin
  if not Running then Exit;
  if List_Channels.SelCount <> 1 then Exit;
  if List_Channels.Selected = nil then Exit;
  Cmd_List.AddDoubleCmd(MSG_CLIENT_JOIN, 0, List_Channels.Selected.Caption, '');
end;

function TSlavaNapWindow.FindChannelWindow(Channel: string):
  TSlavaNapChannelWindow;
var
  I: Integer;
begin
  Result := nil;
  if Cons_Channels = nil then Exit;
  for I := 0 to Cons_Channels.Count - 1 do
    if AnsiLowerCase(TSlavaNapChannelWindow(Cons_Channels.Items[I]).Channel) =
      AnsiLowerCase(Channel) then
    begin
      Result := Cons_Channels.Items[I];
      Exit;
    end;
end;

function TSlavaNapWindow.CreateChannelWindow(Channel: string):
  TSlavaNapChannelWindow;
var
  I: Integer;
  Form: TSlavaNapChannelWindow;
begin
  Result := nil;
  if not Running then Exit;
  if Cons_Channels = nil then Exit;
  for I := 0 to Cons_Channels.Count - 1 do
    if AnsiLowerCase(TSlavaNapChannelWindow(Cons_Channels.Items[I]).Channel) =
      AnsiLowerCase(Channel) then
    begin
      Result := Cons_Channels.Items[I];
      Exit;
    end;
  Form := TSlavaNapChannelWindow.Create(Self);
  Cons_Channels.Add(Form);
  Form.Channel := Channel;
  Form.Caption := Channel;
  try
    Form.Show;
    Form.Edit.SetFocus;
  except
  end;
  Result := Form;
end;

function TSlavaNapWindow.FindChatWindow(User: string): TSlavaNapChatWindow;
var
  I: Integer;
begin
  Result := nil;
  if Cons_Chat = nil then Exit;
  for I := 0 to Cons_Chat.Count - 1 do
    if AnsiLowerCase(TSlavaNapChatWindow(Cons_Chat.Items[I]).User) =
      AnsiLowerCase(User) then
    begin
      Result := Cons_Chat.Items[I];
      Exit;
    end;
end;

function TSlavaNapWindow.CreateChatWindow(User: string): TSlavaNapChatWindow;
var
  I: Integer;
  Form: TSlavaNapChatWindow;
begin
  Result := nil;
  if not Running then Exit;
  if Cons_Chat = nil then Exit;
  for I := 0 to Cons_Chat.Count - 1 do
    if AnsiLowerCase(TSlavaNapChatWindow(Cons_Chat.Items[I]).User) =
      AnsiLowerCase(User) then
    begin
      Result := Cons_Chat.Items[I];
      Exit;
    end;
  Form := TSlavaNapChatWindow.Create(Self);
  Cons_Chat.Add(Form);
  Form.User := User;
  Form.Caption := GetLangI(LNG_CHAT, User);
  try
    Form.Show;
    Form.Edit.SetFocus;
  except
  end;
  Result := Form;
end;

function TSlavaNapWindow.CreateWhoisWindow(User: string): TSlavaNapWhois;
var
  I: Integer;
  Form: TSlavaNapWhois;
begin
  Result := nil;
  if not Running then Exit;
  if Cons_Whois = nil then Exit;
  for I := 0 to Cons_Whois.Count - 1 do
    if AnsiLowerCase(TSlavaNapWhois(Cons_Whois.Items[I]).User) =
      AnsiLowerCase(User) then
    begin
      Result := Cons_Whois.Items[I];
      Exit;
    end;
  Form := TSlavaNapWhois.Create(Self);
  Cons_Whois.Add(Form);
  Form.User := User;
  Result := Form;
end;

procedure TSlavaNapWindow.Btn_Ch_PropsClick(Sender: TObject);
begin
  if not Running then Exit;
  if List_Channels.SelCount <> 1 then Exit;
  if List_Channels.Selected = nil then Exit;
  Cmd_List.AddDoubleCmd(MSG_CMD_CHANNELPROPS, 0, List_Channels.Selected.Caption,
    '');
end;

procedure TSlavaNapWindow.Btn_Bans_RefreshClick(Sender: TObject);
begin
  if Running then
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTBANS, 0, '', '');
end;

procedure TSlavaNapWindow.Btn_Bans_AddClick(Sender: TObject);
var
  T: Cardinal;
begin
  if not Running then Exit;
  if Edit_Bans_User.Text = '' then Exit;
  if Edit_Ban_Reason.Text = '' then
    Edit_Ban_Reason.Text := RS_NoReason;
  T := GetBanID(Edit_Ban_Time);
  Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, Edit_Bans_User.Text + ' ' +
    IntToStr(T) + ' ' + Edit_Ban_Reason.Text, '');
  Cmd_List.AddDoubleCmd(MSG_CMD_LISTBANS, 0, '', '');
  Edit_Bans_User.Text := '';
end;

procedure TSlavaNapWindow.Btn_Ban_DeleteClick(Sender: TObject);
var
  I: Integer;
begin
  if not Running then Exit;
  for I := 0 to List_Bans.Items.Count - 1 do
    if List_Bans.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_UNBAN, 0, List_Bans.Items.Item[I].Caption
        + '!' + List_Bans.Items.Item[I].SubItems[0] + ' ' + Edit_Unban_Reason.Text,
        '');
  if List_Bans.SelCount > 0 then
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTBANS, 0, '', '');
end;

procedure TSlavaNapWindow.Btn_Servers_RefreshClick(Sender: TObject);
begin
  if Running then
  begin
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTSERVERS, 0, '', '');
    Btn_Servers_Refresh.Enabled := False;
    Mnu_Srv_Refresh.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Btn_Servers_ConnectClick(Sender: TObject);
var
  I: Integer;
begin
  if not Running then Exit;
  for I := 0 to List_Servers.Items.Count - 1 do
    if List_Servers.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_CONNECT, 0,
        List_Servers.Items.Item[I].Caption, '');
  if List_Servers.SelCount > 0 then
    Btn_Servers_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Servers_DisconnectClick(Sender: TObject);
var
  I: Integer;
begin
  if not Running then Exit;
  for I := 0 to List_Servers.Items.Count - 1 do
    if List_serVers.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_DISCONNECT, 0,
        List_Servers.Items.Item[I].Caption, '');
  if List_Servers.SelCount > 0 then
    Btn_Servers_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Users_HotlistClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_ADD_HOTLIST, 0,
        List_Users.Items.Item[I].Caption, '');
  if List_Users.SelCount > 0 then
    Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
end;

procedure TSlavaNapWindow.Mnu_Users_IgnoreClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_IGNORE_USER, 0,
        List_Users.Items.Item[I].Caption, '');
  if List_Users.SelCount > 0 then
    Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
end;

procedure TSlavaNapWindow.Mnu_Users_FriendClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_FRIENDS, 0, 'Add ' +
        List_Users.Items.Item[I].Caption, '');
  if List_Users.SelCount > 0 then
    Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
end;

procedure TSlavaNapWindow.Btn_Tb_FriendsClick(Sender: TObject);
begin
  ShowList(consFriends);
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Btn_Tb_IgnoredClick(Sender: TObject);
begin
  ShowList(consIgnored);
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Btn_Tb_BlocksClick(Sender: TObject);
begin
  ShowList(consBlocks);
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.ShowList(T: TConsoleList);
begin
  Cons_List := T;
  ConsoleListLists(True);
end;

procedure TSlavaNapWindow.Mnu_Ch_SelallClick(Sender: TObject);
var
  I: Integer;
begin
  List_Channels.Items.BeginUpdate;
  for I := 0 to List_Channels.Items.Count - 1 do
    List_Channels.Items.Item[I].Selected := True;
  List_Channels.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Ch_SelnoneClick(Sender: TObject);
var
  I: Integer;
begin
  List_Channels.Items.BeginUpdate;
  for I := 0 to List_Channels.Items.Count - 1 do
    List_Channels.Items.Item[I].Selected := False;
  List_Channels.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Ch_CopyNameClick(Sender: TObject);
begin
  if List_Channels.SelCount <> 1 then Exit;
  if List_Channels.Selected = nil then Exit;
  Clipboard.AsText := List_Channels.Selected.Caption;
end;

procedure TSlavaNapWindow.Btn_List_RefreshClick(Sender: TObject);
begin
  Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
end;

procedure TSlavaNapWindow.Btn_List_DeleteClick(Sender: TObject);
var
  I, J: Integer;
  Str: string;
begin
  if not Running then Exit;
  case Cons_List of
    consFriends:
      begin
        J := MSG_CLIENT_FRIENDS;
        Str := 'Remove ';
      end;
    consIgnored:
      begin
        J := MSG_CLIENT_UNIGNORE_USER;
        Str := '';
      end;
    consBlocks:
      begin
        J := MSG_CLIENT_UNBLOCK;
        Str := '';
      end;
  else
    J := 0;
  end;
  for I := 0 to List_Lists.Items.Count - 1 do
    if List_Lists.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(J, 0, Str + List_Lists.Items.Item[I].Caption, '');
  Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
end;

procedure TSlavaNapWindow.Btn_List_AddClick(Sender: TObject);
var
  J: Integer;
  Str: string;
begin
  if Edit_List_Item.Text = '' then Exit;
  if not Running then Exit;
  case Cons_List of
    consFriends:
      begin
        J := MSG_CLIENT_FRIENDS;
        Str := 'Add ';
      end;
    consIgnored:
      begin
        J := MSG_CLIENT_IGNORE_USER;
        Str := '';
      end;
    consBlocks:
      begin
        J := MSG_CLIENT_BLOCK;
        Str := '';
      end;
  else
    J := 0;
  end;
  Cmd_List.AddDoubleCmd(J, 0, Str + Edit_List_Item.Text, '');
  Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
  Edit_List_Item.Text := '';
end;

procedure TSlavaNapWindow.Btn_Servers_DeleteClick(Sender: TObject);
var
  I: Integer;
begin
  if not Running then Exit;
  for I := 0 to List_Servers.Items.Count - 1 do
    if List_Servers.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_REMOVE_SERVER, 0,
        List_Servers.Items.Item[I].Caption, '');
  if List_Servers.SelCount > 0 then
    Btn_Servers_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Servers_AddClick(Sender: TObject);
begin
  if not Running then Exit;
  if Edit_Servers_Host.Text = '' then Exit;
  Cmd_List.AddDoubleCmd(MSG_CMD_ADDSERVER, 0, LowerCase(Edit_Servers_Host.Text),
    '');
end;

procedure TSlavaNapWindow.Btn_Servers_PropsClick(Sender: TObject);
begin
  if not Running then Exit;
  if List_Servers.Selected = nil then Exit;
  Cmd_List.AddDoubleCmd(MSG_CMD_SERVERPROPS, 0, List_Servers.Selected.Caption,
    '');
end;

procedure TSlavaNapWindow.Mnu_Help_ManualClick(Sender: TObject);
begin
  // ShellExecute(Handle, PChar('open'), PChar(ApplicationDir + 'doc\manual.html'), nil, nil, SW_ShowNormal);
  ShellExecute(Handle, PChar('open'), PChar(RS_MainForm_URL_Manual), nil, nil,
    SW_ShowNormal);
end;

procedure TSlavaNapWindow.Mnu_Help_FaqClick(Sender: TObject);
begin
  // ShellExecute(Handle, PChar('open'), PChar(ApplicationDir + 'doc\faq.html'), nil, nil, SW_ShowNormal);
  ShellExecute(Handle, PChar('open'), PChar(RS_MainForm_URL_FAQ), nil, nil,
    SW_ShowNormal);
end;

procedure TSlavaNapWindow.Mnu_Help_ForumsClick(Sender: TObject);
begin
  ShellExecute(Handle, PChar('open'), PChar(RS_MainForm_URL_Forum), nil, nil,
    SW_ShowNormal);
end;

procedure TSlavaNapWindow.Mnu_Help_WebClick(Sender: TObject);
begin
  ShellExecute(Handle, PChar('open'), PChar(RS_MainForm_URL_Web), nil, nil,
    SW_ShowNormal);
end;

procedure TSlavaNapWindow.Btn_Hotlist_RefreshClick(Sender: TObject);
begin
  if Running then
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTHOTLIST, 0, '', '');
end;

procedure TSlavaNapWindow.Mnu_LogClick(Sender: TObject);
begin
  Mnu_Log_Login.Checked := Log_Login;
  Mnu_Log_Search.Checked := Log_Search;
  Mnu_Log_Browse.Checked := Log_Browse;
  Mnu_Log_Transfers.Checked := Log_Transfers;
  Mnu_Log_Napigator.Checked := Log_Napigator;
  Mnu_Log_Dagsta.Checked := Log_Dagsta;
end;

procedure TSlavaNapWindow.Mnu_L(Sender: TObject);
begin
  Log_Main.Lines.Clear;
  Log_Console.Lines.Clear;
end;

procedure TSlavaNapWindow.Mnu_Log_LoginClick(Sender: TObject);
begin
  Log_Login := not Log_Login;
end;

procedure TSlavaNapWindow.Mnu_Log_SearchClick(Sender: TObject);
begin
  Log_Search := not Log_Search;
end;

procedure TSlavaNapWindow.Mnu_Log_TransfersClick(Sender: TObject);
begin
  Log_Transfers := not Log_Transfers;
end;

procedure TSlavaNapWindow.Mnu_Log_NapigatorClick(Sender: TObject);
begin
  Log_Napigator := not Log_Napigator;
end;

procedure TSlavaNapWindow.Mnu_Log_DagstaClick(Sender: TObject);
begin
  Log_Dagsta := not Log_Dagsta;
end;

procedure TSlavaNapWindow.Mnu_Log_ResetClick(Sender: TObject);
begin
  if Running then
    Cmd_List.AddDoubleCmd(MSG_CMD_RESETLOG, 0, '', '');
end;

procedure TSlavaNapWindow.Btn_Reg_AddClick(Sender: TObject);
begin
  if not Running then Exit;
  if not Check_Name(Edit_Reg_User.Text) then Exit;
  Cmd_List.AddDoubleCmd(MSG_CLIENT_REGISTER_USER, 0, Edit_Reg_User.Text + ' ' +
    AddStr(Edit_Reg_Password.Text) + ' nomail ' +
    IntToStr(Edit_Reg_Level.ItemIndex), '');
  Edit_Reg_User.Text := '';
  Edit_Reg_Password.Text := '';
end;

procedure TSlavaNapWindow.SetBanItems(Control: TComboBox);
begin
  Control.Items.Clear;
  Control.Items.Add(GetLangI(LNG_BANS_TIME60));
  Control.Items.Add(GetLangI(LNG_BANS_TIME300));
  Control.Items.Add(GetLangI(LNG_BANS_TIME600));
  Control.Items.Add(GetLangI(LNG_BANS_TIME1800));
  Control.Items.Add(GetLangI(LNG_BANS_TIME3600));
  Control.Items.Add(GetLangI(LNG_BANS_TIME10800));
  Control.Items.Add(GetLangI(LNG_BANS_TIME43200));
  Control.Items.Add(GetLangI(LNG_BANS_TIME86400));
  Control.Items.Add(GetLangI(LNG_BANS_TIME259200));
  Control.Items.Add(GetLangI(LNG_BANS_TIME604800));
  Control.Items.Add(GetLangI(LNG_BANS_TIME1209600));
  Control.Items.Add(GetLangI(LNG_BANS_TIME2678400));
  Control.ItemIndex := Control.Items.Count - 1;
  Control.Items.Add(GetLangI(LNG_BANS_TIME5184000));
  Control.Items.Add(GetLangI(LNG_BANS_TIME7776000));
  Control.Items.Add(GetLangI(LNG_BANS_TIME31536000));
  Control.Items.Add(RS_BantimeForever);
  Control.DropDownCount := Control.Items.Count;
end;

function TSlavaNapWindow.GetBanID(Control: TComboBox): Integer;
var
  T: Integer;
begin
  case control.ItemIndex of
    0: T := 60;
    1: T := 300;
    2: T := 600;
    3: T := 1800;
    4: T := 3600;
    5: T := 10800;
    6: T := 43200;
    7: T := 86400;
    8: T := 259200;
    9: T := 604800;
    10: T := 1209600;
    11: T := 2678400;
    12: T := 5184000;
    13: T := 7776000;
    14: T := 31536000;
    15: T := 0;
  else
    T := Def_Ban_Timeout;
  end;
  Result := T;
end;

procedure TSlavaNapWindow.Timer3Timer(Sender: TObject);
begin
  if not Running then Exit;
  if Timer3.Tag < MaxInt - 5 then
    Timer3.Tag := Timer3.Tag + 5
  else
    Timer3.Tag := 0;
  if Cb_Users_Refresh.Checked and
    (Pages.ActivePage = Sh_Users) and
    (Timer3.Tag mod Edit_Users_Refresh.Value = 0) then
    Btn_Users_RefreshClick(nil);
  if Cb_Servers_Refresh.Checked and
    (Pages.ActivePage = Sh_Servers) and
    (Timer3.Tag mod Edit_Servers_Refresh.Value = 0) then
    Btn_Servers_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Hotlist_AddClick(Sender: TObject);
begin
  if not Running then Exit;
  if not Check_Name(Edit_Hotlist_User.Text) then Exit;
  Cmd_List.AddDoubleCmd(MSG_CLIENT_ADD_HOTLIST, 0, Edit_Hotlist_User.Text, '');
  Cmd_List.AddDoubleCmd(MSG_CMD_LISTHOTLIST, 0, '', '');
end;

procedure TSlavaNapWindow.Btn_Hotlist_DeleteClick(Sender: TObject);
var
  I: Integer;
begin
  if not Running then Exit;
  if List_Hotlist.SelCount < 1 then Exit;
  for I := 0 to List_Hotlist.Items.Count - 1 do
    if List_Hotlist.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_REMOVE_HOTLIST, 0,
        List_Hotlist.Items.Item[I].Caption, '');
  Cmd_List.AddDoubleCmd(MSG_CMD_LISTHOTLIST, 0, '', '');
end;

procedure TSlavaNapWindow.Mnu_Users_ImClick(Sender: TObject);
begin
  if not Running then Exit;
  if List_Users.SelCount <> 1 then Exit;
  if List_Users.Selected = nil then Exit;
  CreateChatWindow(List_Users.Selected.Caption);
end;

{procedure TSlavaNapWindow.Btn_Users_KickbanClick(Sender: TObject);
var
  I, T: Integer;
begin
  T := GetBanID(Edit_Users_Time);
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
    begin
      Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, List_Users.Items.Item[I].Caption + '!' + List_Users.Items.Item[I].SubItems[UL_IP] + ' ' + IntToStr(T) + ' ' + Edit_Users_Reason.Text, '');
      Cmd_List.AddDoubleCmd(MSG_CLIENT_KILL, 0, List_Users.Items.Item[I].Caption + ' ' + Edit_Users_Reason.Text, '');
    end;
  if List_Users.SelCount > 0 then Btn_Users_RefreshClick(nil);
end;}

procedure TSlavaNapWindow.Btn_Users_KickbanClick(Sender: TObject);
var
  I, T: Integer;
begin
  T := GetBanID(Edit_Users_Time);
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
    begin
      Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, List_Users.Items.Item[I].Caption
        + ' ' + IntToStr(T) + ' ' + Edit_Users_Reason.Text, '');
      Cmd_List.AddDoubleCmd(MSG_CLIENT_KILL, 0, List_Users.Items.Item[I].Caption
        + ' ' + Edit_Users_Reason.Text, '');
    end;
  if List_Users.SelCount > 0 then
    Btn_Users_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Btn_Users_KickbanipClick(Sender: TObject);
var
  I, T: Integer;
begin
  T := GetBanID(Edit_Users_Time);
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
    begin
      // Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0, List_Users.Items.Item[I].SubItems[UL_IP] + ' ' + IntToStr(T) + ' ' + Edit_Users_Reason.Text, '');
      Cmd_List.AddDoubleCmd(MSG_CLIENT_BANEX, 0,
        List_Users.Items.Item[I].SubItems[UL_IP] + ' ' + IntToStr(T) + ' ' +
        List_Users.Items.Item[I].Caption + ': ' + Edit_Users_Reason.Text, '');
      Cmd_List.AddDoubleCmd(MSG_CLIENT_KILL, 0, List_Users.Items.Item[I].Caption
        + ' ' + Edit_Users_Reason.Text, '');
    end;
  if List_Users.SelCount > 0 then
    Btn_Users_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Users_WhoisClick(Sender: TObject);
begin
  if not Running then Exit;
  if List_Users.SelCount < 1 then Exit;
  if List_Users.Selected = nil then Exit;
  Cmd_List.AddDoubleCmd(MSG_CLIENT_WHOIS, 0, List_Users.Selected.Caption, '');
end;

procedure TSlavaNapWindow.Popup_ServersPopup(Sender: TObject);
begin
  case List_Servers.SelCount of
    0:
      begin
        Mnu_Srv_Connect.Enabled := False;
        Mnu_Srv_Disconnect.Enabled := False;
        Mnu_Srv_Delete.Enabled := False;
        Mnu_Srv_Comp.Enabled := False;
        Mnu_Srv_Startup.Enabled := False;
        Mnu_Srv_Props.Enabled := False;
        Mnu_Srv_CopyName.Enabled := False;
      end;
    1:
      begin
        Mnu_Srv_Connect.Enabled := True;
        Mnu_Srv_Disconnect.Enabled := True;
        Mnu_Srv_Delete.Enabled := True;
        Mnu_Srv_Comp.Enabled := True;
        Mnu_Srv_Startup.Enabled := True;
        Mnu_Srv_Props.Enabled := True;
        Mnu_Srv_CopyName.Enabled := True;
      end;
  else
    Mnu_Srv_Connect.Enabled := True;
    Mnu_Srv_Disconnect.Enabled := True;
    Mnu_Srv_Delete.Enabled := True;
    Mnu_Srv_Comp.Enabled := True;
    Mnu_Srv_Startup.Enabled := True;
    Mnu_Srv_Props.Enabled := False;
    Mnu_Srv_CopyName.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Mnu_Srv_CompClick(Sender: TObject);
var
  I, J: Integer;
begin
  if Sender = Mnu_Srv_Comp0 then
    I := 0
  else if Sender = Mnu_Srv_Comp1 then
    I := 1
  else if Sender = Mnu_Srv_Comp2 then
    I := 2
  else if Sender = Mnu_Srv_Comp3 then
    I := 3
  else
    Exit;
  if not Running then Exit;
  if List_Servers.SelCount < 1 then Exit;
  for J := 0 to List_Servers.Items.Count - 1 do
    if List_Servers.Items.Item[J].Selected then
      Cmd_List.AddDoubleCmd(MSG_CMD_SETCOMPRESS, 0,
        List_Servers.Items.Item[J].Caption + ' ' + IntToStr(I), '');
  Btn_Servers_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Srv_StartupClick(Sender: TObject);
var
  I, J: Integer;
begin
  if Sender = Mnu_Srv_Startup0 then
    I := 0
  else if Sender = Mnu_Srv_Startup5 then
    I := 5
  else if Sender = Mnu_Srv_Startup10 then
    I := 10
  else if Sender = Mnu_Srv_Startup15 then
    I := 15
  else if Sender = Mnu_Srv_Startup20 then
    I := 20
  else if Sender = Mnu_Srv_Startup30 then
    I := 30
  else
    Exit;
  I := I * 60000;
  if not Running then Exit;
  if List_Servers.SelCount < 1 then Exit;
  for J := 0 to List_Servers.Items.Count - 1 do
    if List_Servers.Items.Item[J].Selected then
      Cmd_List.AddDoubleCmd(MSG_CMD_SETSTARTUP, 0,
        List_Servers.Items.Item[J].Caption + ' ' + IntToStr(I), '');
  Btn_Servers_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Ban_CopyuserClick(Sender: TObject);
begin
  if List_Bans.SelCount <> 1 then Exit;
  if List_Bans.Selected = nil then Exit;
  Clipboard.AsText := List_Bans.Selected.Caption;
end;

procedure TSlavaNapWindow.Mnu_Ban_CopyipClick(Sender: TObject);
begin
  if List_Bans.SelCount <> 1 then Exit;
  if List_Bans.Selected = nil then Exit;
  Clipboard.AsText := List_Bans.Selected.SubItems[0];
end;

procedure TSlavaNapWindow.Mnu_Ban_CopybanClick(Sender: TObject);
begin
  if List_Bans.SelCount <> 1 then Exit;
  if List_Bans.Selected = nil then Exit;
  Clipboard.AsText := List_Bans.Selected.Caption + '!' +
    List_Bans.Selected.SubItems[0];
end;

procedure TSlavaNapWindow.Mnu_Ban_CopyadminClick(Sender: TObject);
begin
  if List_Bans.SelCount <> 1 then Exit;
  if List_Bans.Selected = nil then Exit;
  Clipboard.AsText := List_Bans.Selected.SubItems[1];
end;

procedure TSlavaNapWindow.Mnu_Ban_CopyreasonClick(Sender: TObject);
begin
  if List_Bans.SelCount <> 1 then Exit;
  if List_Bans.Selected = nil then Exit;
  Clipboard.AsText := List_Bans.Selected.SubItems[7];
end;

procedurE TSlavaNapWindow.Mnu_Ban_SelallClick(Sender: TObject);
var
  I: Integer;
begin
  List_Bans.Items.BeginUpdate;
  for I := 0 to List_Bans.Items.Count - 1 do
    List_Bans.Items.Item[I].Selected := True;
  List_Bans.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Ban_SelnoneClick(Sender: TObject);
var
  I: Integer;
begin
  List_Bans.Items.BeginUpdate;
  for I := 0 to List_Bans.Items.Count - 1 do
    List_Bans.Items.Item[I].Selected := False;
  List_Bans.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Popup_BansPopup(Sender: TObject);
begin
  case List_Bans.SelCount of
    0:
      begin
        Mnu_Ban_Unban.Enabled := False;
        Mnu_Ban_Copyuser.Enabled := False;
        Mnu_Ban_Copyip.Enabled := False;
        Mnu_Ban_Copyban.Enabled := False;
        Mnu_Ban_Copyadmin.Enabled := False;
        Mnu_Ban_Copyreason.Enabled := False;
      end;
    1:
      begin
        Mnu_Ban_Unban.Enabled := True;
        Mnu_Ban_Copyuser.Enabled := True;
        Mnu_Ban_Copyip.Enabled := True;
        Mnu_Ban_Copyban.Enabled := True;
        Mnu_Ban_Copyadmin.Enabled := True;
        Mnu_Ban_Copyreason.Enabled := True;
      end;
  else
    Mnu_Ban_Unban.Enabled := True;
    Mnu_Ban_Copyuser.Enabled := False;
    Mnu_Ban_Copyip.Enabled := False;
    Mnu_Ban_Copyban.Enabled := False;
    Mnu_Ban_Copyadmin.Enabled := False;
    Mnu_Ban_Copyreason.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Mnu_Hotlist_CopyNameClick(Sender: TObject);
begin
  if List_Hotlist.SelCount <> 1 then Exit;
  if List_Hotlist.Selected = nil then Exit;
  Clipboard.AsText := List_Hotlist.Selected.Caption;
end;

procedure TSlavaNapWindow.Mnu_Hotlist_SelnoneClick(Sender: TObject);
var
  I: Integer;
begin
  List_Hotlist.Items.BeginUpdate;
  for I := 0 to List_Hotlist.Items.Count - 1 do
    List_Hotlist.Items.Item[I].Selected := False;
  List_Hotlist.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Hotlist_SelallClick(Sender: TObject);
var
  I: Integer;
begin
  List_Hotlist.Items.BeginUpdate;
  for I := 0 to List_Hotlist.Items.Count - 1 do
    List_Hotlist.Items.Item[I].Selected := True;
  List_Hotlist.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Hotlist_ImClick(Sender: TObject);
begin
  if List_Hotlist.SelCount <> 1 then Exit;
  if List_Hotlist.Selected = nil then Exit;
  CreateChatWindow(List_Hotlist.Selected.Caption);
end;

procedure TSlavaNapWindow.Mnu_Hotlist_WhoisClick(Sender: TObject);
begin
  if List_Hotlist.SelCount <> 1 then Exit;
  if List_Hotlist.Selected = nil then Exit;
  if Running then
    Cmd_List.AddDoubleCmd(MSG_CLIENT_WHOIS, 0, List_Hotlist.Selected.Caption,
      '');
end;

procedure TSlavaNapWindow.Mnu_Hotlist_FriendClick(Sender: TObject);
begin
  if List_Hotlist.SelCount <> 1 then Exit;
  if List_Hotlist.Selected = nil then Exit;
  if Running then
    Cmd_List.AddDoubleCmd(MSG_CLIENT_FRIENDS, 0, 'Add ' +
      List_Hotlist.Selected.Caption, '');
end;

procedure TSlavaNapWindow.Popup_HotlistPopup(Sender: TObject);
begin
  case List_Hotlist.SelCount of
    0:
      begin
        Mnu_Hotlist_Im.Enabled := False;
        Mnu_Hotlist_Whois.Enabled := False;
        Mnu_Hotlist_Friend.Enabled := False;
        Mnu_Hotlist_Delete.Enabled := False;
        Mnu_Hotlist_CopyName.Enabled := False;
      end;
    1:
      begin
        Mnu_Hotlist_Im.Enabled := True;
        Mnu_Hotlist_Whois.Enabled := True;
        Mnu_Hotlist_Friend.Enabled := True;
        Mnu_Hotlist_Delete.Enabled := True;
        Mnu_Hotlist_CopyName.Enabled := True;
      end;
  else
    Mnu_Hotlist_Im.Enabled := False;
    Mnu_Hotlist_Whois.Enabled := False;
    Mnu_Hotlist_Friend.Enabled := False;
    Mnu_Hotlist_Delete.Enabled := True;
    Mnu_Hotlist_CopyName.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Mnu_List_SelallClick(Sender: TObject);
var
  I: Integer;
begin
  List_Lists.Items.BeginUpdate;
  for I := 0 to List_Lists.Items.Count - 1 do
    List_Lists.Items.Item[I].Selected := True;
  List_Lists.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_List_SelnoneClick(Sender: TObject);
var
  I: Integer;
begin
  List_Lists.Items.BeginUpdate;
  for I := 0 to List_Lists.Items.Count - 1 do
    List_Lists.Items.Item[I].Selected := False;
  List_Lists.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_List_CopyClick(Sender: TObject);
begin
  if List_Lists.SelCount <> 1 then Exit;
  if List_Lists.Selected = nil then Exit;
  Clipboard.AsText := List_Lists.Selected.Caption;
end;

procedure TSlavaNapWindow.Popup_IgnoredPopup(Sender: TObject);
begin
  case List_Lists.SelCount of
    0:
      begin
        Mnu_Ignored_Delete.Enabled := False;
        Mnu_Ignored_CopyName.Enabled := False;
      end;
    1:
      begin
        Mnu_Ignored_Delete.Enabled := True;
        Mnu_Ignored_CopyName.Enabled := True;
      end;
  else
    Mnu_Ignored_Delete.Enabled := True;
    Mnu_Ignored_CopyName.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Popup_FriendsPopup(Sender: TObject);
begin
  case List_Lists.SelCount of
    0:
      begin
        Mnu_Fr_Delete.Enabled := False;
        Mnu_Fr_CopyName.Enabled := False;
      end;
    1:
      begin
        Mnu_Fr_Delete.Enabled := True;
        Mnu_Fr_CopyName.Enabled := True;
      end;
  else
    Mnu_Fr_Delete.Enabled := True;
    Mnu_Fr_CopyName.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.Popup_BlocksPopup(Sender: TObject);
begin
  case List_Lists.SelCount of
    0:
      begin
        Mnu_Bl_Delete.Enabled := False;
        Mnu_Bl_CopyName.Enabled := False;
      end;
    1:
      begin
        Mnu_Bl_Delete.Enabled := True;
        Mnu_Bl_CopyName.Enabled := True;
      end;
  else
    Mnu_Bl_Delete.Enabled := True;
    Mnu_Bl_CopyName.Enabled := False;
  end;
end;

procedure TSlavaNapWindow.ToolBarResize(Sender: TObject);
var
  List: TListView;
  L, W: Integer;
  Str: string;
begin
  Tmp_Pos := 1338;
  if Pages.ActivePage = Sh_Log then
  begin
    Lbl_Tb_Selected.Visible := False;
    Exit;
  end;
  if Pages.ActivePage = Sh_Users then
    List := List_Users
  else if Pages.ActivePage = Sh_Registered then
    List := List_Registered
  else if Pages.ActivePage = Sh_Servers then
    List := List_Servers
  else if Pages.ActivePage = Sh_Channels then
    List := List_Channels
  else if Pages.ActivePage = Sh_Bans then
    List := List_Bans
  else if Pages.ActivePage = Sh_List then
    List := List_Lists
  else if Pages.ActivePage = Sh_Hotlist then
    List := List_Hotlist
  else
    List := nil;
  Tmp_Pos := 1339;
  if List = nil then
  begin
    Lbl_Tb_Selected.Visible := False;
    Tmp_Pos := 1340;
    Exit;
  end;
  Str := GetLangI(LNG_TB_TOOLBAR_TOTAL, List.SelCount, List.Items.Count);
  if Lbl_Tb_Selected.Caption <> Str then
    Lbl_Tb_Selected.Caption := Str;
  W := Lbl_Tb_Selected.Width;
  L := Toolbar.Width - W - 5;
  if (Btn_Tb_Blocks.Left + Btn_Tb_Blocks.Width + 5) > L then
  begin
    Lbl_Tb_Selected.Visible := False;
    Tmp_Pos := 1341;
    Exit;
  end;
  Lbl_Tb_Selected.Left := L;
  Lbl_Tb_Selected.Visible := True;
  Tmp_Pos := 1342;
end;

procedure TSlavaNapWindow.ListSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  toolbarResize(nil);
end;

procedure TSlavaNapWindow.Mnu_Help_AboutClick(Sender: TObject);
begin
  SlavaNapAbout.Show;
end;

procedure TSlavaNapWindow.Mnu_Ch_ClearClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Channels.Items.Count - 1 do
    if List_Channels.Items[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_CLEAR_CHANNEL, 0,
        List_Channels.Items[I].Caption + ' ' + Edit_Ch_Reason.Text, '');
  if List_Channels.SelCount > 0 then
    Btn_Ch_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Srv_SelallClick(Sender: TObject);
var
  I: Integer;
begin
  List_Servers.Items.BeginUpdate;
  for I := 0 to List_Servers.Items.Count - 1 do
    List_Servers.Items.Item[I].Selected := True;
  List_Servers.Items.EndUpdate;
end;

procedure TSlavaNapWindow.Mnu_Srv_SelnoneClick(Sender: TObject);
var
  I: Integer;
begin
  List_Servers.Items.BeginUpdate;
  for I := 0 to List_Servers.Items.Count - 1 do
    List_Servers.Items.Item[I].Selected := False;
  List_Servers.Items.EndUpdate;
end;

proCedure TSlavaNapWindow.Mnu_Srv_CopyNameClick(Sender: TObject);
begin
  if List_Servers.SelCount <> 1 then Exit;
  if List_Servers.Selected = nil then Exit;
  Clipboard.AsText := List_Servers.Selected.Caption;
end;

procedure TSlavaNapWindow.Mnu_Ch_ClearbansClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Channels.Items.Count - 1 do
    if List_Channels.Items[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_CHANNEL_CLEAR_BANS, 0,
        List_Channels.Items[I].Caption, '');
  if List_Channels.SelCount > 0 then
    Btn_Ch_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Cb_Log_AwayClick(Sender: TObject);
begin
  Lbl_Log_Away.Visible := Cb_Log_Away.Checked;
  Edit_Log_Away.Visible := Cb_Log_Away.Checked;
  Cb_Log_Awaypopup.Visible := Cb_Log_Away.Checked;
  Cb_Log_Awaypopup.Checked := Cb_Log_Away.Checked;
end;

procedure TSlavaNapWindow.Btn_Log_ModeClick(Sender: TObject);
begin
  Cmd_List.AddDoubleCmd(MSG_CMD_GETMODE, 0, '', '');
  Btn_Log_Mode.Enabled := False;
end;

procedure TSlavaNapWindow.Btn_Users_ModeClick(Sender: TObject);
var
  P: TPoint;
begin
  P.X := 0;
  P.Y := Btn_Users_Mode.Height;
  P := Btn_Users_Mode.ClientToScreen(P);
  Popup_Usersmode.Popup(P.X, P.Y);
end;

function TSlavaNapWindow.IsColumnVisible(List: TListView; N: Integer): Boolean;
begin
  Result := List.Columns.Items[N].Width > 2;
end;

procedure TSlavaNapWindow.SetColumnVisible(List: TListView; N: Integer;
  W: Integer; Auto: Boolean);
begin
  List.Columns.BeginUpdate;
  List.Columns.Items[N].Autosize := Auto;
  List.Columns.Items[N].Width := W;
  List.Columns.EndUpdate;
  List.Height := List.Height - 10;
end;

procedure TSlavaNapWindow.Mnu_Um_Click(Sender: TObject);
var
  N, W: Integer;
  A: Boolean;
begin
  if Sender = Mnu_Um_Level then
    N := UL_LEVEL + 1
  else if Sender = Mnu_Um_Shared then
    N := UL_SHARED + 1
  else if Sender = Mnu_Um_Size then
    N := UL_SIZE + 1
  else if Sender = Mnu_Um_Average then
    N := UL_AVERAGE + 1
  else if Sender = Mnu_Um_Soft then
    N := UL_SOFT + 1
  else if Sender = Mnu_Um_Speed then
    N := UL_SPEED + 1
  else if Sender = Mnu_Um_Ip then
    N := UL_IP + 1
  else if Sender = Mnu_Um_RemoteHost then
    N := UL_REMOTEHOST + 1
  else if Sender = Mnu_Um_Port then
    N := UL_PORT + 1
  else if Sender = Mnu_Um_Time then
    N := UL_TIME + 1
  else if Sender = Mnu_Um_Up then
    N := UL_UP + 1
  else if Sender = Mnu_Um_Down then
    N := UL_DOWN + 1
  else if Sender = Mnu_Um_Transfers then
    N := UL_TRANSFERS + 1
  else if Sender = Mnu_Um_Totalup then
    N := UL_TUP + 1
  else if Sender = Mnu_Um_Totaldown then
    N := UL_TDOWN + 1
  else if Sender = Mnu_Um_Total then
    N := UL_TTRANSFERS + 1
  else if Sender = Mnu_Um_Server then
    N := UL_SERVER + 1
  else if Sender = Mnu_Um_Ulrequests then
    N := UL_ULREQUESTS + 1
  else if Sender = Mnu_Um_Dlrequests then
    N := UL_DLREQUESTS + 1
  else if Sender = Mnu_Um_Searchreqs then
    N := UL_SEARCHREQS + 1
  else if Sender = Mnu_Um_BlockFiles then
    N := UL_BLOCKFILES + 1
  else
    Exit;
  if IsColumnVisible(List_Users, N) then
  begin
    SetColumnVisible(List_Users, N, 0, False);
    Exit;
  end;
  W := 0;
  if Sender = Mnu_Um_Level then
    W := 80
  else if Sender = Mnu_Um_Shared then
    W := 60
  else if Sender = Mnu_Um_Size then
    W := 60
  else if Sender = Mnu_Um_Average then
    W := 60
  else if Sender = Mnu_Um_Soft then
    W := 0
  else if Sender = Mnu_Um_Speed then
    W := 75
  else if Sender = Mnu_Um_Ip then
    W := 80
  else if Sender = Mnu_Um_Port then
    W := 40
  else if Sender = Mnu_Um_Time then
    W := 60
  else if Sender = Mnu_Um_Up then
    W := 30
  else if Sender = Mnu_Um_Down then
    W := 30
  else if Sender = Mnu_Um_Transfers then
    W := 0
  else if Sender = Mnu_Um_Totalup then
    W := 50
  else if Sender = Mnu_Um_Totaldown then
    W := 50
  else if Sender = Mnu_Um_Total then
    W := 0
  else if Sender = Mnu_Um_Server then
    W := 0
  else if Sender = Mnu_Um_Ulrequests then
    W := 30
  else if Sender = Mnu_Um_Dlrequests then
    W := 30
  else if Sender = Mnu_Um_Searchreqs tHen
    W := 40
  else if Sender = Mnu_Um_BlockFiles then
    W := 40;
  if W = 0 then
  begin
    W := 10;
    A := True;
  end
  else
    A := False;
  SetColumnVisible(List_Users, N, W, A);
end;

procedure TSlavaNapWindow.Popup_UsersmodePopup(Sender: TObject);
begin
  Mnu_Um_Level.Checked := IsColumnVisible(List_Users, UL_LEVEL + 1);
  Mnu_Um_Shared.Checked := IsColumnVisible(List_Users, UL_SHARED + 1);
  Mnu_Um_Size.Checked := IsColumnVisible(List_Users, UL_SIZE + 1);
  Mnu_Um_Average.Checked := IsColumnVisible(List_Users, UL_AVERAGE + 1);
  Mnu_Um_Soft.Checked := IsColumnVisible(List_Users, UL_SOFT + 1);
  Mnu_Um_Speed.Checked := IsColumnVisible(List_Users, UL_SPEED + 1);
  Mnu_Um_Ip.Checked := IsColumnVisible(List_Users, UL_IP + 1);
  Mnu_Um_RemoteHost.Checked := IsColumnVisible(List_Users, UL_REMOTEHOST + 1);
  Mnu_Um_Port.Checked := IsColumnVisible(List_Users, UL_PORT + 1);
  Mnu_Um_Time.Checked := IsColumnVisible(List_Users, UL_TIME + 1);
  Mnu_Um_Up.Checked := IsColumnVisible(List_Users, UL_UP + 1);
  Mnu_Um_Down.Checked := IsColumnVisible(List_Users, UL_DOWN + 1);
  Mnu_Um_Transfers.Checked := IsColumnVisible(List_Users, UL_TRANSFERS + 1);
  Mnu_Um_Totalup.Checked := IsColumnVisible(List_Users, UL_TUP + 1);
  Mnu_Um_Totaldown.Checked := IsColumnVisible(List_Users, UL_TDOWN + 1);
  Mnu_Um_Total.Checked := IsColumnVisible(List_Users, UL_TTRANSFERS + 1);
  Mnu_Um_Server.Checked := IsColumnVisible(List_Users, UL_SERVER + 1);
  Mnu_Um_Ulrequests.Checked := IsColumnVisible(List_Users, UL_ULREQUESTS + 1);
  Mnu_Um_Dlrequests.Checked := IsColumnVisible(List_Users, UL_DLREQUESTS + 1);
  Mnu_Um_Searchreqs.Checked := IsColumnVisible(List_Users, UL_SEARCHREQS + 1);
  Mnu_Um_BlockFiles.Checked := IsColumnVisible(List_Users, UL_BLOCKFILES + 1);
end;

procedure TSlavaNapWindow.Btn_Users_RegisterClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Users.Items.Count - 1 do
    if List_Users.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_REGISTER_USER, 0,
        List_Users.Items.Item[I].Caption, '');
end;

procedure TSlavaNapWindow.Mnu_Log_CopyClick(Sender: TObject);
begin
  if Popup_Log.Tag = 1 then
    Log_Main.CopyToClipboard;
  ;
  if Popup_Log.Tag = 2 then
    Log_Console.CopyToClipboard;
end;

procedure TSlavaNapWindow.Btn_Log_PauseClick(Sender: TObject);
begin
  if not PauseLog then
  begin
    Btn_Log_Pause.Caption := GetLangI(LNG_LOG_RESUME);
  end
  else
  begin
    Btn_Log_Pause.Caption := GetLangI(LNG_LOG_PAUSE);
  end;
  PauseLog := not PauseLog;
  Btn_Log_Pause.Width := Canvas.TextWidth(Btn_Log_Pause.Caption) + 20;
end;

procedure TSlavaNapWindow.Btn_Log_ClearClick(Sender: TObject);
begin
  Log_Main.Lines.Clear;
end;

procedure TSlavaNapWindow.Cb_List_SoundClick(Sender: TObject);
begin
  if Cons_List <> consFriends then Exit;
  Friend_Sound := not Friend_Sound;
end;

procedure TSlavaNapWindow.Btn_List_ReloadClick(Sender: TObject);
var
  I: Integer;
  List: TMyStringList;
begin
  if Cons_List <> Cons_List then Exit;
  List := CreateStringList;
  try
    List.LoadFromFile(ApplicationDir + 'block');
  except
    FreeStringList(List);
    Exit;
  end;
  for I := 0 to List.Count - 1 do
    if Length(List.Strings[I]) > 1 then
      if List.Strings[I][1] <> '#' then
        Cmd_List.AddDoubleCmd(MSG_CLIENT_BLOCK, 0,
          AnsiLowerCase(List.Strings[I]), '');
  FreeStringList(List);
  Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
end;

procedure TSlavaNapWindow.Mnu_Log_BrowseClick(Sender: TObject);
begin
  Log_Browse := not Log_Browse;
end;

procedure TSlavaNapWindow.Btn_Reg_UnregisterClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Registered.Items.Count - 1 do
    if List_Registered.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_UNREGISTER, 0,
        List_Registered.Items.Item[I].Caption + ' ' + Edit_Reg_Reason.Text, '');
  if List_Registered.SelCount > 0 then
    Btn_Reg_RefreshClick(nil);
end;

procedure TSlavaNapWindow.Mnu_Reg_UnregisterClick(Sender: TObject);
var
  I: Integer;
begin
  for I := 0 to List_Registered.Items.Count - 1 do
    if List_Registered.Items.Item[I].Selected then
      Cmd_List.AddDoubleCmd(MSG_CLIENT_UNREGISTER, 0,
        List_Registered.Items.Item[I].Caption + ' ' + Edit_Reg_Reason.Text, '');
  if List_Registered.SelCount > 0 then
    Btn_Reg_RefreshClick(nil);

end;

procedure TSlavaNapWindow.Mnu_Users_BrowseClick(Sender: TObject);
var
  Item: TListItem;
  I: Integer;
  Form: TSlavaNapBrowseWindow;
begin
  if not Running then Exit;
  Item := List_Users.Selected;
  while Item <> nil do
  begin
    if Cons_Browse <> nil then
      for I := 0 to Cons_Browse.Count - 1 do
      begin
        Form := TSlavaNapBrowseWindow(Cons_Browse.Items[I]);
        if AnsiLowerCase(Form.User) = AnsiLowerCase(Item.Caption) then
        begin
          Form.List.Clear;
          Form.Shared := 0;
          Form.Size := 0;
        end;
      end;
    Cmd_List.AddDoubleCmd(MSG_CLIENT_BROWSE, 0, Item.Caption, '');
    Item := List_Users.GetNextItem(Item, sdAll, [IsSelected]);
  end;
end;

function TSlavaNapWindow.CreateBrowseWindow(User: string):
  TSlavaNapBrowseWindow;
var
  I: Integer;
  Form: TSlavaNapBrowseWindow;
begin
  Result := nil;
  if not Running then Exit;
  if Cons_Browse = nil then Exit;
  for I := 0 to Cons_Browse.Count - 1 do
    if AnsiLowerCase(TSlavaNapBrowseWindow(Cons_Browse.Items[I]).User) =
      AnsiLowerCase(User) then
    begin
      Result := Cons_Browse.Items[I];
      Exit;
    end;
  Form := TSlavaNapBrowseWindow.Create(Self);
  Cons_Browse.Add(Form);
  Form.User := User;
  Result := Form;
end;

procedure TSlavaNapWindow.Mnu_Users_AnnounceClick(Sender: TObject);
var
  Users: TStringList;
  Item: TListItem;
begin
  if not Running then Exit;
  if List_Users.Selected = nil then Exit;
  Users := TStringList.Create; // 開放はフォームの破棄のときにする
  Item := List_Users.Selected;
  while Item <> nil do
  begin
    Users.Add(Item.Caption);
    Item := List_Users.GetNextItem(Item, sdAll, [IsSelected]);
  end;
  CreateAnnounceWindow(Users);
end;

function TSlavaNapWindow.CreateAnnounceWindow(Users: TStringList):
  TSlavaNapAnnounceWindow;
var
  Form: TSlavaNapAnnounceWindow;
begin
  Result := nil;
  if not Running then Exit;
  Form := TSlavaNapAnnounceWindow.Create(Self);
  Form.Users := Users;
  Form.Caption := RS_AnnounceForm_Caption;
  try
    Form.Show;
    Form.Edit.SetFocus;
  except
  end;
  Result := Form;
end;

procedure TSlavaNapWindow.Cb_Users_RefreshClick(Sender: TObject);
begin
  Edit_Users_Refresh.Visible := Cb_Users_Refresh.Checked;
  Lbl_Users_Refresh.Visible := Cb_Users_Refresh.Checked;
end;

procedure TSlavaNapWindow.Cb_Servers_RefreshClick(Sender: TObject);
begin
  Edit_Servers_Refresh.Visible := Cb_Servers_Refresh.Checked;
  Lbl_Servers_Refresh.Visible := Cb_Servers_Refresh.Checked;
end;

procedure TSlavaNapWindow.CMShowingChanged(var Msg: TMessage);
var
  I: Integer;
begin
  inherited;

  if Visible and not Running then
  begin
    Update;

    LogStartup('MainForm::Create: Resetting sockets');
    for I := 0 to MAX_LISTEN_SOCKET do
    begin
      Server_Port[I] := 0;
      Server_Socket[I] := INVALID_SOCKET;
    end;
    for I := 0 to MAX_LISTEN_TRAPSOCKET do
    begin
      Trap_Port[I] := 0;
      Trap_Socket[I] := INVALID_SOCKET;
    end;
    Napigator_Socket := INVALID_SOCKET;
    Dagsta_Socket := INVALID_SOCKET;
    Stats_Socket := INVALID_SOCKET;
    Server_Port[0] := DEF_LISTEN_PORT;
    LogStartup('MainForm::Create: Clearing log');
    Log_Main.Lines.Clear;
    MainThread := nil;
    LogStartup('MainForm::Create: Creating main lists');
    Sync_Reply_List := TNapDoubleCmdList.Create;
    Cmd_List := TNapDoubleCmdList.Create;
    Debug_File := nil;
    DB_Online := TOnlineUsers.Create;
    DB_Local := TMyList.Create;
    DB_Servers := TMyList.Create;
    LogStartup('MainForm::Create: Loading servers list');
    LoadServers;
    DB_Channels := TMyList.Create;
    DB_Registered := TRegUserDataBase.Create;
    LogStartup('MainForm::Create: Loading registered users');
    DB_Registered.LoadFromFile(ApplicationDir + 'users');
    DB_Bans := TBanList.Create;
    LogStartup('MainForm::Create: Loading bans');
    DB_Bans.LoadFromFile(ApplicationDir + 'bans');
    LogStartup('MainForm::Create: Loading MOTD');
    StrHash_Reset(DB_Motd);
    StrHash_LoadFromFile(DB_Motd, ApplicationDir + 'motd');
    LogStartup('MainForm::Create: Loading friends list');
    StrHash_Reset(DB_Friends);
    StrHash_LoadFromFile(DB_Friends, ApplicationDir + 'friends');
    DB_Software := TNapCmd2List.Create;
    LogStartup('MainForm::Create: Loading clientstats');
    try
      DB_Software.LoadFromFile(ApplicationDir + 'clientstats', Cmd2ID2CRCLC);
    except
    end;
    LogStartup('MainForm::Create: Creating other lists...');
    DB_Invitations := TNapCmdExList.Create;
    DB_Whowas := TNapCmdExList.Create;
    DB_Reconnect := TMyStringList.Create;
    DB_Reconnect.Duplicates := Classes2.dupIgnore;
    DB_Reconnect.Sorted := True;
    DB_Login := TMyList.Create;
    Null_Password := Null_Pass;
    Local_Users := 0;
    Total_Users := 0;
    Local_Users_Max := 0;
    Total_Users_Max := 0;
    Total_Users_Limit := 0;
    Local_Files := 0;
    Total_Files := 0;
    Total_Files_Max := 0;
    Local_Files_Max := 0;
    Local_Bytes := 0;
    Total_Bytes := 0;
    Local_Bytes_Max := 0;
    Total_Bytes_Max := 0;
    Total_Connections := 0;
    Bytes_in := 0;
    Bytes_Out := 0;
    Total_Bytes_in := 0;
    Total_Bytes_Out := 0;
    Last_Bytes_in := 0;
    Last_Bytes_Out := 0;
    Total_Searches := 0;
    Num_Searches := 0;
    Last_Searches := 0;
    Successful_Searches := 0;
    Total_Search_Results := 0;
    Total_Transfers := 0;
    Num_Transfers := 0;
    Last_Transfers := 0;
    Total_Browses := 0;
    Num_Browses := 0;
    Last_Browses := 0;
    Total_Browse_Results := 0;
    Num_Login := 0;
    Last_Login := 0;
    Last_Rejects := 0;
    Num_Rejects := 0;
    Num_Servers := 0;
    Napigator_Socket := INVALID_SOCKET;
    Napigator_Salt := '';
    Dagsta_Socket := INVALID_SOCKET;
    Dagsta_Salt := '';

    // Load config
    // LogStartup('MainForm::Create: Loading english.msg and english.lng');
    // LoadLanguage('english');
    LogStartup('MainForm::Create: LoadConfig;');
    LoadConfig(lmRest);
    LogStartup('MainForm::Create: Loading channels');
    LoadChannels(ApplicationDir + 'channels');
    LogStartup('MainForm::Create: ChangeInterface;');
    ChangeInterface(lmRest);
    LogStartup('MainForm::Create: LogMain...');
    LogMain(slText, GetLangI(LNG_LOG_STARTING, SLAVANAP_FULL));
{$IFDEF TEST_VERSION}
    LogMain(clRed, '-----');
    LogMain(clRed, RS_MainForm_TestVersion0);
    LogMain(clRed, RS_MainForm_TestVersion1);
    LogMain(clRed, '-----');
{$ENDIF}
    LogStartup('MainForm::Create: Refreshing lists');
    Cmd_List.AddDoubleCmd(MSG_CMD_LIStrEGISTERED, 0, '', '');
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTUSERS, 0, '', '');
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTSERVERS, 0, '', '');
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTCHANNELS, 0, '', '');
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTBANS, 0, '', '');
    Cmd_List.AddDoubleCmd(MSG_CMD_LISTHOTLIST, 0, '', '');
    Cmd_List.AddDoubleCmd(MSG_CMD_REFRESHLISTS, 0, '0', '');
    LogStartup('MainForm::Create: Activating timer');
    Timer1Timer(nil);
    Running := True;
    Start_Time := GetTickCount;
    Start_Time_T := GetTickCountT;
    LogStartup('MainForm::Create: Creating main Thread');
    MainThread := TMainThread.Create;
    LogStartup('MainForm::Create: RUNNING !!!!!');
  end;
end;

end.
