unit uFavoriteGamesProfileEditor;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, ComCtrls, ToolWin, IniFiles, StdCtrls, Buttons, GR32_Image,
  VirtualTrees, ImgList;

type
  pFavoriteProfile = ^TFavoriteProfile;
  TFavoriteProfile = record
    fpImageIndex: Integer;
    fpDescription,
    fpFileName: String;
  end;

type
  TFormFavoriteGamesProfileEditor = class(TForm)
    ToolBarButtons: TToolBar;
    ButtonNewUser: TToolButton;
    ButtonDeleteUser: TToolButton;
    ButtonUpdateFavoriteGamesList: TToolButton;
    LabelGameDescription: TLabel;
    ButtonClose: TButton;
    ProfileIcon: TImage;
    TopImage: TImage32;
    LabelAccessMode: TLabel;
    LabelSelectUser: TGroupBox;
    ProfileSettingsBox: TGroupBox;
    LabelUserNameDescription: TLabel;
    LabelUserNameFileName: TLabel;
    UserNameFileNameButtonSelect: TButton;
    ButtonUpdateUserProfile: TButton;
    ButtonCancel: TButton;
    UserNameFileNameButtonCopyDescription: TButton;
    UserNameDescription: TEdit;
    UserNameFileName: TEdit;
    FavProfiles: TVirtualStringTree;
    IL_FavoriteProfiles: TImageList;
    procedure ButtonNewUserClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure ButtonUpdateFavoriteGamesListClick(Sender: TObject);
    procedure ButtonUpdateUserProfileClick(Sender: TObject);
    procedure ButtonCancelClick(Sender: TObject);
    procedure UserNameFileNameButtonCopyDescriptionClick(Sender: TObject);
    procedure UserNameFileNameButtonSelectClick(Sender: TObject);
    procedure ButtonCloseClick(Sender: TObject);
    procedure UserNameDescriptionChange(Sender: TObject);
    procedure UserNameFileNameChange(Sender: TObject);
    procedure FavProfilesChange(Sender: TBaseVirtualTree;
      Node: PVirtualNode);
    procedure FavProfilesCompareNodes(Sender: TBaseVirtualTree; Node1,
      Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer);
    procedure FavProfilesFreeNode(Sender: TBaseVirtualTree;
      Node: PVirtualNode);
    procedure FavProfilesGetText(Sender: TBaseVirtualTree;
      Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType;
      var CellText: WideString);
    procedure FavProfilesGetHint(Sender: TBaseVirtualTree;
      Node: PVirtualNode; Column: TColumnIndex;
      var LineBreakStyle: TVTTooltipLineBreakStyle;
      var HintText: WideString);
    procedure FavProfilesGetImageIndex(Sender: TBaseVirtualTree;
      Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
      var Ghosted: Boolean; var ImageIndex: Integer);
    procedure FavProfilesHeaderClick(Sender: TVTHeader;
      Column: TColumnIndex; Button: TMouseButton; Shift: TShiftState; X,
      Y: Integer);
    procedure FavProfilesIncrementalSearch(Sender: TBaseVirtualTree;
      Node: PVirtualNode; const SearchText: WideString;
      var Result: Integer);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
    ProfileNode: PVirtualNode;
    ProfileData: pFavoriteProfile;
    function  GetProfileData(tNodeIndex: PVirtualNode): Boolean;
    function  SetUpdateButtonState(EditBoxHolder: TEdit; CheckDescription: Boolean): Boolean;
    procedure SelectProfileNode(NodeHolder: PVirtualNode);
    function  FindProfileNode(ProfileDescription: String): PVirtualNode;
    procedure ManageUser;
    procedure ResetBrowseMode;
  public
    { Public declarations }
  end;

var
  FormFavoriteGamesProfileEditor: TFormFavoriteGamesProfileEditor;

implementation

uses uMain, uCommon, uFilesUtil, uStatus;

{$R *.DFM}

// procedures ----------------------

function TFormFavoriteGamesProfileEditor.GetProfileData(tNodeIndex: PVirtualNode): Boolean;
begin
  Result:= False;
  if ProfileData <> nil then
     ProfileData:= nil;
  if FavProfiles.SelectedCount = 0 then
     Exit;

  ProfileData:= FavProfiles.GetNodeData(tNodeIndex);
  Result:= ProfileData <> nil;
end;

function TFormFavoriteGamesProfileEditor.SetUpdateButtonState(EditBoxHolder: TEdit; CheckDescription: Boolean): Boolean;
var
  strText: String;
begin
  Result:= ProfileData <> nil;
  if Result then
     begin
       case CheckDescription of
         True : strText:= ProfileData.fpDescription;
         False: strText:= ProfileData.fpFileName;
       end;
       Result:= (LowerCase(EditBoxHolder.Text) <> LowerCase(strText)) and
                ProfileSettingsBox.Enabled;
     end;
end;

procedure TFormFavoriteGamesProfileEditor.SelectProfileNode(NodeHolder: PVirtualNode);
begin
  if FavProfiles.TotalCount = 0 then
     Exit;
  if NodeHolder <> nil then
     begin
       FavProfiles.Selected[NodeHolder]:= True;
       FavProfiles.FocusedNode:= NodeHolder;
       FavProfiles.ScrollIntoView(NodeHolder, True);
     end;
end;

function TFormFavoriteGamesProfileEditor.FindProfileNode(ProfileDescription: String): PVirtualNode;
var
  Data: pFavoriteProfile;
  tempNode: PVirtualNode;
begin
  Result:= nil;
  tempNode:= FavProfiles.GetFirst;
  if (ProfileDescription = '') or (FavProfiles.TotalCount = 0) or (tempNode = nil) then
     Exit;
  Result:= tempNode;
  repeat
    Data:= FavProfiles.GetNodeData(tempNode);
    if Data.fpDescription <> ProfileDescription then
       tempNode:= FavProfiles.GetNext(tempNode)
    else
       Result:= tempNode;
  until (not Assigned(tempNode)) or (Data.fpDescription = ProfileDescription);
end;

procedure TFormFavoriteGamesProfileEditor.ResetBrowseMode;
begin
  KeyPreview:= True;
  FavProfiles.SetFocus;
  LabelAccessMode.Caption:= '[browse mode]';
  ProfileSettingsBox.Tag:= -1;
  ButtonCancel.Visible:= False;
  ButtonClose.Enabled:= True;
end;

procedure TFormFavoriteGamesProfileEditor.ManageUser;
var
  FavoriteIni: TMemIniFile;
  FavoriteFile: THashedStringList;
  ProfileFound: Boolean;
  Node: PVirtualNode;
  Data: pFavoriteProfile;
  IcoStr, IcoStrNew: String;
begin
  if FavProfiles.SelectedCount = 0 then
     begin
       GenerateMessage('Error', 'No user selected. Please select an user from the list and try again.', 2);
       Exit;
     end;

  // 0  -> New User
  // -1 -> Edit User
  // 2  -> Delete USer

  if ProfileSettingsBox.Tag <> 2 then
     begin
       if UserNameDescription.Text = '' then
          begin
            GenerateMessage('Error', 'Profile description is empty!', 2);
            UserNameDescription.SetFocus;
            Exit;
          end;

       if (UserNameFileName.Text = '') or
          (LowerCase(UserNameFileName.Text) = '.el') then
          begin
            GenerateMessage('Error', 'Profile filename is empty!', 2);
            UserNameFileName.SetFocus;
            Exit;
          end;
     end;
  if FormMain.CheckReadOnly(FormMain.FrontendPath+'ini_files\favorites.ini') then
     begin
       GenerateMessage('Error', 'File "'+FormMain.FrontendPath+'ini_files\favorites.ini'+
                       '" is read-only. Cannot continue...', 2);
       Exit;
     end;

  KeyPreview:= False;
  if ExtractFileExt(UserNameFileName.Text) <> '.el' then
     UserNameFileName.Text:= ChangeFileExt(UserNameFileName.Text, '.el');
  ProfileFound:= False;
  case ProfileSettingsBox.Tag of
    0: // Create a new user
      begin
        Node:= FavProfiles.GetFirst;
        repeat
          Data:= FavProfiles.GetNodeData(Node);
          if LowerCase(Data.fpFileName) = LowerCase(UserNameFileName.Text) then
             ProfileFound:= True;
          Node:= FavProfiles.GetNext(Node);
        until (Node = nil) or ProfileFound;

        case ProfileFound of
          True:
            begin
              GenerateMessage('Error', 'Another profile is already using the file "'+
                              UserNameFileName.Text+'" to store games! Please choose another name.', 2);
              UserNameFileName.SetFocus;
              Exit;
            end;
          False:
            begin
              Node:= nil;
              FavProfiles.BeginUpdate;
              Node:= FavProfiles.AddChild(nil);
              Data:= FavProfiles.GetNodeData(Node);
              Data.fpDescription:= UserNameDescription.Text;
              Data.fpFileName:= UserNameFileName.Text;
              if not FormMain.AddDefaultIcons(ChangeFileExt(Data.fpFileName, '.ico'), FormMain.GetFavoritesFolder, IL_FavoriteProfiles) then
                 FormMain.AddDefaultIcons('default.ico', FormMain.GetFavoritesFolder, IL_FavoriteProfiles);
              Data.fpImageIndex:= IL_FavoriteProfiles.Count-1;
              FavProfiles.EndUpdate;

              FavoriteIni:= TMemIniFile.Create(FormMain.FrontendPath+'ini_files\favorites.ini');
              FavoriteIni.WriteString(UserNameDescription.Text, 'File', UserNameFileName.Text);
              FavoriteIni.UpdateFile;
              FreeAndNil(FavoriteIni);
              if not FileExists(FormMain.GetFavoritesFolder+UserNameFileName.Text) then
                 begin
                   FavoriteFile:= THashedStringList.Create;
                   FavoriteFile.SaveToFile(FormMain.GetFavoritesFolder+UserNameFileName.Text);
                   FreeAndNil(FavoriteFile);
                 end;
              ResetBrowseMode;
              SelectProfileNode(FindProfileNode(Data.fpDescription));
            end;
        end;
      end;
    -1: // Edit a existing user
      begin
        Node:= FavProfiles.GetFirst;
        repeat
          Data:= FavProfiles.GetNodeData(Node);
          if LowerCase(Data.fpFileName) = LowerCase(UserNameFileName.Text) then
             ProfileFound:= True;
          Node:= FavProfiles.GetNext(Node);
        until (Node = nil) or ProfileFound;

        case ProfileFound of
          True:
            begin
              GenerateMessage('Error', 'Another profile is already using the file "'+
                              UserNameFileName.Text+'" to store games! Please choose another name.', 2);
              UserNameFileName.SetFocus;
              Exit;
            end;
          False:
            begin
              if (UserNameFileName.Text <> ProfileData.fpFileName) and
                 (not FileExists(FormMain.GetFavoritesFolder+UserNameFileName.Text)) then
                 begin
                   if not RenameFile(FormMain.GetFavoritesFolder+ProfileData.fpFileName, FormMain.GetFavoritesFolder+UserNameFileName.Text) then
                      GenerateMessage('Error', 'An error has occurred trying to rename "'+
                                      ProfileData.fpFileName+'" file to "'+FormMain.GetFavoritesFolder+UserNameFileName.Text+
                                      '". Please try again.', 2);

                   IcoStr:= ChangeFileExt(ProfileData.fpFileName, '.ico');
                   IcoStrNew:= ChangeFileExt(UserNameFileName.Text, '.ico');
                   if FileExists(FormMain.GetFavoritesFolder+IcoStr) and
                      (not FileExists(FormMain.GetFavoritesFolder+IcoStrNew)) then
                      begin
                        if not RenameFile(FormMain.GetFavoritesFolder+IcoStr, FormMain.GetFavoritesFolder+IcoStrNew) then
                           GenerateMessage('Error', 'An error has occurred trying to rename "'+
                                           FormMain.GetFavoritesFolder+IcoStr+'" icon file to "'+FormMain.GetFavoritesFolder+IcoStrNew+
                                           '". Please try again.', 2);
                      end;
                 end;
              FavoriteIni:= TMemIniFile.Create(FormMain.FrontendPath+'ini_files\favorites.ini');
              FavoriteIni.WriteString(UserNameDescription.Text, 'File', UserNameFileName.Text);
              if LowerCase(UserNameDescription.Text) <> LowerCase(ProfileData.fpDescription) then
                 begin
                   if FavoriteIni.SectionExists(ProfileData.fpDescription) then
                      FavoriteIni.EraseSection(ProfileData.fpDescription);
                 end;
              FavoriteIni.UpdateFile;
              FreeAndNil(FavoriteIni);
              FavProfiles.BeginUpdate;
              ProfileData.fpDescription:= UserNameDescription.Text;
              ProfileData.fpFileName:= UserNameFileName.Text;
              if not FormMain.SetToolBarIcon(ChangeFileExt(ProfileData.fpFileName, ''), FormMain.GetFavoritesFolder, IL_FavoriteProfiles, ProfileData.fpImageIndex, False) then
                 FormMain.SetToolBarIcon('default', FormMain.GetFavoritesFolder, IL_FavoriteProfiles, ProfileData.fpImageIndex, False);
              FavProfiles.EndUpdate;
              FavProfiles.OnChange(FavProfiles, ProfileNode);
            end;
        end;
      end;
    2: // Delete a existing user
      begin
        if GenerateMessage('Delete Profile', Format('Delete profile "%s". Are you sure ?',
                           [ProfileData.fpDescription]), 1) = mrYes then
           begin
             FavoriteIni:= TMemIniFile.Create(FormMain.FrontendPath+'ini_files\favorites.ini');
             FavoriteIni.EraseSection(ProfileData.fpDescription);
             FavoriteIni.UpdateFile;
             FreeAndNil(FavoriteIni);
             if FileExists(FormMain.GetFavoritesFolder+ProfileData.fpFileName) then
                begin
                  if GenerateMessage('Delete Favorites File', Format('Would you like to delete file "%s" ?',
                                     [FormMain.GetFavoritesFolder+
                                     ProfileData.fpFileName]), 1) = mrYes then
                     DeleteFile(FormMain.GetFavoritesFolder+ProfileData.fpFileName);
                end;

             IcoStr:= ChangeFileExt(ProfileData.fpFileName, '.ico');
             if FileExists(FormMain.GetFavoritesFolder+IcoStr) then
                begin
                  if GenerateMessage('Delete Icon File', Format('Would you like to delete the icon file "%s" ?',
                                     [FormMain.GetFavoritesFolder+
                                      IcoStr]), 1) = mrYes then
                     DeleteFile(FormMain.GetFavoritesFolder+IcoStr);
                end;

             FavProfiles.BeginUpdate;
             FavProfiles.DeleteSelectedNodes;
             FavProfiles.EndUpdate;
             SelectProfileNode(FindProfileNode('(Default)'));
             ResetBrowseMode;
             Exit;
           end;
      end;
  end;

  if not FormMain.SetToolBarIcon(ChangeFileExt(UserNameFileName.Text, ''), FormMain.GetFavoritesFolder, FormMain.IL_StatusBar, 4) then
         FormMain.SetToolBarIcon('default', FormMain.GetFavoritesFolder, FormMain.IL_StatusBar, 4);
  FormMain.StatusBar_FavoritesProfile.Hint:= 'Favorites Profile: '+FormMain.FavoriteUser;

  if not FormMain.LoadFavUserIcon128(ChangeFileExt(UserNameFileName.Text, '.ico'), ProfileIcon) then
     if not FormMain.LoadFavUserIcon128('default.ico', ProfileIcon) then
        ProfileIcon.Picture:= nil;
  ResetBrowseMode;

  with FavProfiles.Header, FavProfiles do
  begin
    SortTree(SortColumn, SortDirection, False);
    ScrollIntoView(ProfileNode, True);
  end;
end;

procedure TFormFavoriteGamesProfileEditor.ButtonNewUserClick(Sender: TObject);
begin
  KeyPreview:= False;
  ProfileSettingsBox.Tag:= TToolButton(Sender).Tag;
  ButtonClose.Enabled:= False;
  case TToolButton(Sender).Tag of
    0:
      begin
        LabelAccessMode.Caption:= '[new profile mode]';
        ProfileSettingsBox.Enabled:= True;
        ProfileSettingsBox.Caption:= 'Settings';
        ButtonUpdateUserProfile.Caption:= 'Ok';
        ButtonUpdateUserProfile.Hint:= 'Add new profile';
        ButtonCancel.Visible:= True;
        UserNameDescription.Text:= '';
        UserNameFileName.Text:= '';
        UserNameDescription.SetFocus;
      end;
    2: ManageUser;
  end;
end;

procedure TFormFavoriteGamesProfileEditor.FormShow(Sender: TObject);
var
  FavoritesIni: TMemIniFile;
  FavUsersList: THashedStringList;
  Loop: Integer;
  Node: PVirtualNode;
  Data: pFavoriteProfile;
begin
  FormMain.LoadTopBar(TopImage, 'favorites.png');
  ButtonUpdateFavoriteGamesList.Enabled:= FormMain.SelectedFilterName <> 'favorites';
  FavProfiles.NodeDataSize:= SizeOf(TFavoriteProfile);
  FavProfiles.RootNodeCount:= 0;
  FavProfiles.BeginUpdate;
  Node:= FavProfiles.AddChild(nil);
  Data:= FavProfiles.GetNodeData(Node);
  FormMain.AddDefaultIcons('default.ico', FormMain.GetFavoritesFolder, IL_FavoriteProfiles);
  Data.fpImageIndex:= 0;
  Data.fpDescription:= '(Default)';
  Data.fpFileName:= 'default.el';

  if not FormMain.CheckReadOnly(FormMain.FrontendPath+'ini_files\favorites.ini') then
     begin
       FavUsersList:= THashedStringList.Create;
       FavoritesIni:= TMemIniFile.Create(FormMain.FrontendPath+'ini_files\favorites.ini');
       FavoritesIni.ReadSections(FavUsersList);
       FavUsersList.Sort;
       if FavUsersList.Count > 0 then
          begin
            for Loop:=0 to FavUsersList.Count -1 do
            begin
              Node:= FavProfiles.AddChild(nil);
              Data:= FavProfiles.GetNodeData(Node);
              Data.fpDescription:= FavUsersList[Loop];
              Data.fpFileName:= FavoritesIni.ReadString(FavUsersList[Loop], 'File', 'default.el');
              if not FormMain.AddDefaultIcons(ChangeFileExt(Data.fpFileName, '.ico'), FormMain.GetFavoritesFolder, IL_FavoriteProfiles) then
                 FormMain.AddDefaultIcons('default.ico', FormMain.GetFavoritesFolder, IL_FavoriteProfiles);
              Data.fpImageIndex:= IL_FavoriteProfiles.Count-1;
            end;
          end;
       FreeAndNil(FavoritesIni);
       FreeAndNil(FavUsersList);
     end;
  FavProfiles.EndUpdate;
  FavProfiles.SetFocus;
  if FormMain.FavoriteUser = 'Default' then
     SelectProfileNode(FindProfileNode('(Default)'))
  else
     SelectProfileNode(FindProfileNode(FormMain.FavoriteUser));

end;

procedure TFormFavoriteGamesProfileEditor.ButtonUpdateFavoriteGamesListClick(
  Sender: TObject);
var
  FavoriteGamesList, mGamesList: THashedStringList;
  Loop, GameIndex: Integer;
  ListChanged: Boolean;
begin
  // Button Maintenance !
  if not FileExists(FormMain.GetFavoritesFolder+ProfileData.fpFileName) then
     GenerateMessage('File Not Found', 'The file "'+FormMain.GetFavoritesFolder+
                     ProfileData.fpFileName+'" was not found!', 2);

  if GetFileSize(FormMain.GetFavoritesFolder+ProfileData.fpFileName) = 0 then
     begin
       GenerateMessage('No Games', 'The profile "'+ProfileData.fpDescription+
                       '" is empty, there are no games added.', 2);
       Exit;
     end;

  if FormMain.CheckReadOnly(FormMain.GetFavoritesFolder+ProfileData.fpFileName) then
     begin
       GenerateMessage('Error', 'File "'+FormMain.GetFavoritesFolder+ProfileData.fpFileName+
                       '" is marked as read-only. Cannot continue...', 2);
       Exit;
     end;

  if GenerateMessage('Warning', 'This procedure will make changes to list of games for the "'+
                      ProfileData.fpDescription+'" profile - ['+FormMain.GetFavoritesFolder+
                      ProfileData.fpFileName+']. Unknown games will be removed.'+
                      #13#10+'Continue ?', 1) = mrNo then
     Exit;

  Application.ProcessMessages;
  Screen.Cursor:= crHourGlass;
  mGamesList:= THashedStringList.Create;
  GetGamesList(mGamesList, 1);
  GetGamesList(mGamesList, 2);
  GetGamesList(mGamesList, 3);
  GetGamesList(mGamesList, 4);
  GetGamesList(mGamesList, 5);
  GetGamesList(mGamesList, 6);

  mGamesList.BeginUpdate;
  for Loop:=0 to mGamesList.Count-1 do
  begin
    FormMain.GetROMFields(mGamesList, Loop);
    mGamesList.Strings[Loop]:= Format('%s=%s', [FormMain.mName, FormMain.GetSystemFolderName(FormMain.mROMIdentification)]);
  end;
  mGamesList.EndUpdate;

  Application.ProcessMessages;
  FavoriteGamesList:= THashedStringList.Create;
  FavoriteGamesList.LoadFromFile(FormMain.GetFavoritesFolder+ProfileData.fpFileName);

  ListChanged:= False;
  FavoriteGamesList.BeginUpdate;
  for Loop:=FavoriteGamesList.Count-1 downto 0 do
  begin
    GameIndex:= mGamesList.IndexOfName(FavoriteGamesList.Names[Loop]);
    if GameIndex = -1 then
       begin
         ListChanged:= True;
         FavoriteGamesList.Delete(Loop);
       end;
  end;
  FavoriteGamesList.EndUpdate;
  FreeAndNil(mGamesList);

  Screen.Cursor:= crDefault;
  if ListChanged then
     begin
       FavoriteGamesList.SaveToFile(FormMain.GetFavoritesFolder+ProfileData.fpFileName);
       GenerateMessage('Operation Complete', Format('"%s" profile - [%s] updated!',
                       [ProfileData.fpDescription, ProfileData.fpFileName]), 2);
     end;
  FreeAndNil(FavoriteGamesList);
end;

procedure TFormFavoriteGamesProfileEditor.ButtonUpdateUserProfileClick(
  Sender: TObject);
begin
  ManageUser;
end;

procedure TFormFavoriteGamesProfileEditor.ButtonCancelClick(
  Sender: TObject);
begin
  ButtonCancel.Visible:= False;
  ResetBrowseMode;
  FavProfiles.OnChange(FavProfiles, ProfileNode);
end;

procedure TFormFavoriteGamesProfileEditor.UserNameFileNameButtonCopyDescriptionClick(
  Sender: TObject);
begin
  if UserNameDescription.Text <> '' then
     UserNameFileName.Text:= UserNameDescription.Text+'.el';
end;

procedure TFormFavoriteGamesProfileEditor.UserNameFileNameButtonSelectClick(
  Sender: TObject);
begin
  FormMain.OpenDialog.FilterIndex:= 5;
  FormMain.OpenDialog.InitialDir:= FormMain.GetFavoritesFolder;
  if FormMain.OpenDialog.Execute then
     UserNameFileName.Text:= ExtractFileName(FormMain.OpenDialog.FileName);
end;

procedure TFormFavoriteGamesProfileEditor.ButtonCloseClick(Sender: TObject);
begin
  if ProfileSettingsBox.Tag = -1 then
     Close;
end;

procedure TFormFavoriteGamesProfileEditor.UserNameDescriptionChange(
  Sender: TObject);
begin
  ButtonUpdateUserProfile.Enabled:= SetUpdateButtonState(UserNameDescription, True);
end;

procedure TFormFavoriteGamesProfileEditor.UserNameFileNameChange(
  Sender: TObject);
begin
  ButtonUpdateUserProfile.Enabled:= SetUpdateButtonState(UserNameFileName, False);
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesChange(
  Sender: TBaseVirtualTree; Node: PVirtualNode);
begin
  if (Sender.SelectedCount = 1) and (Sender.Visible) then
     begin
       if ProfileNode <> Node then
          ProfileNode:= Node;
       GetProfileData(ProfileNode);
       ProfileSettingsBox.Enabled:= ProfileData.fpDescription <> '(Default)';
       case ProfileSettingsBox.Enabled of
         True:
           begin
             if ProfileSettingsBox.Caption <> 'Settings' then
                ProfileSettingsBox.Caption:= 'Settings';
           end;
         False: ProfileSettingsBox.Caption:= 'Settings -- [Edit is Prohibited!!]';
       end;
       ButtonDeleteUser.Enabled:= ProfileSettingsBox.Enabled;

       if ProfileData.fpDescription = '(Default)' then
          FormMain.FavoriteUser:= 'Default'
       else
          FormMain.FavoriteUser:= ProfileData.fpDescription;

       if UserNameFileName.Text <> ProfileData.fpFileName then
          begin
            FormMain.FavoriteUserFile:= ProfileData.fpFileName;
            UserNameDescription.Text:= ProfileData.fpDescription;
            UserNameFileName.Text:= ProfileData.fpFileName;
            if not FormMain.LoadFavUserIcon128(ChangeFileExt(ProfileData.fpFileName, '.ico'), ProfileIcon) then
               if not FormMain.LoadFavUserIcon128('default.ico', ProfileIcon) then
                  ProfileIcon.Picture:= nil;
            if not FormMain.SetToolBarIcon(ChangeFileExt(ProfileData.fpFileName, ''), FormMain.GetFavoritesFolder, FormMain.IL_StatusBar, 4, False) then
               FormMain.SetToolBarIcon('default', FormMain.GetFavoritesFolder, FormMain.IL_StatusBar, 4, False);
            FormMain.StatusBar_FavoritesProfile.Hint:= 'Favorites Profile: '+FormMain.FavoriteUser;

            if not FormMain.SetToolBarIcon(ChangeFileExt(ProfileData.fpFileName, ''), FormMain.GetFavoritesFolder, FormMain.IL_MenuPopup, 3, False) then
               FormMain.SetToolBarIcon('default', FormMain.GetFavoritesFolder, FormMain.IL_MenuPopup, 3, False);
          end;
     end;
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesCompareNodes(
  Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode;
  Column: TColumnIndex; var Result: Integer);
var
  Data1, Data2: pFavoriteProfile;
begin
  Data1:= Sender.GetNodeData(Node1);
  Data2:= Sender.GetNodeData(Node2);
  if Column = 0 then
     Result:= CompareText(Data1.fpDescription, Data2.fpDescription);
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesFreeNode(
  Sender: TBaseVirtualTree; Node: PVirtualNode);
var
  Data: pFavoriteProfile;
begin
  Data:= Sender.GetNodeData(Node);
  Finalize(Data^);
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesGetText(
  Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
  TextType: TVSTTextType; var CellText: WideString);
var
  Data: pFavoriteProfile;
begin
  Data:= Sender.GetNodeData(Node);
  if Column = 0 then
     CellText:= Data.fpDescription;
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesGetHint(
  Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex;
  var LineBreakStyle: TVTTooltipLineBreakStyle; var HintText: WideString);
var
  Data: pFavoriteProfile;
begin
  Data:= Sender.GetNodeData(Node);
  if Column = 0 then
     HintText:= ProfileData.fpDescription;
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesGetImageIndex(
  Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind;
  Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
var
  Data: pFavoriteProfile;
begin
  if Kind in [ikNormal, ikSelected] then
     begin
       if Column = 0 then
          begin
            Data:= FavProfiles.GetNodeData(Node);
            ImageIndex:= Data.fpImageIndex;
          end;
     end;
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesHeaderClick(
  Sender: TVTHeader; Column: TColumnIndex; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbLeft then
     begin
       with Sender, Treeview do
       begin
         if SortColumn > NoColumn then
            Columns[SortColumn].Options:= Columns[SortColumn].Options + [coParentColor];
         if (SortColumn = NoColumn) or (SortColumn <> Column) then
            begin
              SortColumn:= Column;
              SortDirection:= sdAscending;
            end
         else
            if SortDirection = sdAscending then
               SortDirection:= sdDescending
            else
               SortDirection:= sdAscending;
         SortTree(SortColumn, SortDirection, False);
       end;
     end;
end;

procedure TFormFavoriteGamesProfileEditor.FavProfilesIncrementalSearch(
  Sender: TBaseVirtualTree; Node: PVirtualNode;
  const SearchText: WideString; var Result: Integer);
var
  StringsText,
  EntryText: String;
  Data: pFavoriteProfile;
begin
  StringsText:= SearchText;
  Data:= Sender.GetNodeData(Node);
  EntryText:= Data.fpDescription;
  Result:= AnsiStrLIComp(PChar(StringsText), PChar(EntryText), Length(StringsText));
end;

procedure TFormFavoriteGamesProfileEditor.FormKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if Key = VK_ESCAPE then
     Close;
end;

procedure TFormFavoriteGamesProfileEditor.FormCreate(Sender: TObject);
begin
  FormMain.SetAlphaBlendTreeView(FavProfiles);
end;

end.
