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

 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;

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');
 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');
 list:=TMyStringList.Create;
 try
  // 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;

  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','理由なし');
  edit_reg_reason.Text:=ini.ReadString('Interface','RegReason','理由なし');
  edit_ch_reason.Text:=ini.ReadString('Interface','ChReason','理由なし');
  edit_ban_reason.Text:=ini.ReadString('Interface','BanReason','理由なし');
  edit_unban_reason.Text:=ini.ReadString('Interface','UnBanReason','理由なし');
  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','(自動応答)ただいま近くにおりません。IMありがとう');
  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','ChangeThis');
  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','mp2 mp3 mpga ogg vqf wma');
  ext_audio:=ini.ReadString('Share','Audio Extensions','wav mid midi voc mod ra ram rmp rm');
  ext_video:=ini.ReadString('Share','Video Extensions','mpeg mpg mpe avi asf mov fli flc lsf wm wmv qt viv vivo movie divx');
  ext_text:=ini.ReadString('Share','Text Extensions','txt pdf doc wri mcw rtf wps ps xls xlw');
  ext_image:=ini.ReadString('Share','Image Extensions','gif png jpg jpe jpeg psd tga bmp fla swf tif tiff pcx');
  ext_app:=ini.ReadString('Share','App Extensions','exe zip rar ace rpm gz tgz tar hqx sit msi');
  ext_cd:=ini.ReadString('Share','CD Extensions','iso bin cif nrg ccd cue img sub cdi cda rip udf');
  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','サーバーの限界に達しました : $users$人のユーザーがオンライン');
  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','AnnouncementsBot');
  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','.zip.avi .zip.mpg');
  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','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','#Alternative');
  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','Admin');
  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
  ini.Free;
 end;
 list.Free;
 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);
   // 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:='参照(&O)';
 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:='共有ファイルサイズ(Mb)を表示';
 mnu_um_average.Caption:='平均ファイルサイズ(Mb)を表示';
 mnu_um_speed.Caption:=GetLangI(LNG_LIST_MNU2_SPEED);
 mnu_um_ip.Caption:=GetLangI(LNG_LIST_MNU2_IP);
 mnu_um_remotehost.Caption:='リモートホストを表示';
 mnu_um_port.Caption:=GetLangI(LNG_LIST_MNU2_PORT);
 mnu_um_time.Caption:=GetLangI(LNG_LIST_MNU2_TIME);
 mnu_um_up.Caption:='アップロード数を表示';
 mnu_um_down.Caption:='ダウンロード数を表示';
 mnu_um_transfers.Caption:=GetLangI(LNG_LIST_MNU2_TRANSFERS);
 mnu_um_totalup.Caption:='アップロードの合計を表示';
 mnu_um_totaldown.Caption:='ダウンロードの合計を表示';
 mnu_um_total.Caption:=GetLangI(LNG_LIST_MNU2_TOTAL);
 mnu_um_server.Caption:=GetLangI(LNG_LIST_MNU2_SERVER);
 mnu_um_ulrequests.Caption:='アップロード要求の合計を表示';
 mnu_um_dlrequests.Caption:='ダウンロード要求の合計を表示';
 mnu_um_searchreqs.Caption:='検索要求の合計を表示';
 mnu_um_blockfiles.Caption:='ブロックされたファイルの合計を表示';

 // 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:='サイズ(Mb)';
   Items[UL_AVERAGE+1].Caption:='平均サイズ(Mb)';
   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:='リモートホスト';
   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:='UL';
   Items[UL_DOWN+1].Caption:='DL';
   Items[UL_TRANSFERS+1].Caption:=GetLangI(LNG_LIST_HEADER_TRANSFERS);
   Items[UL_TUP+1].Caption:='合計UL';
   Items[UL_TDOWN+1].Caption:='合計DL';
   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:='UL要求';
   Items[UL_DLREQUESTS+1].Caption:='DL要求';
   Items[UL_SEARCHREQS+1].Caption:='検索要求';
   Items[UL_BLOCKFILES+1].Caption:='ﾌﾞﾛｯｸﾌｧｲﾙ';
   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:='理由なし';
 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('http://www.slavanap.org/manual.html'),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('http://www.slavanap.org/faq.html'),nil,nil,SW_ShowNormal);
end;

procedure TSlavaNapWindow.mnu_help_forumsClick(Sender: TObject);
begin
 ShellExecute(Handle,PChar('open'),PChar('http://www.slavanap.org/phpbb/'),nil,nil,SW_ShowNormal);
end;

procedure TSlavaNapWindow.mnu_help_webClick(Sender: TObject);
begin
 ShellExecute(Handle,PChar('open'),PChar('http://www.slavanap.org/'),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('無期限');
 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:='個別アナウンス';
 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,'This is a test version.');
    LogMain(clRed,'Some features are disabled or not implemented yet.');
    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.
