unit UMainWindow;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, cTCPClient, cTCPServer, cWindows, cSockets, cUtils,
  cSocketsUDP, ImgList, Menus, CoolTrayIcon, ToolWin,
  ActnMan, ActnCtrls, ActnMenus, ActnList, XPStyleActnCtrls, ComCtrls,
  ExtCtrls, cWinSock, UAutoRegistry, Registry, CustomizeDlg, MPlayer,
  StdActns, ULogExceptions, RVScroll, RichView, RVStyle, UTextFileStream,
  ShellAPI, SunriseChatCoreUnit, SunriseChatNetworkCoreUnit, IdBaseComponent,
  IdComponent, IdUDPBase, IdUDPServer, XPMan, IdUDPClient, IdCustomTCPServer,
  IdTCPServer, IdTCPConnection, IdTCPClient, IdAntiFreezeBase, IdAntiFreeze;

const
  ApplicationName = 'SunriseChat';
  Author = 'Jiří Hajda';
  HomePage = 'http://www.zdechov.net/sunrisechat/';
  Email = 'robie@centrum.cz';
  ClientVersion = '3.0';
  ClientReleaseDate = '11.2.2008';
  OfflineTimeout = 13/24/3600;   // 13 seconds
  Creator = 'Chronosoft';
  RegistryPath = '\Software\' + Creator + '\SunriseChat';
  ChangeLogFile = 'Novinky.txt';
  Licence = 'Copyleft';
  HttpHeader = 'http://';
  ShareHeader = '\\';

type
  TAppEventTextColor = record
    Color: Integer;
    Charset: Integer;
    Style: string;
    Size: Integer;
    Name: string;
  end;

  TAppEvent = record
    // Actions
    EventName: string;
    ShowWindow: Boolean;
    ShowBalloonHint: Boolean;
    PlaySound: Boolean;
    ShowAlertIcon: Boolean;
    IconFile: string;
    PlayBeep: Boolean;
    SoundFile: string;
    ExecuteApplication: Boolean;
    ApplicationFile: string;
    ShowMessage: Boolean;
    MessageText: string;
    MessageFont: TFont;
    MessageFontTemp: TAppEventTextColor;
  end;

  TAppUserEvent = record
    // Conditions
    ConditionTextEnable: Boolean;
    ConditionText: string;
    ConditionUserEnable: Boolean;
    ConditionUser: string;
    ConditionAppEventEnable: Boolean;
    ConditionAppEvent: Integer;

    // Actions
    EventName: string;
    ShowWindow: Boolean;
    ShowBalloonHint: Boolean;
    PlaySound: Boolean;
    ShowAlertIcon: Boolean;
    IconFile: string;
    PlayBeep: Boolean;
    SoundFile: string;
    ExecuteApplication: Boolean;
    ApplicationFile: string;
    ShowImage: Boolean;
    ImageFile: string;
    Image: TImage;
  end;

  TEventOption = (eoShowWindow, eoShowBalloonHint, eoShowAlertIcon, eoPlayBeep,
    eoShowMessage);
  TEventOptions = set of TEventOption;

  TMainWindow = class(TForm)
    Panel3: TPanel;
    Panel4: TPanel;
    Button1: TButton;
    ActionManager1: TActionManager;
    ActionOptions: TAction;
    ActionInfo: TAction;
    ActionAbout: TAction;
    ActionStatus: TAction;
    ActionClose: TAction;
    ActionRestore: TAction;
    ActionOnline: TAction;
    ActionAway: TAction;
    ActionInvisible: TAction;
    ActionTestResponse: TAction;
    ActionBlockIP: TAction;
    ActionCallUp: TAction;
    CoolTrayIcon1: TCoolTrayIcon;
    PopupMenu2: TPopupMenu;
    Blokovatadresu1: TMenuItem;
    estodezvy1: TMenuItem;
    Vzva1: TMenuItem;
    PopupMenu1: TPopupMenu;
    Obnovit1: TMenuItem;
    Informace1: TMenuItem;
    Nastaven2: TMenuItem;
    Oprogramu2: TMenuItem;
    Ukonit1: TMenuItem;
    ImageList1: TImageList;
    Timer1: TTimer;
    ActionUserRoom: TAction;
    ActionLogCommand: TAction;
    PopupMenu3: TPopupMenu;
    Odejtzmstnosti1: TMenuItem;
    CustomizeDlg1: TCustomizeDlg;
    ActionCustomizeDlg: TAction;
    PopupMenu4: TPopupMenu;
    Pedchozzprva1: TMenuItem;
    Doplnitjmno1: TMenuItem;
    MainMenu1: TMainMenu;
    Status1: TMenuItem;
    Online1: TMenuItem;
    Pry1: TMenuItem;
    Neviditeln1: TMenuItem;
    Nastaven1: TMenuItem;
    Informace2: TMenuItem;
    Status2: TMenuItem;
    Online2: TMenuItem;
    Pry2: TMenuItem;
    Neviditeln2: TMenuItem;
    ActionNetworkTest: TAction;
    estst1: TMenuItem;
    Panel5: TPanel;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    ToolButton4: TToolButton;
    ToolButton5: TToolButton;
    ToolButton7: TToolButton;
    Panel2: TPanel;
    Label1: TLabel;
    ListView1: TListView;
    Splitter3: TSplitter;
    Panel1: TPanel;
    Label2: TLabel;
    MediaPlayer1: TMediaPlayer;
    Vytvoitmstnost1: TMenuItem;
    ActionCreateRoom: TAction;
    Vytvoitmstnost2: TMenuItem;
    SearchFind1: TSearchFind;
    PopupMenu5: TPopupMenu;
    Find1: TMenuItem;
    Vymazatve1: TMenuItem;
    ActionClearMessageList: TAction;
    ComboBox1: TComboBox;
    N1: TMenuItem;
    Novinky1: TMenuItem;
    ActionChangeLog: TAction;
    Oprogramu1: TMenuItem;
    RVStyle1: TRVStyle;
    Panel6: TPanel;
    RichView1: TRichView;
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    Pozvatuivateledomstnosti1: TMenuItem;
    ActionUserEventsList: TAction;
    Nabdkauivatelskchudlost1: TMenuItem;
    ToolButton6: TToolButton;
    ListView2: TListView;
    Koprovar1: TMenuItem;
    Vloit1: TMenuItem;
    Vloitsovodkaz1: TMenuItem;
    OpenDialog1: TOpenDialog;
    XPManifest1: TXPManifest;
    Log1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Vloitsovodkaz1Click(Sender: TObject);
    procedure RichView1Jump(Sender: TObject; id: Integer);
    procedure Vloit1Click(Sender: TObject);
    procedure Koprovar1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure ComboBox1KeyPress(Sender: TObject; var Key: Char);
    procedure ComboBox1KeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure ActionInfoExecute(Sender: TObject);
    procedure ActionAwayExecute(Sender: TObject);
    procedure ActionOnlineExecute(Sender: TObject);
    procedure ActionCloseExecute(Sender: TObject);
    procedure ListView1Click(Sender: TObject);
    procedure ActionTestResponseExecute(Sender: TObject);
    procedure ActionRestoreExecute(Sender: TObject);
    procedure ActionInvisibleExecute(Sender: TObject);
    procedure ActionAboutExecute(Sender: TObject);
    procedure ActionOptionsExecute(Sender: TObject);
    procedure ActionCallUpExecute(Sender: TObject);
    procedure TabControl1Change(Sender: TObject);
    procedure ActionBlockIPExecute(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure ActionUserRoomExecute(Sender: TObject);
    procedure Odejtzmstnosti1Click(Sender: TObject);
    procedure ActionCustomizeDlgExecute(Sender: TObject);
    procedure PopupMenu2Popup(Sender: TObject);
    procedure Pedchozzprva1Click(Sender: TObject);
//    procedure Doplnitjmno1Click(Sender: TObject);
    procedure ActionNetworkTestExecute(Sender: TObject);
    procedure ToolButton7Click(Sender: TObject);
    procedure CoolTrayIcon1Click(Sender: TObject);
    procedure ToolButton1Click(Sender: TObject);
    procedure ToolButton3Click(Sender: TObject);
    procedure ToolButton2Click(Sender: TObject);
    procedure ToolButton5Click(Sender: TObject);
    procedure ToolButton4Click(Sender: TObject);
    procedure RichEdit1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ListView1InfoTip(Sender: TObject; Item: TListItem;
      var InfoTip: String);
    procedure ActionCreateRoomExecute(Sender: TObject);
    procedure Doplnitjmno1Click(Sender: TObject);
    procedure SearchFind1FindDialogFind(Sender: TObject);
    procedure SearchFind1BeforeExecute(Sender: TObject);
    procedure ActionClearMessageListExecute(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
    procedure ActionChangeLogExecute(Sender: TObject);
    procedure ComboBox1DropDown(Sender: TObject);
    procedure ComboBox1CloseUp(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure ActionUserEventsListExecute(Sender: TObject);
    procedure ToolButton6Click(Sender: TObject);
    procedure Panel6Resize(Sender: TObject);
    procedure SunriseChatNetworkCore1RoomListChanged;
    procedure SunriseChatNetworkCore1UserListUpdate;
    procedure SunriseChatNetworkCore1AddMessage(EventType: TAppEventType;
      Room: TRoom; const Args: array of TVarRec; RoomLine: TRoomLine);
    procedure FormDestroy(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Log1Click(Sender: TObject);
  private
    CloseEnabled: Boolean;
    UserLastText: string;
    procedure WMQueryEndSession(var Message: TMessage); message WM_QUERYENDSESSION;
    procedure AppMessage(var Msg: TMsg; var Handled: Boolean);
    procedure ChangeNetworkState;
    procedure CallUp;
    procedure lComboBox1Change(Sender: TObject);
    { Private declarations }
  public
    SunriseChatNetworkCore1: TSunriseChatNetworkCore;
    UserEventsImagesEnabled: Boolean;
    FirstStart: Boolean;
    LastRichViewStyle: Integer;
    MaxNumberOfRoomLines: Integer;
    AppEvents: array of TAppEvent;
    AppUserEvents: array of TAppUserEvent;
    AppEventsInit: array of TAppEvent;
    Options: TAutoRegistry;
    AppEventsOptions: array of TAutoRegistry;
    AppUserEventsOptions: array of TAutoRegistry;
    NetworkPort: Integer;
    NetworkInterface: string;
    PingTimeout: Integer;
    MinimizeToTray: Boolean;
    StartInTray: Boolean;
    RunOnLogon: Boolean;
    LastText: string;
    OnTop: Boolean;
    ShowOnMessage: Boolean;
    PositionX, PositionY, SizeX, SizeY: Integer;
    LastWindowState: Integer;
    AlphaBlendWindow: Integer;
    UserListWidth: Integer;
    ShowMessageTime: Boolean;
    ShowMainMenu: Boolean;
    InstanceIndex: Integer;
    ShowBallonHint: Boolean;
    NoResloveHostName: Boolean;
    MinimalizeOnCloseWindow: Boolean;
    DefaultReason: string;
    ServiceFunction: Boolean;
    ShowRightToolBar: Boolean;
    PauseScrollText: Boolean;
    OneAppInstance: Boolean;
    WM_SunriseChatStart: Cardinal;
    WM_SunriseChatClose: Cardinal;
    NoSaveToRegistry: Boolean;
    SoundDisable: Boolean;
    StopProgram: Boolean;
    SnapWindow: Boolean;
    InvisibledOnStart: Boolean;
    AutoChangeWindowHeight: Boolean;
    AutoChangeWindowHeightDirectionDown: Boolean;
    MinimumVisibleUsersCount: Integer;
    SoundVolume: Integer;
    LanguageIndex: Integer;
    SettingsName: string;
    AutoChangeInfoWindowHeight: Boolean;
    AppUserEventsCount: Integer;
    HyperLinks: array of string;
    BroadcastTypeI: Integer;
    UserNick: string;
    UsersAutoAwayDelay: Integer;
    procedure RoomListChanged;
    procedure InitTrayIcon;
    procedure ChangeRunOnLogon;
    procedure ScrollDownRichEdit1;
    procedure DoplnitJmeno;
    procedure AddEvent(Name, Text: string; Options: TEventOptions);
    procedure SaveAppEventsToRegistry;
    procedure LoadAppEventsFromRegistry;
    procedure SaveAppUserEventsToRegistry;
    procedure LoadAppUserEventsFromRegistry(UpdateOnly: Boolean = False);
    procedure RefreshAppTitle;
    procedure InitSettings;
    procedure FillComboBox;
    procedure ShowUserList;
    procedure ReloadImages;
  end;

procedure MPSetVolume(MP: TMediaPlayer; Volume: Integer) ;
function MPGetVolume(MP: TMediaPlayer): Integer;

var
  MainWindow: TMainWindow;

implementation

uses UInfoWindow, UAboutWindow, UOptionsWindow, UNetworkTest, UNewRoom,
  DateUtils, ULocalization, UJobProgressView, MMSystem, UProtocolMessageLog;

{$R *.dfm}

const
   MCI_SETAUDIO = $0873;
   MCI_DGV_SETAUDIO_VOLUME = $4002;
   MCI_DGV_SETAUDIO_ITEM = $00800000;
   MCI_DGV_SETAUDIO_VALUE = $01000000;
   MCI_DGV_STATUS_VOLUME = $4019;
type
   MCI_DGV_SETAUDIO_PARMS = record
     dwCallback: DWORD;
     dwItem: DWORD;
     dwValue: DWORD;
     dwOver: DWORD;
     lpstrAlgorithm: PChar;
     lpstrQuality: PChar;
   end;
type
   MCI_STATUS_PARMS = record
     dwCallback: DWORD;
     dwReturn: DWORD;
     dwItem: DWORD;
     dwTrack: DWORD;
   end;

{Set Volume, range 0 - 1000}
procedure MPSetVolume(MP: TMediaPlayer; Volume: Integer) ;
var
   p: MCI_DGV_SETAUDIO_PARMS;
begin
   p.dwCallback := 0;
   p.dwItem := MCI_DGV_SETAUDIO_VOLUME;
   p.dwValue := Volume;
   p.dwOver := 0;
   p.lpstrAlgorithm := nil;
   p.lpstrQuality := nil;
   mciSendCommand(MP.DeviceID, MCI_SETAUDIO, MCI_DGV_SETAUDIO_VALUE or MCI_DGV_SETAUDIO_ITEM, Cardinal(@p)) ;
end;

{Get Volume, range 0 - 1000}
function MPGetVolume(MP: TMediaPlayer): Integer;
var
   p: MCI_STATUS_PARMS;
begin
   p.dwCallback := 0;
   p.dwItem := MCI_DGV_STATUS_VOLUME;
   mciSendCommand(MP.DeviceID, MCI_STATUS, MCI_STATUS_ITEM, Cardinal(@p)) ;
   Result := p.dwReturn;
end;

procedure SwitchToThisWindow(h1: hWnd; x: bool); stdcall; external user32 Name 'SwitchToThisWindow';

procedure TMainWindow.FormCreate(Sender: TObject);
const
  Separator = '|';
var
  Row: string;
  FileName: string;
  I: Integer;
begin
  SunriseChatNetworkCore1 := TSunriseChatNetworkCore.Create(Self);
  with SunriseChatNetworkCore1 do begin
    UdpPort := 55557;
    UseDefaultEventsText := True;
    AutoAwayDelay := 5;
    AutoReconnect := True;
    BroadcastType := btLocal;
    MaxRoomLines := 100;
  end;


  SettingsName := '';
  // Process application parameters
  for I := 0 to ParamCount do begin
    //ShowMessage(ParamStr(I));
    if Copy(ParamStr(I), 1, 3) = '/s:' then SettingsName := Copy(ParamStr(I), 4, 255);
  end;
  if SettingsName = '' then SettingsName := 'Default';

  with SunriseChatNetworkCore1 do begin
    OnChangeNetworkState := ChangeNetworkState;
    OnAddMessage := SunriseChatNetworkCore1AddMessage;
    OnUserListUpdate := ShowUserList;
    OnRoomListChanged := RoomListChanged;
  end;

  Options := TAutoRegistry.Create(RegistryPath + '\' + SettingsName);
  with Options, SunriseChatNetworkCore1 do begin
    InitSettings;
    if FirstStart then begin
      FileName := ExtractFileDir(Application.ExeName) + '\' + SmileysDefFile;
      if FileExists(FileName) then begin
        with TTextFileStream.Create(FileName, fmOpenRead) do try
          repeat
            Row := Trim(ReadLn);
            if Row <> '' then begin
              SetLength(AppUserEvents, Length(AppUserEvents)+1);
              with AppUserEvents[High(AppUserEvents)] do begin
                EventName := Copy(Row, 1, Pos(Separator, Row)-1);
                ConditionTextEnable := True;
                ConditionText := EventName;
                ShowImage := True;
                ImageFile := ExtractFileDir(FileName) + '\' + Copy(Row, Pos(Separator, Row)+1, Length(Row));
              end;
            end;
          until Position = Size;
        finally
          Free;
        end;
        SetLength(AppUserEventsOptions,Length(AppUserEvents));
        AppUserEventsCount:= Length(AppUserEvents);
        LoadAppUserEventsFromRegistry(True);
        SaveAppUserEventsToRegistry;
        ReloadImages;
      end;
    end;

    // Check multiple application instance
    WM_SunriseChatStart := RegisterWindowMessage('SunriseChatStart');
    WM_SunriseChatClose := RegisterWindowMessage('SunriseChatClose');
    Application.OnMessage := AppMessage;
    PostMessage(HWND_BROADCAST, WM_SunriseChatStart, Application.Handle, 0);
    for I := 0 to 10 do begin
      Sleep(1);
      Application.ProcessMessages;
      if StopProgram then Break;
    end;
    if StopProgram then begin
      Application.Terminate;
      Exit;
    end;
  end;

  // Local user initialization
  with SunriseChatNetworkCore1.LocalUser do begin
    Client := ApplicationName;
    Application.Title := ApplicationName;
  end;
  SunriseChatNetworkCore1.LocalUser.ClientVersion := ClientVersion;
  SunriseChatNetworkCore1.UDPPort := NetworkPort;
  SunriseChatNetworkCore1.SelectNetworkInterfaceByGUID(NetworkInterface);
//  SunriseChatCore.Init;
  RoomListChanged;
//  if FileExists(CustomizeFile) then ActionManager1.LoadFromFile(CustomizeFile);
  RefreshAppTitle;
  SunriseChatNetworkCore1.Active := True;
  SunriseChatNetworkCore1.AutoReconnect := True;
end;

procedure TMainWindow.InitTrayIcon;
begin
  CoolTrayIcon1.MinimizeToTray:= MinimizeToTray;
  CoolTrayIcon1.IconIndex:= 5;
  CoolTrayIcon1.IconVisible:= True; //MinimizeToTray;
  if OnTop then FormStyle:= fsStayOnTop else FormStyle:= fsNormal;

  if MinimizeToTray then CoolTrayIcon1.HideTaskbarIcon
  else CoolTrayIcon1.ShowTaskbarIcon;

  // Hide MainForm at startup.
  if StartInTray then Application.ShowMainForm:= False;
end;

procedure TMainWindow.Koprovar1Click(Sender: TObject);
begin
  RichView1.CopyText;
  //SendMessage(RichView1.Handle, WM_COPY, 0, 0);
end;

procedure TMainWindow.SunriseChatNetworkCore1AddMessage(
  EventType: TAppEventType; Room: TRoom; const Args: array of TVarRec;
  RoomLine: TRoomLine);
var
  ForUser, ForUser2, MessageTime: string;
  Icon: TIcon;
  RichViewStyle: Integer;
  I, II: Integer;
  MessageTextTemp: string;
  TextStart, TextEnd: Integer;
  TemporaryText: string;
  UserNick: string;
begin
  case EventType of
    aeUserChangeNick: RefreshAppTitle;
    aeCommonMessage, aeOneUserMessage: UserNick := string(Args[1].VPChar);
  end;

  // Format text line
  try
    RoomLine.Text := Format(AppEvents[Integer(EventType)].MessageText, Args);
  except
    ShowMessage('Chyba ve zprávě pro událost '+AppEvents[Integer(EventType)].EventName+'!');
  end;

  with AppEvents[Integer(EventType)] do begin
    if ShowWindow then CallUp; //CoolTrayIcon1.ShowMainForm;
    if not SoundDisable then begin
      if PlayBeep then Beep;
      if PlaySound then
      try
        MediaPlayer1.FileName := SoundFile;
        MediaPlayer1.Open;
        MediaPlayer1.Play;
        MPSetVolume(MediaPlayer1, SoundVolume);
      except
        Dialogs.ShowMessage('Zadaný zvukový soubor pro událost '+AppEvents[Integer(EventType)].EventName+' není audio soubor nebo nebyl nalezen!');
      end;
    end;

    try
      if ExecuteApplication then ShellLaunch(ApplicationFile);
    except
      Dialogs.ShowMessage('Zadaný program ke spuštění pro událost '+AppEvents[Integer(EventType)].EventName+' nebyl nalezen!');
    end;

    with SunriseChatNetworkCore1 do
    if (not Visible) and ShowBalloonHint then
      CoolTrayIcon1.ShowBalloonHint(ApplicationName+' - Zpráva', RoomLine.Text, bitInfo, 10);

    // Change tray icon
    if ShowAlertIcon and MinimizeToTray and (not Visible) and FileExists(IconFile) then begin
      Icon:= TIcon.Create;
      try
        Icon.LoadFromFile(IconFile);
        CoolTrayIcon1.IconList.ReplaceIcon(6,Icon);
        CoolTrayIcon1.IconIndex:= 6;
      finally
        Icon.Free;
      end;
    end;

    if ShowMessage then with SunriseChatNetworkCore1 do begin
      // Set text font
      RoomLine.Font.Charset := MessageFont.Charset;
      RoomLine.Font.Name := MessageFont.Name;
      RoomLine.Font.Size := MessageFont.Size;
      RoomLine.Font.Style := MessageFont.Style;
      if EventType = aeOneUserMessage then begin
        RoomLine.Font.Color := MessageFont.Color;
        RoomLine.Font.Style := RoomLine.Font.Style + [fsBold];
      end;

      if (Room = nil) or (RoomList.IndexOf(ActiveRoom) = RoomList.IndexOf(Room)) then
      begin
        with RVStyle1.TextStyles do begin
          AddFontEx(RoomLine.Font.Name, RoomLine.Font.Size, RoomLine.Font.Color, RoomLine.Font.Style, RoomLine.Font.Charset);

          if ShowMessageTime then MessageTime := '['+TimeToStr(Now)+'] ' else MessageTime := '';
          RichView1.AddNamedCheckPoint('a');
          RichView1.AddFromNewLine(MessageTime, Count-1);

          // Process user defined events
          MessageTextTemp := RoomLine.Text;
          TextStart := 1;
          TextEnd := 1;
          while TextEnd <= Length(MessageTextTemp) do begin
            if (HttpHeader = Copy(MessageTextTemp, TextEnd, Length(HttpHeader))) or
            (ShareHeader = Copy(MessageTextTemp, TextEnd, Length(ShareHeader))) or
            (('"' + ShareHeader) = Copy(MessageTextTemp, TextEnd, Length(ShareHeader)+1)) then begin
              if (MessageTime = '') and (TextStart = 1) then RichView1.AddTextFromNewLine(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1)
              else RichView1.AddText(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1);
              TemporaryText := Copy(MessageTextTemp, TextEnd, High(Integer));
              if TemporaryText[1] = '"' then begin
                if Pos('"', Copy(TemporaryText, 2, High(Integer))) > 0 then
                  TemporaryText := Copy(TemporaryText, 1, Pos('"', Copy(TemporaryText, 2, High(Integer)))+1)
              end else if(Pos(' ', TemporaryText)>0) then TemporaryText := Copy(TemporaryText, 1, Pos(' ', TemporaryText)-1);
              RichView1.Add(TemporaryText, rvsJump1);
              TextStart := TextEnd + Length(TemporaryText);
              TextEnd := TextStart-1;
              SetLength(HyperLinks, Length(HyperLinks) + 1);
              HyperLinks[High(HyperLinks)] := TemporaryText;
            end else
            for I := 0 to High(AppUserEvents) do
            with AppUserEvents[I] do begin
              if (((not ConditionUserEnable) or (ConditionUserEnable and (ConditionUser = UserNick))) and
              ((not ConditionTextEnable) or (ConditionTextEnable and (Length(ConditionText)>0)and (ConditionText = Copy(MessageTextTemp,TextEnd,Length(ConditionText))))) and
              ((not ConditionAppEventEnable) or (ConditionAppEventEnable and (ConditionAppEvent = Integer(EventType))))) and
              (ConditionAppEventEnable or ConditionTextEnable or ConditionUserEnable) then begin
                // Show image instead text
                if ShowImage and UserEventsImagesEnabled then begin
                  if (MessageTime = '') and (TextStart = 1) then RichView1.AddTextFromNewLine(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1)
                  else RichView1.AddText(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1);

                  if not Assigned(Image) then begin
                    Image:= TImage.Create(Self);
                    if FileExists(ImageFile) then
                      Image.Picture.LoadFromFile(ImageFile);
                  end;
                  if Assigned(Image.Picture.Graphic) then RichView1.AddImage(Image, False)
                  else RichView1.AddText(ConditionText+'"Obrázek nenalezen!"',Count-1);

                  TextStart:= TextEnd + Length(ConditionText);
                  TextEnd:= TextStart-1;
                end;

                // Show call up
                if ShowWindow then CallUp; //CoolTrayIcon1.ShowMainForm;

                // Play sound
                if not SoundDisable then begin
                  if PlayBeep then Beep;
                  if PlaySound then
                  try
                    MediaPlayer1.FileName:= SoundFile;
                    MediaPlayer1.Open;
                    MediaPlayer1.Play;
                  except
                    Dialogs.ShowMessage('Zadaný zvukový soubor pro uživatelskou událost '+EventName+' není audio soubor nebo nebyl nalezen!');
                  end;
                end;
                // Execute application
                try
                  if ExecuteApplication then ShellLaunch(ApplicationFile);
                except
                  Dialogs.ShowMessage('Zadaný program ke spuštění pro událost '+AppEvents[Integer(EventType)].EventName+' nebyl nalezen!');
                end;

                // Show balloon hint
                with SunriseChatNetworkCore1 do
                if (not Visible) and ShowBalloonHint then with SunriseChatNetworkCore1 do
                  CoolTrayIcon1.ShowBalloonHint(ApplicationName+' - Zpráva', RoomLine.Text, bitInfo,10);

                // Change tray icon
                if ShowAlertIcon and MinimizeToTray and (not Visible) and FileExists(IconFile) then begin
                  Icon:= TIcon.Create;
                  try
                    Icon.LoadFromFile(IconFile);
                    CoolTrayIcon1.IconList.ReplaceIcon(6,Icon);
                    CoolTrayIcon1.IconIndex:= 6;
                  finally
                    Icon.Free;
                  end;
                end;
                Break;
              end;
            end;
            TextEnd:= TextEnd + 1;
          end;
          if (MessageTime = '') and (TextStart = 1) then RichView1.AddTextFromNewLine(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1)
          else RichView1.AddText(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1);
          //Dialogs.ShowMessage(IntToStr(RichView1.CheckPointsCount));
          if RichView1.CheckPointsCount > SunriseChatNetworkCore1.MaxRoomLines then
            RichView1.DeleteSection('a');
          RichView1.Format;
          ScrollDownRichEdit1;
          RichView1.Paint;
        end;
      end else begin
        if RoomList.IndexOf(Room) < PageControl1.PageCount then
          with PageControl1.Pages[RoomList.IndexOf(Room)] do begin
            if ImageIndex = 25 then ImageIndex := 27;
            if ImageIndex = 26 then ImageIndex := 28;
          end;
      end;
    end else RoomLine.Text := '';;
  end;
end;

procedure TMainWindow.Button1Click(Sender: TObject);
var
  TargetUser: string;
  I: Integer;
begin
  //raise Exception.Create('Test');
  if ComboBox1.Text <> '' then with SunriseChatNetworkCore1, ComboBox1 do begin
    TRoom(RoomList[PageControl1.TabIndex]).Select;
    LocalUser.Status := usOnline;
    if Pos(':', Text) > 0 then TargetUser := Copy(Text, 1, Pos(':', Text)-1)
      else TargetUser := '';

    I := 0;
    while (I < UserList.Count) and (TUser(UserList[I]).Nick <> TargetUser) do
      I := I + 1;
    if I < UserList.Count then begin
      SunriseChatNetworkCore1.SendCommand(scMessage, ComboBox1.Text,
        TUser(UserList[I]).Id.Machine, TUser(UserList[I]).Id.User);
    end else SendCommand(scMessage, ComboBox1.Text);
  end;
  ComboBox1.Text := '';
  ComboBox1.SetFocus;
  lComboBox1Change(Self);
end;

procedure TMainWindow.FormShow(Sender: TObject);
begin
  FirstStart := False;
  Options.SaveToRegistry;

  LogExceptions.NazevAplikace := ApplicationName + ' ' +ClientVersion;
  if MinimizeToTray then CoolTrayIcon1.HideTaskbarIcon
  else CoolTrayIcon1.ShowTaskbarIcon;
  CoolTrayIcon1.IconIndex := 5;
  // Localization section
  with Localization do begin
    ActionAbout.Caption := Item('AboutProgram');
    ActionAway.Caption := Item('AwayMode');
    ActionBlockIP.Caption := Item('BlockUser');
    ActionCallUp.Caption := Item('CallUp');
    ActionClearMessageList.Caption := Item('ClearMessageList');
    ActionClose.Caption := Item('Close');
    ActionCreateRoom.Caption := Item('CreateRoom');
    ActionInfo.Caption := Item('Information');
    ActionInvisible.Caption := Item('Invisible');
    ActionNetworkTest.Caption := Item('NetworkTest');
    ActionOnline.Caption := Item('Online');
    ActionOptions.Caption := Item('Options');
    ActionRestore.Caption := Item('Restore');
    ActionStatus.Caption := Item('Status');
    ActionTestResponse.Caption := Item('ResponseTest');
    ActionUserRoom.Caption := Item('InviteUserToRoom');
    ActionChangeLog.Caption := Item('ChangeLog');

    SearchFind1.Caption := Item('SearchText');
    Label1.Caption := Item('UserList')+':';
    Label2.Caption := Item('MessageList')+':';
    Pedchozzprva1.Caption := Item('PreviousMessage');
    Doplnitjmno1.Caption := Item('CompleteUserName');
    Odejtzmstnosti1.Caption := Item('LeaveRoom');
    Button1.Caption := Item('Send');
  end;
end;

procedure TMainWindow.CallUp;
begin
  CoolTrayIcon1.ShowMainForm;
  FormStyle := fsStayOnTop;
//  ShowMessage('Výzva');
//  CallUpWindow.Show;
  BringWindowToTop(Handle);
  //Timer1.Tag := 0;
  //Timer1.Enabled := True;

  //Windows.SetForegroundWindow(Handle);
  //BringToFront;
  //windows.SetFocus(Handle);
  //FormStyle := fsStayOnTop;
  //  ShellLaunch('calc.exe');
  if not OnTop then FormStyle := fsNormal;
  //SwitchToThisWindow(Handle,True);
  //TabControl1Change(Self);
//  RichEdit1.Repaint;
end;

procedure TMainWindow.Timer1Timer(Sender: TObject);
begin
  with SunriseChatNetworkCore1, LocalUser do begin
    Repaint;
    Beep;
    Timer1.Tag := Timer1.Tag + 1;
    if Timer1.Tag > 50 then Timer1.Enabled := False;
//  if SunriseChatCore.Connected then NewCaption:= '' else NewCaption:= '(offline)';
//  Caption:= 'SunriseChat'+NewCaption+' - '+SunriseChatCore.LocalUser.Nick;
//  Label1.Caption:= BoolToStr(CoolTrayIcon1.MinimizeToTray);
//  Label3.Caption:= BoolToStr(SunriseChatCore.fndTCPServer1.Active);
//  Label4.Caption:= IntToStr(SunriseChatCore.fndTCPServer1.ClientCount);
  end;
end;

procedure TMainWindow.ChangeRunOnLogon;
begin
  // Check run on startup
  with TRegistry.Create do
  try
    RootKey := HKEY_CURRENT_USER;
    OpenKey('\Software\Microsoft\Windows\CurrentVersion\Run', True);
    if RunOnLogon then WriteString(ApplicationName+'-'+SettingsName,'"'+Application.ExeName+'" "/s:'+SettingsName+'"')
    else DeleteValue(ApplicationName+'-'+SettingsName);
  finally
    Free;
  end;
end;

procedure TMainWindow.ChangeNetworkState;
begin
  RefreshAppTitle;
end;

procedure TMainWindow.ShowUserList;
var
  I: Integer;
  Node: TListItem;
  Index: Integer;
  LastCount: Integer;
  NewImageIndex: Integer;

function StatusToImageIndex(Status: TUserStatusMode): Integer;
begin
  if Status = usAway then Result:= 2
  else if Status = usWriting then Result:= 4
  else if Status = usInvisible then Result:= 7
  else if Status = usOffline then Result:= 7
  else Result:= 0;
end;

begin
  with SunriseChatNetworkCore1, ListView1 do begin
    if Assigned(ListView1.Selected) then Index := ListView1.Selected.Index
      else Index := 0;
    LastCount := ListView1.Items.Count;
    //ListView1.Items.BeginUpdate;
    //ListView1.Items.Clear;

    // Add missing items to list
    for I := 1 to UserList.Count - Items.Count do begin
      Node := ListView1.Items.Add;
      with Node do begin
        Node.Caption := '';
        ImageIndex:= 0;
      end;
    end;

    // Delete excessive items from list
    for I := 1 to Items.Count - UserList.Count do Items.Delete(Items.Count-1);

    // Update all items
    for I := 0 to UserList.Count-1 do with TUser(UserList[I]), Items.Item[I] do begin
      if Caption <> Nick then Caption:= Nick;
      if (Now - LastTime)>OfflineTimeout then NewImageIndex:= 7 else begin
        if (IdleTime>(AutoAwayDelay * 60)) and (Status <> usAway) then NewImageIndex:= 1 else
        NewImageIndex:= StatusToImageIndex(Status);
        if BlockMessages then NewImageIndex:= 17;
      end;
      if NewImageIndex <> ImageIndex then ImageIndex:= NewImageIndex;
    end;

    //ListView1.Items.EndUpdate;

    // Select previous selected item
    try
      with ListView1 do
        if Items.Count>0 then
          if Index < Items.Count then Selected:= Items.Item[Index] else
            Selected:= Items.Item[Items.Count-1];
    except
    end;

    // Automatically change window height according to user list count
    if AutoChangeWindowHeight then
    if LastCount <> ListView1.Items.Count then begin
      LastCount:= ListView1.Items.Count;
      if LastCount < MinimumVisibleUsersCount then LastCount:= MinimumVisibleUsersCount;
      with MainWindow do begin
        if not AutoChangeWindowHeightDirectionDown then
          Top := Top - (LastCount * 17 - ListView1.Height + 10);
        Height := Height + (LastCount * 17 - ListView1.Height + 10);
        ListView1.Update;
      end;
    end;
  end;
end;

procedure TMainWindow.ComboBox1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then begin
    with ComboBox1 do
    if DroppedDown and (Style <> csSimple) then begin
      DroppedDown:= False;
      Items.Clear;
      SelStart:= Length(ComboBox1.Text);
      ComboBox1.Style:= csSimple;
    end else Button1Click(Self);
    Key:= #0;
  end;
end;

procedure TMainWindow.ComboBox1KeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
//  ShowMessage(IntToStr(Key));
  if Key = 38 then ComboBox1.Text := UserLastText;
  if Key = 39 then with SunriseChatNetworkCore1 do DoplnitJmeno;
end;

procedure TMainWindow.ActionInfoExecute(Sender: TObject);
begin
  InfoWindow.ShowModal;
end;

procedure TMainWindow.ActionAwayExecute(Sender: TObject);
begin
  with SunriseChatNetworkCore1, LocalUser do
  if Status <> usAway then begin
    Reason := DefaultReason;
    if ComboBox1.Text <> '' then begin
      Reason := ComboBox1.Text;
      ComboBox1.Text := '';
    end else
      if not InputQuery('Odchod pryč', 'Zadejte důvod nepřítomnosti', Reason) then Exit;
    ActionAway.Checked := True;
    Status := usAway;
    SendCommand(scUserInfo);
    ShowUserList;
    ComboBox1.Enabled := False;
    Button1.Enabled := False;
  end;
  //ShowUserList;
end;

procedure TMainWindow.ActionOnlineExecute(Sender: TObject);
begin
  ActionOnline.Checked := True;
  with SunriseChatNetworkCore1, LocalUser do begin
    if Status = usAway then begin
      Status := usOnline;
      SendCommand(scUserInfo);
    end;
    ShowUserList;
  end;
  ComboBox1.Enabled:= True;
  Button1.Enabled:= True;
  ShowUserList;
end;

procedure TMainWindow.ActionCloseExecute(Sender: TObject);
begin
  CloseEnabled:= True;
  Close;
end;

procedure TMainWindow.ListView1Click(Sender: TObject);
begin
  with SunriseChatNetworkCore1 do
  if Assigned(ListView1.Selected) then with ListView1.Selected do begin
    if TUser(UserList[Index]).Status = usAway then
      AddMessage(aeUserGoAway, ActiveRoom, [TUser(UserList[Index]).Nick, TUser(UserList[Index]).Reason]);
  end;
end;

procedure TMainWindow.ActionTestResponseExecute(Sender: TObject);
begin
  with SunriseChatNetworkCore1 do
  if Assigned(ListView1.Selected) then with ListView1.Selected do begin
    SendCommand(scPing, TimeToStr(Now), TUser(UserList[Index]).Id.Machine, TUser(UserList[Index]).Id.User);
    AddMessage(aeSendPing, ActiveRoom, [TUser(UserList[Index]).Nick]);
  end;
end;

procedure TMainWindow.ActionRestoreExecute(Sender: TObject);
begin
  CoolTrayIcon1.ShowMainForm;
end;

procedure TMainWindow.ActionInvisibleExecute(Sender: TObject);
begin
  ActionInvisible.Checked := True;
  SunriseChatNetworkCore1.LocalUser.Status := usInvisible;
  ComboBox1.Enabled := False;
  Button1.Enabled := False;
  ShowUserList;
end;

procedure TMainWindow.ActionAboutExecute(Sender: TObject);
begin
  AboutWindow.ShowModal;
end;

procedure TMainWindow.ActionOptionsExecute(Sender: TObject);
begin
  OptionsWindow.ShowModal;
end;

procedure TMainWindow.ActionCallUpExecute(Sender: TObject);
begin
  with SunriseChatNetworkCore1 do
  if Assigned(ListView1.Selected) then with ListView1.Selected, TUser(UserList[Index]) do begin
    AddMessage(aeSendCallUp, nil, [Nick]);
    SendCommand(scCallUp, '', Id.Machine, Id.User);
  end;
end;


procedure TMainWindow.TabControl1Change(Sender: TObject);
var
  I, II: Integer;
  ForUser: string;
  MessageTime: string;
  MessageTextTemp: string;
  TextStart, TextEnd: Integer;
  TemporaryText: string;
begin
  SetLength(HyperLinks, 0);
  SunriseChatNetworkCore1.ActiveRoom := SunriseChatNetworkCore1.RoomList[PageControl1.TabIndex];
  with SunriseChatNetworkCore1, TRoom(RoomList[PageControl1.TabIndex]) do begin
    with PageControl1 do
    if ActiveRoom.Typ = rtPublic then Pages[TabIndex].ImageIndex:= 25
      else Pages[TabIndex].ImageIndex := 26;
    RichView1.Clear;
    ForUser := SunriseChatNetworkCore1.LocalUser.Nick+': ';
    for II := 0 to Count-1 do
    with SunriseChatNetworkCore1, RVStyle1.TextStyles, TRoomLine(Lines[(StartLine+II) mod MaxRoomLines]) do begin

      AddFontEx(Font.Name, Font.Size, Font.Color, Font.Style, Font.Charset);
      if ShowMessageTime then MessageTime := '['+TimeToStr(Time)+'] ' else MessageTime:= '';
      RichView1.AddNamedCheckPoint('a');
      RichView1.AddFromNewLine(MessageTime, Count-1);

      // Process user defined events
      MessageTextTemp:= Text;
      TextStart:= 1;
      TextEnd:= 1;
      while TextEnd <= Length(MessageTextTemp) do begin
        if (HttpHeader = Copy(MessageTextTemp, TextEnd, Length(HttpHeader))) or
          (ShareHeader = Copy(MessageTextTemp, TextEnd, Length(ShareHeader))) or
          (('"' + ShareHeader) = Copy(MessageTextTemp, TextEnd, Length(ShareHeader)+1)) then begin
          if (MessageTime = '') and (TextStart = 1) then RichView1.AddTextFromNewLine(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1)
            else RichView1.AddText(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1);
          TemporaryText := Copy(MessageTextTemp, TextEnd, High(Integer));
          if TemporaryText[1] = '"' then begin
            if Pos('"', Copy(TemporaryText, 2, High(Integer))) > 0 then
              TemporaryText := Copy(TemporaryText, 1, Pos('"', Copy(TemporaryText, 2, High(Integer)))+1)
          end else if(Pos(' ', TemporaryText)>0) then TemporaryText := Copy(TemporaryText, 1, Pos(' ', TemporaryText)-1);
          RichView1.Add(TemporaryText, rvsJump1);
          TextStart := TextEnd + Length(TemporaryText);
          TextEnd := TextStart-1;
          SetLength(HyperLinks, Length(HyperLinks)+1);
          HyperLinks[High(HyperLinks)] := TemporaryText;
        end else
        for I:= 0 to High(AppUserEvents) do
        with AppUserEvents[I] do begin
          if (((not ConditionUserEnable) or (ConditionUserEnable and (ConditionUser = Nick))) and
          ((not ConditionTextEnable) or (ConditionTextEnable and (ConditionText = Copy(MessageTextTemp,TextEnd,Length(ConditionText))))) and
          (ConditionText <> '') and
          ((not ConditionAppEventEnable) or (ConditionAppEventEnable and (ConditionAppEvent = Integer(EventType))))) and
          (ConditionAppEventEnable or ConditionTextEnable or ConditionUserEnable) then begin
            // Show image instead text
            if ShowImage and UserEventsImagesEnabled then begin
              if (MessageTime = '') and (TextStart = 1) then RichView1.AddTextFromNewLine(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1)
              else RichView1.AddText(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1);
              if not Assigned(Image) then begin
                Image:= TImage.Create(Self);
                if FileExists(ImageFile) then
                  Image.Picture.LoadFromFile(ImageFile);
              end;
              if Assigned(Image.Picture.Graphic) then RichView1.AddImage(Image, False)
              else RichView1.AddText(ConditionText+'"Obrázek nenalezen!"',Count-1);
              TextStart:= TextEnd + Length(ConditionText);
              TextEnd:= TextStart-1;
              Break;
            end;
          end;
        end;
        TextEnd:= TextEnd + 1;
      end;
      if (MessageTime = '') and (TextStart = 1) then RichView1.AddTextFromNewLine(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1)
        else RichView1.AddText(Copy(MessageTextTemp,TextStart,TextEnd-TextStart),Count-1);
    end;
    RichView1.Format;
    ScrollDownRichEdit1;
    RichView1.Paint;
  end;
end;

procedure TMainWindow.ActionBlockIPExecute(Sender: TObject);
begin
  with SunriseChatNetworkCore1 do
  if Assigned(ListView1.Selected) then
    with ListView1.Selected, TUser(UserList[Index]) do begin
      BlockMessages:= not BlockMessages;
      ShowUserList;
    end;
end;

procedure TMainWindow.FormCloseQuery(Sender: TObject;
  var CanClose: Boolean);
begin
  CanClose:= CloseEnabled;
  if MinimalizeOnCloseWindow then begin
    CoolTrayIcon1.HideMainForm;
  end else CanClose:= True;
end;

procedure TMainWindow.ActionUserRoomExecute(Sender: TObject);
begin
  if Assigned(ListView1.Selected) then
    with ListView1.Selected, SunriseChatNetworkCore1, TUser(UserList[Index]) do begin
      if ActiveRoom.Typ = rtPublic then ShowMessage('Nelze pozvat uživatele do veřejné místnosti!')
      else begin
        SendCommand(scCreateRoom, '', Id.Machine, Id.User);
        AddMessage(aeUserInvited, ActiveRoom, [Nick]); 
        //if (IP<>LocalUser.IP) or (ID<>LocalUser.ID) then SendCommand('CreateRoom','',LocalUser.IP,LocalUser.ID);
      end;
    end;
end;

procedure TMainWindow.RoomListChanged;
var
  I: Integer;
//  T: TListBox;
  NewTabSheet: TTabSheet;
begin
  with SunriseChatNetworkCore1 do with PageControl1 do begin
    while PageCount>0 do Pages[0].Free;
    for I:= 0 to RoomList.Count-1 do begin
      NewTabSheet := TTabSheet.Create(PageControl1);
      NewTabSheet.PageControl := PageControl1;
      NewTabSheet.Caption := TRoom(RoomList[I]).Name;
      if TRoom(RoomList[I]).Typ = rtPublic then NewTabSheet.ImageIndex:= 25
      else NewTabSheet.ImageIndex:= 26;
    end;
    Visible := PageCount > 1;
    if RoomList.IndexOf(ActiveRoom) = -1 then ActiveRoom := RoomList[0];
    ActivePageIndex := RoomList.IndexOf(ActiveRoom);
    PageControl1.TabIndex := ActivePageIndex;
    TabControl1Change(Self);
  end;
end;

procedure TMainWindow.Odejtzmstnosti1Click(Sender: TObject);
begin
  with SunriseChatNetworkCore1 do
  if PageControl1.ActivePageIndex = 0 then ShowMessage('Tuto místnost nelze zrušit')
  else begin
    SendCommand(scLeaveRoom);
    DeleteRoom(PageControl1.ActivePageIndex);
    TabControl1Change(Self);
  end;
end;

procedure TMainWindow.ActionCustomizeDlgExecute(Sender: TObject);
begin
  FormStyle:= fsNormal;
  CustomizeDlg1.Show;
//  if OnTop then FormStyle:= fsStayOnTop;
end;

procedure TMainWindow.PopupMenu2Popup(Sender: TObject);
begin
  with SunriseChatNetworkCore1 do
  if Assigned(ListView1.Selected) then
    with ListView1.Selected, SunriseChatNetworkCore1, TUser(UserList[Index]) do
      BlokovatAdresu1.Checked:= BlockMessages;
end;

procedure TMainWindow.WMQueryEndSession(var Message: TMessage);
{ This method is a hack. It intercepts the WM_QUERYENDSESSION message.
  This way we can decide if we want to ignore the "Close to tray" option.
  Otherwise, when selected, the option would make Windows unable to shut down. }
begin
  CloseEnabled:= True;
  Message.Result:= 1;
end;

procedure TMainWindow.Pedchozzprva1Click(Sender: TObject);
var
  I: Integer;
begin
  ComboBox1.Style:= csDropDown;
  with SunriseChatNetworkCore1, ComboBox1.Items do begin
    BeginUpdate;
    Clear;
    for I := ActiveRoom.Count-1 downto 0 do with ActiveRoom, TRoomLine(Lines[(I + StartLine) mod MaxRoomLines]) do begin
      Add(Text);
    end;
    Update;
    EndUpdate;
    if ComboBox1.Items.Count>0 then ComboBox1.DroppedDown:= True;
  end;
end;


procedure TMainWindow.DoplnitJmeno;
var
  I: Integer;
  UserIndex: Integer;
  NickCount: Integer;
begin
  UserIndex := -1;
  NickCOunt := 0;
  with SunriseChatNetworkCore1 do begin
    for I := 0 to UserList.Count-1 do begin
      if Length(ComboBox1.Text) <= Length(TUser(UserList[I]).Nick) then
        if ComboBox1.Text = Copy(TUser(UserList[I]).Nick, 1, Length(ComboBox1.Text)) then begin
          UserIndex := I;
          NickCount := NickCount + 1;
        end;
    end;
    if NickCount = 1 then begin
      ComboBox1.Text:= TUser(UserList[UserIndex]).Nick + ': ';
      ComboBox1.SelStart:= Length(ComboBox1.Text);
    end else
    if NickCount > 1 then FillComboBox;
  end;
end;

procedure TMainWindow.ActionNetworkTestExecute(Sender: TObject);
begin
  NetworkTest.ShowModal;
end;

procedure TMainWindow.ToolButton7Click(Sender: TObject);
begin
  Application.Minimize;
end;

procedure TMainWindow.Vloit1Click(Sender: TObject);
begin
  SendMessage(ComboBox1.Handle, WM_PASTE, 0, 0);
end;

procedure TMainWindow.Vloitsovodkaz1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then begin
    if Pos(' ', OpenDialog1.FileName) > 0 then
      ComboBox1.Text := ComboBox1.Text + '"' + OpenDialog1.FileName + '"'
    else
      ComboBox1.Text := ComboBox1.Text + OpenDialog1.FileName;
  end;
end;

procedure TMainWindow.CoolTrayIcon1Click(Sender: TObject);
begin
//  RichEdit1.Lines.Add(IntToStr(GetForegroundWindow)+' '+IntToStr(MainWindow.Handle)+' '+IntToStr(Application.Handle));
//  if GetForegroundWindow = Application.Handle then CoolTrayIcon1.HideMainForm else
  if MainWindow.Visible then CoolTrayIcon1.HideMainForm else
  CoolTrayIcon1.ShowMainForm;
end;

procedure TMainWindow.ToolButton1Click(Sender: TObject);
begin
//  ToolButton1.Marked := not ToolButton1.Marked;
  PauseScrollText := ToolButton1.Down;
end;

procedure TMainWindow.ToolButton3Click(Sender: TObject);
begin
  ActionOptionsExecute(Self);
end;

procedure TMainWindow.ToolButton2Click(Sender: TObject);
begin
  ActionInfoExecute(Self);
end;

procedure TMainWindow.ToolButton5Click(Sender: TObject);
begin
//  ToolButton5.Marked:= not ToolButton5.Marked;
  OnTop:= ToolButton5.Down;
  InitTrayIcon;
end;

procedure TMainWindow.ToolButton4Click(Sender: TObject);
begin
//  ToolButton4.Marked:= not ToolButton4.Marked;
  SoundDisable:= ToolButton4.Down;
end;

procedure TMainWindow.ScrollDownRichEdit1;
begin
  if not PauseScrollText then begin
    RichView1.ScrollTo(High(Integer));
    RichView1.Paint;
 (*
    // Scroll down Richedit
    ScrollMessage.Msg:= WM_VScroll;

    ScrollMessage.ScrollCode:= sb_Bottom;
    ScrollMessage.Pos:= 0;
    RichEdit1.Dispatch(ScrollMessage);
    if Win32Platform = 1 then begin
      ScrollMessage.Msg:= WM_VScroll;
      begin
        ScrollMessage.ScrollCode:= SB_PAGEUP;
        ScrollMessage.Pos:= 0;
        RichEdit1.Dispatch(ScrollMessage);
      end;
    end;
    *)
  end;
end;


procedure TMainWindow.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if Msg.Message = WM_SunriseChatStart then begin
    if HWND(Msg.wParam) <> Application.Handle then begin
      if OneAppInstance then begin
        Application.Restore;
        CoolTrayIcon1.ShowMainForm;
        SetForeGroundWindow(Application.MainForm.Handle);
        PostMessage(HWND_BROADCAST, WM_SunriseChatClose, Application.Handle, 0);
      end;
    end;
    Handled := true;
  end;
  if Msg.Message = WM_SunriseChatClose then begin
    if HWND(Msg.wParam) <> Application.Handle then begin
      if OneAppInstance then begin
        NoSaveToRegistry:= True;
        StopProgram:= True;
      end;
    end;
    Handled := true;
  end;
end;

procedure TMainWindow.RichEdit1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  SendMessage(HWND_BROADCAST,WM_SunriseChatStart,0,0);
end;

procedure TMainWindow.RichView1Jump(Sender: TObject; id: Integer);
var
  Url: string;
begin
  Url := HyperLinks[id];
  if Url[1] = '"' then Delete(Url, 1, 1);
  if Pos('"', Url) > 0 then Delete(Url, Length(Url), 1);
  ShellExecute(Handle, 'open', PChar(Url), nil, nil, SW_SHOWNORMAL);
end;

procedure TMainWindow.lComboBox1Change(Sender: TObject);
begin
  with SunriseChatNetworkCore1 do begin
    if (ComboBox1.Text = '') and (Length(LastText) > 0) then begin
      LocalUser.Status := usOnline;
      SendCommand(scUserInfo);
    end;
    if (Length(ComboBox1.Text) > 0) and (Length(LastText) = 0) then begin
      LocalUser.Status := usWriting;
      SendCommand(scUserInfo);
    end;
    LastText := ComboBox1.Text;
  end;
//  if Edit1.Text='' then SunriseChatCore.LocalUser.Status:= usOnline;
end;

procedure TMainWindow.AddEvent(Name, Text: string; Options: TEventOptions);
begin
  SetLength(AppEventsInit, Length(AppEventsInit) + 1);
  with AppEventsInit[High(AppEventsInit)] do begin
    EventName := Name;
    ShowMessage := eoShowMessage in Options;
    MessageText := Text;
    MessageFont := TFont.Create;
    ShowBalloonHint := eoShowBalloonHint in Options;
    ShowAlertIcon := eoShowAlertIcon in Options;
    ShowWindow := eoShowWindow in Options;
    PlayBeep := eoPlayBeep in Options;
  end;
end;

procedure TMainWindow.SaveAppEventsToRegistry;
var
  I: Integer;
begin
  for I:= 0 to High(AppEventsOptions) do with AppEvents[I] do begin
    MessageFontTemp.Color := MessageFont.Color;
    MessageFontTemp.Style:= '';
    if fsBold in MessageFont.Style then MessageFontTemp.Style := MessageFontTemp.Style + 'Bold,';
    if fsItalic in MessageFont.Style then MessageFontTemp.Style := MessageFontTemp.Style + 'Italic,';
    if fsUnderline in MessageFont.Style then MessageFontTemp.Style := MessageFontTemp.Style + 'Underline,';
    if fsStrikeOut in MessageFont.Style then MessageFontTemp.Style := MessageFontTemp.Style + 'StrikeOut,';
    MessageFontTemp.Charset := MessageFont.Charset;
    MessageFontTemp.Size := MessageFont.Size;
    MessageFontTemp.Name := MessageFont.Name;

    AppEventsOptions[I].SaveToRegistry;
    AppEventsOptions[I].Free;
  end;
  SetLength(AppEventsOptions,0);
  LoadAppEventsFromRegistry;
end;

procedure TMainWindow.SaveAppUserEventsToRegistry;
var
  I: Integer;
  Max: Integer;
begin
  AppUserEventsCount := Length(AppUserEvents);
  Max := High(AppUserEventsOptions);
  for I := 0 to Max do begin
    if I<Length(AppUserEvents) then AppUserEventsOptions[I].SaveToRegistry;
    //AppUserEventsOptions[I].Free;
    if Assigned(JobProgressView) then JobProgressView.Progress := I/Max;
  end;
  //SetLength(AppUserEventsOptions,0);
  //LoadAppUserEventsFromRegistry;
end;

procedure TMainWindow.LoadAppEventsFromRegistry;
var
  I: Integer;
  Text: string;
begin
  SetLength(AppEventsOptions, Length(AppEvents));
  for I := 0 to High(AppEventsOptions) do begin
    //if not Assigned(AppEventsOptions[I]) then
    AppEventsOptions[I] := TAutoRegistry.Create(RegistryPath + '\' + SettingsName +
      '\AppEvents\' + IntToStr(I));
    with AppEventsOptions[I], AppEvents[I] do begin
      Include('ShowWindow', ShowWindow, ShowWindow);
      Include('ShowAlertIcon', ShowAlertIcon, ShowAlertIcon);
      Include('ShowBaloonHint', ShowBalloonHint, ShowBalloonHint);
      Include('PlayBeep', PlayBeep, PlayBeep);
      Include('PlaySound' ,PlaySound, PlaySound);
      Include('SoundFile', SoundFile, '');
      Include('ExecuteApplication', ExecuteApplication, False);
      Include('ApplicationFile', ApplicationFile, '');
      Include('ShowMessage', ShowMessage, ShowMessage);
      Include('MessageText', MessageText, MessageText);
      Include('IconFile', IconFile, 'Envelope.ico');
      // Font
      Include('FontColor', MessageFontTemp.Color, Integer(clBlack));
      Include('FontStyle', MessageFontTemp.Style, '');
      Include('FontCharset', MessageFontTemp.Charset, 1);
      Include('FontSize', MessageFontTemp.Size, 8);
      Include('FontName', MessageFontTemp.Name, 'MS Sans Serif');
      LoadFromRegistry;
      MessageFont.Color := MessageFontTemp.Color;
      while Pos(',', MessageFontTemp.Style) > 0 do begin
        Text := Copy(MessageFontTemp.Style, 1, Pos(',', MessageFontTemp.Style) - 1);
        System.Delete(MessageFontTemp.Style, 1, Length(Text) + 1);
        if Text = 'Bold' then MessageFont.Style := MessageFont.Style + [fsBold];
        if Text = 'Italic' then MessageFont.Style := MessageFont.Style + [fsItalic];
        if Text = 'Underline' then MessageFont.Style := MessageFont.Style + [fsUnderline];
        if Text = 'StrikeOut' then MessageFont.Style := MessageFont.Style + [fsStrikeOut];
      end;
      MessageFont.Charset := MessageFontTemp.Charset;
      MessageFont.Size := MessageFontTemp.Size;
      MessageFont.Name := MessageFontTemp.Name;
    end;
  end;
end;

procedure TMainWindow.LoadAppUserEventsFromRegistry(UpdateOnly: Boolean = False);
var
  I: Integer;
begin
  SetLength(AppUserEventsOptions, AppUserEventsCount);
  SetLength(AppUserEvents, AppUserEventsCount);
  for I := 0 to AppUserEventsCount - 1 do begin
    //if not Assigned(AppEventsOptions[I]) then
    AppUserEventsOptions[I] := TAutoRegistry.Create(RegistryPath + '\' +
      SettingsName + '\AppUserEvents\' + IntToStr(I));
    with AppUserEventsOptions[I], AppUserEvents[I] do begin
      Update := UpdateOnly;
      Include('ConditionTextEnable', ConditionTextEnable, ConditionTextEnable);
      Include('ConditionText', ConditionText, ConditionText);
      Include('ConditionUserEnable', ConditionUserEnable, ConditionUserEnable);
      Include('ConditionUser', ConditionUser, ConditionUser);
      Include('ConditionAppEventEnable', ConditionAppEventEnable, ConditionAppEventEnable);
      Include('ConditionAppEvent', ConditionAppEvent, ConditionAppEvent);
      Include('ShowWindow', ShowWindow, ShowWindow);
      Include('ShowAlertIcon', ShowAlertIcon, ShowAlertIcon);
      Include('IconFile', IconFile, 'Envelope.ico');
      Include('ShowBaloonHint', ShowBalloonHint, ShowBalloonHint);
      Include('PlayBeep', PlayBeep, PlayBeep);
      Include('PlaySound', PlaySound, PlaySound);
      Include('SoundFile', SoundFile, '');
      Include('ExecuteApplication', ExecuteApplication, False);
      Include('ApplicationFile', ApplicationFile, '');
      Include('ShowImage', ShowImage, ShowImage);
      Include('ImageFile', ImageFile, ImageFile);
      Include('EventName', EventName, EventName);
      LoadFromRegistry;
    end;
    if Assigned(JobProgressView) then JobProgressView.Progress := I / AppUserEventsCount;
  end;
end;

procedure TMainWindow.Log1Click(Sender: TObject);
begin
  ProtocolMessageLogForm.Show;
end;

procedure TMainWindow.RefreshAppTitle;
var
  NewCaption: string;
  Settings: string;
begin
  if SettingsName = 'Default' then Settings:= '' else Settings:= '(' + SettingsName + ')';
  if SunriseChatNetworkCore1.Connected then NewCaption := ''
    else NewCaption := ' (Offline)';
  Caption := ApplicationName + Settings + ' - ' +
    SunriseChatNetworkCore1.LocalUser.Nick + NewCaption;
end;

procedure TMainWindow.ListView1InfoTip(Sender: TObject; Item: TListItem;
  var InfoTip: String);
begin
  InfoTip := TUser(SunriseChatNetworkCore1.UserList[Item.Index]).DetailInfo;
end;

procedure TMainWindow.ActionCreateRoomExecute(Sender: TObject);
begin
  NewRoom.ShowModal;
end;

procedure TMainWindow.Doplnitjmno1Click(Sender: TObject);
begin
  //if Pos(':',ComboBox1.Text) = 0 then
  DoplnitJmeno;
  ComboBox1.SelStart := ComboBox1.SelStart + 1;
end;

procedure TMainWindow.SearchFind1FindDialogFind(Sender: TObject);
//var
//  FoundAt: LongInt;
//  StartPos, ToEnd: Integer;
//  STypes: TSearchTypes;
begin
(*
  with SearchFind1, RichEdit1 do begin
    if frWholeWord in Dialog.Options then STypes := STypes + [stWholeWord];
    if frMatchCase in Dialog.Options then STypes := STypes + [stMatchCase];
    if SelLength <> 0 then StartPos := SelStart + SelLength
      else StartPos := 0;
    ToEnd := Length(Text) - StartPos;
    FoundAt := FindText(Dialog.FindText, StartPos, ToEnd, Stypes);
    if FoundAt <> -1 then begin
      SetFocus;
      SelStart := FoundAt;
      SelLength := Length(Dialog.FindText);
    end else ShowMessage(Dialog.FindText+' nelze najít');
  end;
*)
end;

procedure TMainWindow.SearchFind1BeforeExecute(Sender: TObject);
begin
  SearchFind1.Dialog.Options := [frHideUpDown];
end;

procedure TMainWindow.ActionClearMessageListExecute(Sender: TObject);
var
  I: Integer;
begin
  with SunriseChatNetworkCore1 do begin
    for I := 0 to ActiveRoom.Count - 1 do
      TRoomLine(ActiveRoom.Lines[I]).Font.Free;
    ActiveRoom.Count := 0;
    TabControl1Change(Self);
  end;
end;

procedure TMainWindow.InitSettings;
var
  I: Integer;
begin
  with Options, SunriseChatNetworkCore1 do begin
    Include('UserEventsImagesEnabled', UserEventsImagesEnabled, True);
    Include('ShowRightToolBar', ShowRightToolBar, True);
    Include('MinimalizeOnCloseWindow', MinimalizeOnCloseWindow, False);
    Include('DefaultReason', DefaultReason, 'Jsem pryč');
    Include('NoResloveHostName', NoResloveHostName, False);
    Include('ShowMainMenu', ShowMainMenu, True);
    MainMenu1.Items.Visible := ShowMainMenu;
    Include('ShowMessageTime', ShowMessageTime, False);
    Include('AlphaBlend', AlphaBlendWindow, 255);
    Include('UserListWidth', UserListWidth, 100);
    Include('ShowOnMessage', ShowOnMessage, False);
    Include('ShowBallonHint', ShowBallonHint, False);
    Include('OnTop', OnTop, False);
    Include('RunOnLogon', RunOnLogon, True);
    Include('StartInTray', StartInTray, False);
    Include('MinimizeToTray', MinimizeToTray, True);
    Include('ServiceFunction', ServiceFunction, False);
    Include('Nick', UserNick, 'Host');
    Include('DetailInfo', LocalUser.DetailInfo, '');
    LocalUser.NickTime := Now;
    Include('Color', LocalUser.Color, 0);
    Include('SnapWindow', SnapWindow, True);
    Include('Port', NetworkPort, 55557);
    Include('NetworkInterfaceGUID', NetworkInterface, '');
    Include('PositionX',PositionX, Left);
    if (PositionX < 0) or (PositionX > Screen.Width) then PositionX := 0;
    Include('PositionY',PositionY,Top);
    if (PositionY < 0) or (PositionY > Screen.Height) then PositionY := 0;
    Include('SizeX', SizeX, Width);
    Include('SizeY', SizeY, Height);
    Include('WindowState', LastWindowState, Integer(fsNormal));
    Include('AutoAwayIdleTime', UsersAutoAwayDelay, 5);
    Include('PauseScrollText', PauseScrollText, False);
    Include('SoundDisable', SoundDisable, False);
    Include('OneAppInstance', OneAppInstance, True);
    Include('MaxNumberOfRoomLines', MaxNumberOfRoomLines, 100);
    Include('AutoChangeWindowHeight', AutoChangeWindowHeight, False);
    Include('AutoChangeWindowHeightDirectionDown', AutoChangeWindowHeightDirectionDown, False);
    Include('MinimumVisibleUsersCount', MinimumVisibleUsersCount, 8);
    Include('PingTimeout', PingTimeout, 200);
    Include('LanguageIndex', LanguageIndex, 0);
    Include('InvisibledOnStart', InvisibledOnStart, False);
    Include('AutoChangeInfoWindowHeight', AutoChangeInfoWindowHeight, True);
    Include('AppUserEventsCount', AppUserEventsCount, 0);
    Include('FirstStart', FirstStart, True);
    Include('BroadcastType', BroadcastTypeI, 0);
    Include('SoundVolume', SoundVolume, 1000);
    LoadFromRegistry;
    AutoAwayDelay := UsersAutoAwayDelay;
    LocalUser.Nick := UserNick;
    MPSetVolume(MediaPlayer1, SoundVolume);
    SunriseChatNetworkCore1.BroadcastType := TBroadcastType(BroadcastTypeI);
    if InvisibledOnStart then ActionInvisibleExecute(Self) else ActionOnlineExecute(Self);
    Localization.Activate(LanguageIndex);
    SunriseChatNetworkCore1.MaxRoomLines := MaxNumberOfRoomLines;
    MainWindow.ScreenSnap := SnapWindow;
    ToolButton1.Down := PauseScrollText;
    ToolButton4.Down := SoundDisable;
    ToolButton5.Down := OnTop;
    Left := PositionX;
    Top := PositionY;
    Width := SizeX;
    Height := SizeY;
    WindowState := TWindowState(LastWindowState);
    Panel2.Width := UserListWidth;
    AlphaBlendValue := AlphaBlendWindow;
    AlphaBlend := AlphaBlendValue < 255;

    // Initialisation of Events
    AddEvent('Běžná zpráva', '<%0:s> %1:s', [eoShowMessage, eoPlayBeep, eoShowAlertIcon]);
    AddEvent('Osobní zpráva', '<%0:s> %1:s', [eoShowMessage, eoPlayBeep, eoShowAlertIcon, eoShowBalloonHint]);
    AddEvent('Uživatel se připojil', 'Uživatel %0:s se připojil z počítače %1:s', [eoShowMessage]);
    AddEvent('Uživatel se odpojil', 'Uživatel %s se odpojil', [eoShowMessage]);
    AddEvent('Uživatel obnoven', 'Uživatel %s obnoven', []);
    AddEvent('Uživatel zmizel', 'Uživatel %s zmizel', []);
    AddEvent('Uživatel odešel', 'Uživatel %0:s odešel: %1:s', [eoShowMessage]);
    AddEvent('Uživatel se vrátil', 'Uživatel %s se vrátil', []);
    AddEvent('Odeslání výzvy', 'Výzva uživateli %s byla odeslána', [eoShowMessage]);
    AddEvent('Přijetí výzvy', 'Uživatel %s vás vyzval', [eoShowMessage, eoShowWindow, eoPlayBeep]);
    AddEvent('Test odezvy', 'Odezva uživateli %s byla odeslána', [eoShowMessage]);
    AddEvent('Přijetí odezvy', 'Odezva od uživatele %0:s přijata za %1:s sekund', [eoShowMessage]);
    AddEvent('Změna jména uživatele', 'Uživatel %0:s se přejmenoval na %1:s', [eoShowMessage]);
    AddEvent('Změna jména při konfliktu', 'Došlo ke konfliktu jmen. Měním vaše jméno na %s', [eoShowMessage]);
    AddEvent('Vytvoření místnosti', 'Uživatel %0:s vytvořil místnost %1:s', [eoShowMessage]);
    AddEvent('Opuštění místnosti', 'Uživatel %0:s opustil místnosti %1:s', [eoShowMessage]);
    AddEvent('Uživatel automaticky odešel', 'Uživatel %0:s automaticky odešel po %1:s minutách nečinnosti', []);
    AddEvent('Uživatel se automaticky vrátil', 'Uživatel %0:s se automaticky vrátil po %1:s minutách', []);
    AddEvent('Celé hodiny', 'Je %0:d hodin', []);
    AddEvent('Start aplikace', 'Vítá tě '+ApplicationName+'!', [eoShowMessage]);
    AddEvent('Ukončení aplikace', 'Loučí se s tebou '+ApplicationName+'!', [eoShowMessage]);
    AddEvent('Pozvání do soukromé místnosti', 'Uživatel %0:s pozván do místnosti', [eoShowMessage]);
    AddEvent('Volitelná událost', 'Volitelná událost', []);
    SetLength(AppEvents, Length(AppEventsInit));
    for I := 0 to High(AppEventsInit) do
      AppEvents[I] := AppEventsInit[I];
    SetLength(AppEventsInit, 0);
    LoadAppEventsFromRegistry;

    LoadAppUserEventsFromRegistry;
    ReloadImages;

    CoolTrayIcon1.Hint := ApplicationName;
    if OnTop then FormStyle := fsStayOnTop else FormStyle := fsNormal;
    InitTrayIcon;
    ChangeRunOnLogon;
    Panel5.Visible := ShowRightToolBar;
    Panel2.Visible := False;
    Panel2.Visible := True;
  end;
end;

procedure TMainWindow.ComboBox1Change(Sender: TObject);
begin
  lComboBox1Change(Self);
end;

procedure TMainWindow.FillComboBox;
var
  I: Integer;
begin
  ComboBox1.Style := csDropDown;
  with SunriseChatNetworkCore1, ComboBox1.Items do begin
    BeginUpdate;
    Clear;
    for I := 0 to UserList.Count - 1 do with TUser(UserList[I]) do begin
      if Copy(Nick, 1, Length(ComboBox1.Text)) = ComboBox1.Text then Add(Nick + ': ');
    end;
    Update;
    EndUpdate;
    if ComboBox1.Items.Count > 0 then ComboBox1.DroppedDown:= True;
  end;
end;

procedure TMainWindow.ActionChangeLogExecute(Sender: TObject);
begin
  ShellLaunch(ChangeLogFile);
end;

procedure TMainWindow.ComboBox1DropDown(Sender: TObject);
begin
  ComboBox1.Style := csSimple;
end;

procedure TMainWindow.ComboBox1CloseUp(Sender: TObject);
begin
  ComboBox1.Style := csSimple;
  ComboBox1.SelStart := -1;
end;

procedure TMainWindow.FormResize(Sender: TObject);
begin
  ScrollDownRichEdit1;
end;

procedure TMainWindow.ReloadImages;
var
  I: Integer;
begin
  RichView1.Clear;
  for I := 0 to High(AppUserEvents) do
  if Assigned(AppUserEvents[I].Image) then FreeAndNil(AppUserEvents[I].Image);
  TabControl1Change(Self);
(*
  for I:= 0 to High(AppUserEvents) do
with AppUserEvents[I] do begin
    if not Assigned(Image) then Image:= TImage.Create(Self);
    if FileExists(ImageFile) then
      Image.Picture.LoadFromFile(ImageFile);
  end;
  RichView1.Paint;
*)
end;

procedure TMainWindow.ActionUserEventsListExecute(Sender: TObject);
var
  I: Integer;
  StringList: TStringList;
begin
  ComboBox1.Style := csDropDown;
  StringList := TStringList.Create;
  try
    with SunriseChatNetworkCore1, StringList do begin
      BeginUpdate;
      for I := 0 to High(AppUserEvents) do with AppUserEvents[I] do begin
        Add(ComboBox1.Text+EventName);
      end;
      Sort;
      EndUpdate;
    end;
    with SunriseChatNetworkCore1, ComboBox1, Items do begin
      BeginUpdate;
      Clear;
      AddStrings(StringList);
      if Count > 0 then DroppedDown:= True;
      Update;
      EndUpdate;
    end;
  finally
    StringList.Free;
  end;
end;

procedure TMainWindow.ToolButton6Click(Sender: TObject);
begin
//  ToolButton6.Marked := not ToolButton6.Marked;
  ToolButton6.Repaint;
  UserEventsImagesEnabled := not ToolButton6.Down;
  TabControl1Change(Self);
end;

procedure TMainWindow.Panel6Resize(Sender: TObject);
begin
  RichView1.Width := Panel6.Width - 2;
  RichView1.Height := Panel6.Height - 2;
end;

procedure TMainWindow.SunriseChatNetworkCore1RoomListChanged;
begin
  RoomListChanged;
end;

procedure TMainWindow.SunriseChatNetworkCore1UserListUpdate;
begin
  ShowUserList;
end;

procedure TMainWindow.FormDestroy(Sender: TObject);
var
  I: Integer;
begin
  UsersAutoAwayDelay := SunriseChatNetworkCore1.AutoAwayDelay;
  UserNick := SunriseChatNetworkCore1.LocalUser.Nick;
//  IdleTrackerTerm;
  //Timer1.Enabled:= False;
  BroadcastTypeI := Integer(SunriseChatNetworkCore1.BroadcastType);
  PositionX := Left;
  PositionY := Top;
  SizeX := Width;
  SizeY := Height;
  LastWindowState := Integer(WindowState);
  UserListWidth := Panel2.Width;
  if not NoSaveToRegistry then Options.SaveToRegistry;
  ShowBallonHint := False;
  SoundDisable := True;
  SunriseChatNetworkCore1.SendCommand(scDisconnect);
  SunriseChatNetworkCore1.Free;
  Options.Free;
  for I := 0 to High(AppEvents) do
    AppEvents[I].MessageFont.Free;
  for I := 0 to High(AppEventsOptions) do
    AppEventsOptions[I].Free;
  for I := 0 to High(AppUserEventsOptions) do
    AppUserEventsOptions[I].Free;
end;

procedure TMainWindow.FormClose(Sender: TObject; var Action: TCloseAction);
//var
//  I: Integer;
begin
  SunriseChatNetworkCore1.SendCommand(scDisconnect);
  Application.ProcessMessages;
  Sleep(500);
  SaveAppEventsToRegistry;
  SaveAppUserEventsToRegistry;
end;

end.

