{
     Apophysis Copyright (C) 2001-2004 Mark Townsend
     Apophysis Copyright (C) 2005-2006 Ronald Hordijk, Piotr Borys, Peter Sdobnov
     Apophysis Copyright (C) 2007-2008 Piotr Borys, Peter Sdobnov
     
     Apophysis "3D hack" Copyright (C) 2007-2008 Peter Sdobnov
     Apophysis "7X" Copyright (C) 2009-2010 Georg Kiehne
     Apophysis AV "Phoenix Edition" Copyright (C) 2021-2022 Alice V. Koryagina

     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.

     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.

     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
}
unit Settings;

interface

uses Graphics;

function ReadPluginDir: string;
procedure ReadSettings;
procedure SaveSettings;

implementation

uses
  Windows, Classes, SysUtils, StrUtils, Forms, Registry, Global, Dialogs,
  XFormMan;

(*
function ReadPluginDir: string;
var
    settingFileName: string;
    sl : TStringList;
begin
    sl := TStringList.Create;

    settingFileName := ExtractFilePath(Application.ExeName) + 'ApoPluginSrc.dat';
    if FileExists(settingFileName) then
      sl.LoadFromFile(settingFileName)
    else begin
      settingFileName := GetEnvVarValue('APPDATA') + '\ApoPluginSrc.dat';

      if FileExists(settingFileName) then
        sl.LoadFromFile(settingFileName)
      else
        sl.Text := ExtractFilePath(Application.ExeName) + 'Plugins\';
    end;

    if Trim(sl.Text) = '' then
      sl.Text := ExtractFilePath(Application.ExeName) + 'Plugins\';

    Result := Trim(sl.Text);
    if (RightStr(Result, 1) <> '\') and (Result <> '') then
      Result := Result + '\';

    sl.Free;
end;

procedure SavePluginDir(data: string);
  var
    settingFileName: string;
    sl : TStringList;
  begin
    settingFileName := ExtractFilePath(Application.ExeName) + 'ApoPluginSrc.dat';
    sl := TStringList.Create;
    sl.Text := PluginPath;

    try
      sl.SaveToFile(settingFileName);
      sl.Destroy;
    except
      // not elevated?
      settingFileName := GetEnvVarValue('APPDATA') + '\ApoPluginSrc.dat';
      try
        sl.SaveToFile(settingFileName);
      except
        MessageBox(0, PCHAR(TextByKey('main-status-pluginpath-ioerror')),
          PCHAR('Apophysis'), MB_ICONWARNING);
      end;
      sl.Free;
    end;
end;
*)

// AV: rewrote to save the plugin directory in the Windows registry
// because this 'ApoPluginSrc.dat' always resets my settings!
function ReadPluginDir: string;
var
    Registry: TRegistry;
    plugdir: string;
begin
  plugdir := ExtractFilePath(Application.ExeName) + 'Plugins\';
  Result := plugdir;
  Registry := TRegistry.Create;
  try
      Registry.RootKey := HKEY_CURRENT_USER;
      if Registry.OpenKey('Software\' + APP_NAME + '\Defaults', False) then
      begin
        if Registry.ValueExists('PluginPath') then
        begin
          Result := Trim(Registry.ReadString('PluginPath'));
          if (RightStr(Result, 1) <> '\') and (Result <> '') then
            Result := Result + '\';
        end
        else
          Result := plugdir;

        Registry.CloseKey;
      end
      else
        Result := plugdir;
  finally
    Registry.Free;

    if (Result = '') or (not DirectoryExists(Result)) then
      Result := ExtractFilePath(Application.ExeName);  // AV
  end;
end;

procedure ReadSettings;
var
  Registry: TRegistry;
  DefaultPath: string;
  i: integer;
  VarUsed: byte;
begin
  // DefaultPath :=  GetEnvVarValue('USERPROFILE');
  DefaultPath := AppPath; // AV: backward compatibility is more convenient
  PluginPath := ReadPluginDir;  // AV
  Registry := TRegistry.Create;
  try
    Registry.RootKey := HKEY_CURRENT_USER;

    { Defaults }
    if Registry.OpenKey('Software\' + APP_NAME + '\Defaults', False) then
    begin
      if Registry.ValueExists('DefaultFlameFile3D') then
        defFlameFile := Registry.ReadString('DefaultFlameFile3D')
      else 
        defFlameFile := '';

      if Registry.ValueExists('AlwaysCreateBlankFlame') then
        AlwaysCreateBlankFlame := Registry.ReadBool('AlwaysCreateBlankFlame')
      else
        AlwaysCreateBlankFlame := false;

      if Registry.ValueExists('GradientFile') then
        GradientFile := Registry.ReadString('GradientFile')
      else
        GradientFile := '';

      if Registry.ValueExists('SavePath3D') then
        SavePath := Registry.ReadString('SavePath3D')
      else 
        SavePath := DefaultPath + 'Flames.flame';

      if Registry.ValueExists('RandomizeTemplates') then
        RandomizeTemplates := Registry.ReadBool('RandomizeTemplates')
      else
        RandomizeTemplates := True;

      if Registry.ValueExists('WarnOnMissingPlugin') then
        WarnOnMissingPlugin := Registry.ReadBool('WarnOnMissingPlugin')
      else WarnOnMissingPlugin := true;

      if Registry.ValueExists('SetEnglishLayout') then
        SetEngLayout := Registry.ReadBool('SetEnglishLayout')
      else SetEngLayout := false;

      if Registry.ValueExists('ApplyFlatten') then
        ApplyFlatten := Registry.ReadBool('ApplyFlatten')
      else ApplyFlatten := true;

      if Registry.ValueExists('LanguageFile') then
        LanguageFile := Registry.ReadString('LanguageFile')
      else LanguageFile := '';

      if Registry.ValueExists('SmoothPaletteFile') then
        defSmoothPaletteFile := Registry.ReadString('SmoothPaletteFIle')
      else
        defSmoothPaletteFile := DefaultPath + 'Gradients\SmoothPalette.ugr';

      if Registry.ValueExists('PlaySoundOnRenderComplete') then
        PlaySoundOnRenderComplete := Registry.ReadBool('PlaySoundOnRenderComplete')
      else
        PlaySoundOnRenderComplete := false;
      if Registry.ValueExists('RenderCompleteSoundFile') then
        RenderCompleteSoundFile := Registry.ReadString('RenderCompleteSoundFile')
      else
        RenderCompleteSoundFile := '';

      if Registry.ValueExists('ConfirmDelete') then
        ConfirmDelete := Registry.ReadBool('ConfirmDelete')
      else
        ConfirmDelete := True;
      if Registry.ValueExists('OldPaletteFormat') then
        OldPaletteFormat := Registry.ReadBool('OldPaletteFormat')
      else
        OldPaletteFormat := false;

      if Registry.ValueExists('ConfirmExit') then
        ConfirmExit := Registry.ReadBool('ConfirmExit')
      else
        ConfirmExit := True;

      if Registry.ValueExists('ConfirmClearScript') then  // AV
        ConfirmClearScript := Registry.ReadBool('ConfirmClearScript')
      else
        ConfirmClearScript := False;

      if Registry.ValueExists('ConfirmResetUndo') then  // AV
        ConfirmResetUndo := Registry.ReadBool('ConfirmResetUndo')
      else
        ConfirmResetUndo := False;

      if Registry.ValueExists('PreserveQuality') then
        PreserveQuality := Registry.ReadBool('PreserveQuality')
      else
        PreserveQuality := true;

      if Registry.ValueExists('KeepBackground') then
        KeepBackground := Registry.ReadBool('KeepBackground')
      else
        KeepBackground := False;

      if Registry.ValueExists('NumTries') then
        NumTries := Registry.ReadInteger('NumTries')
      else
        NumTries := 10;
      if Registry.ValueExists('TryLength') then
        TryLength := Registry.ReadInteger('TryLength')
      else
        TryLength := 100000;

      if Registry.ValueExists('MinTransforms') then
      begin
        randMinTransforms := Registry.ReadInteger('MinTransforms');
        if randMinTransforms < 2 then randMinTransforms := 2;
      end
      else
        randMinTransforms := 2;
		
      if Registry.ValueExists('MaxTransforms') then
      begin
        randMaxTransforms := Registry.ReadInteger('MaxTransforms');
        if randMaxTransforms < randMinTransforms then randMaxTransforms := randMinTransforms;
      end
      else
        randMaxTransforms := randMinTransforms + 1;

      if Registry.ValueExists('MutationMinTransforms') then
      begin
        mutantMinTransforms := Registry.ReadInteger('MutationMinTransforms');
        if mutantMinTransforms < 2 then mutantMinTransforms := 2;
      end
      else
        mutantMinTransforms := 2;

      if Registry.ValueExists('MutationMaxTransforms') then
      begin
        mutantMaxTransforms := Registry.ReadInteger('MutationMaxTransforms');
        if mutantMaxTransforms < mutantMinTransforms then mutantMinTransforms := mutantMinTransforms;
      end
      else
        mutantMaxTransforms := mutantMinTransforms + 1;

      if Registry.ValueExists('RandomGradient') then
        randGradient := Registry.ReadInteger('RandomGradient')
      else
        randGradient := 0;

      if Registry.ValueExists('ParameterFolder3D') then
        ParamFolder := Registry.ReadString('ParameterFolder3D')
      else
        ParamFolder := DefaultPath;

      if Registry.ValueExists('UPRPath') then
        UPRPath := Registry.ReadString('UPRPath')
      else
        UPRPath := DefaultPath + 'ApophysisAV_export.upr'; // AV

      if Registry.ValueExists('ImageFolder') then
        ImageFolder := Registry.ReadString('ImageFolder')
      else
        ImageFolder := GetEnvVarValue('USERPROFILE') + '\Pictures\';  // AV

      if Registry.ValueExists('ScreenshotsFolder') then   // AV
        ScreenShotPath := Registry.ReadString('ScreenshotsFolder')
      else
        ScreenShotPath := DefaultPath + 'ScreenShots\';

     if Registry.ValueExists('DefaultScript') then   // AV
        defScriptFile := Registry.ReadString('DefaultScript')
      else
        defScriptFile := '';

     if Registry.ValueExists('AutoSaveXML') then   // AV
        AutoSaveXML := Registry.ReadBool('AutoSaveXML')
      else
        AutoSaveXML := true;

      if Registry.ValueExists('UPRWidth') then
        UPRWidth := Registry.ReadInteger('UPRWidth')
      else
        UPRWidth := 640;

      if Registry.ValueExists('UPRHeight') then
        UPRHeight := Registry.ReadInteger('UPRHeight')
      else
        UPRHeight := 480;

      if Registry.ValueExists('BrowserPath') then
        BrowserPath := Registry.ReadString('BrowserPath')
      else
        BrowserPath := DefaultPath;

      if Registry.ValueExists('EditPreviewQaulity') then
        EditPrevQual := Registry.ReadInteger('EditPreviewQaulity')
      else
        EditPrevQual := 1;

      if Registry.ValueExists('MutatePreviewQaulity') then
        MutatePrevQual := Registry.ReadInteger('MutatePreviewQaulity')
      else
        MutatePrevQual := 0; // AV: hack, to speed up the calculations

      if Registry.ValueExists('AdjustPreviewQaulity') then
        AdjustPrevQual := Registry.ReadInteger('AdjustPreviewQaulity')
      else
        AdjustPrevQual := 1;

      if Registry.ValueExists('ThumbPrevQuality') then  // AV
        ThumbPrevQual := Registry.ReadInteger('ThumbPrevQuality')
      else
        ThumbPrevQual := 1;

      if Registry.ValueExists('AnimPrevQuality') then  // AV
        AnimPrevQual := Registry.ReadInteger('AnimPrevQuality')
      else
        AnimPrevQual := 1;

      if Registry.ValueExists('RandomPrefix') then
        RandomPrefix := Registry.ReadString('RandomPrefix')
      else
        RandomPrefix := 'ApoAV-';
      if Registry.ValueExists('RandomDate') then
        RandomDate := Registry.ReadString('RandomDate')
      else
        RandomDate := '';
      if Registry.ValueExists('RandomIndex') then
        RandomIndex := Registry.ReadInteger('RandomIndex')
      else
        RandomIndex := 0;

      if Registry.ValueExists('SymmetryType') then
        SymmetryType := Registry.ReadInteger('SymmetryType')
      else
        SymmetryType := 0;

      if Registry.ValueExists('SymmetryOrder') then
        SymmetryOrder := Registry.ReadInteger('SymmetryOrder')
      else
        SymmetryOrder := 4;

      if Registry.ValueExists('SymmetryNVars') then
        SymmetryNVars := Registry.ReadInteger('SymmetryNVars')
      else
        SymmetryNVars := 12;

      if Registry.ValueExists('RandBackColor') then
        RandBackColor := Registry.ReadInteger('RandBackColor')
      else
        RandBackColor := $000000;

      if Registry.ValueExists('MinNodes') then
      begin
        MinNodes := Registry.ReadInteger('MinNodes');
        if MinNodes < 2 then MinNodes := 2;
      end
      else
        MinNodes := 2;

      if Registry.ValueExists('MinHue') then
        MinHue := Registry.ReadInteger('MinHue')
      else
        MinHue := 0;

      if Registry.ValueExists('MinSat') then
        MinSat := Registry.ReadInteger('MinSat')
      else
        MinSat := 0;

      if Registry.ValueExists('MinLum') then
        MinLum := Registry.ReadInteger('MinLum')
      else
        MinLum := 0;

      if Registry.ValueExists('MaxNodes') then
      begin
        MaxNodes := Registry.ReadInteger('MaxNodes');
        if MaxNodes < MinNodes then MaxNodes := MinNodes;
      end
      else
        MaxNodes := 10;

      if Registry.ValueExists('MaxHue') then
      begin
        MaxHue := Registry.ReadInteger('MaxHue');
        if MaxHue < 0 then MaxHue := 0;
      end
      else
        MaxHue := 600;

      if Registry.ValueExists('MaxSat') then
      begin
        MaxSat := Registry.ReadInteger('MaxSat');
        if MaxSat < 0 then MaxSat := 0;
      end
      else
        MaxSat := 100;

      if Registry.ValueExists('EqualStripes') then   // AV
        EqualStripes := Registry.ReadBool('EqualStripes')
      else
        EqualStripes := True; // gradient color stripes' width

      if Registry.ValueExists('ColorBlendType') then   // AV
        randColorBlend := Registry.ReadInteger('ColorBlendType')
      else
        randColorBlend := 0; // RGB-blending

      if Registry.ValueExists('RandomGradientFile') then
        randGradientFile := Registry.ReadString('RandomGradientFile')
      else
        randGradientFile := '';

      if Registry.ValueExists('RotationMode') then
        MainForm_RotationMode := Registry.ReadInteger('RotationMode')
      else MainForm_RotationMode := 0;

      if Registry.ValueExists('EnumerationMode') then  // AV
        FlameEnumMode := Registry.ReadInteger('EnumerationMode')
      else FlameEnumMode := 0;

      if Registry.ValueExists('MaxLum') then
      begin
        MaxLum := Registry.ReadInteger('MaxLum');
        if MaxLum <= 0 then MaxLum := 100;
      end
      else
        MaxLum := 100;

      if Registry.ValueExists('BatchSize') then
      begin
        BatchSize := Registry.ReadInteger('BatchSize');
        if BatchSize <= 0 then BatchSize := 10;
      end
      else
        BatchSize := 10;

      if Registry.ValueExists('ScriptPath') then
        ScriptPath := Registry.ReadString('ScriptPath')
      else
        ScriptPath := DefaultPath + 'Scripts\';

      if Registry.ValueExists('FunctionLibrary') then
        defLibrary := Registry.ReadString('FunctionLibrary')
      else  // AV: moved back into the scripting folder
        defLibrary := DefaultPath + 'Scripts\Functions.asc';  

      if Registry.ValueExists('ExportFileFormat') then
        ExportFileFormat := Registry.ReadInteger('ExportFileFormat')
      else
        ExportFileFormat := 1;

      if Registry.ValueExists('ExportWidth') then
      begin
        ExportWidth := Registry.ReadInteger('ExportWidth');
        if ExportWidth <= 0 then ExportWidth := 640;
      end
      else
        ExportWidth := 640;

      if Registry.ValueExists('ExportHeight') then
      begin
        ExportHeight := Registry.ReadInteger('ExportHeight');
        if ExportHeight <= 0 then ExportHeight := 480;
      end
      else
        ExportHeight := 480;

      if Registry.ValueExists('ExportDensity') then
      begin
        ExportDensity := Registry.ReadFloat('ExportDensity');
        if ExportDensity <= 0 then ExportDensity := 100;
      end
      else
        ExportDensity := 100;

      if Registry.ValueExists('ExportOversample') then
      begin
        ExportOversample := Registry.ReadInteger('ExportOversample');
        if ExportOversample <= 0 then ExportOversample := 2;
      end
      else
        ExportOversample := 2;

      if Registry.ValueExists('ExportFilter') then
      begin
        ExportFilter := Registry.ReadFloat('ExportFilter');
        if ExportFilter <= 0 then ExportFilter := 0.6;
      end
      else
        ExportFilter := 0.6;

    // AV: don't need to waste our time for these properties
    (*
      if Registry.ValueExists('ExportBatches') then
      begin
        ExportBatches := Registry.ReadInteger('ExportBatches');
        if ExportBatches <= 0 then ExportBatches := 3;
      end
      else
        ExportBatches := 3;

      if Registry.ValueExists('Nick') then
      begin
        SheepNick := Registry.ReadString('Nick');
      end
      else
      begin
        SheepNick := '';
      end;
      if Registry.ValueExists('URL') then
      begin
        SheepURL := Registry.ReadString('URL');
      end
      else
      begin
        SheepURL := '';
      end;
      if Registry.ValueExists('Pass') then
      begin
        SheepPW := Registry.ReadString('Pass');
      end
      else
      begin
        SheepPW := '';
      end;
	  if Registry.ValueExists('Server') then
      begin
        SheepServer := Registry.ReadString('Server');
      end
      else
      begin
        SheepServer := 'http://v2d5.sheepserver.net/';
      end;
	  *)
	  
      if Registry.ValueExists('Renderer') then
        flam3Path := Registry.ReadString('Renderer')
      else
        flam3Path := GetEnvVarValue('PROGRAMFILES') + '\flam3-3.0.1\flam3-render.exe';  // AV

      if Registry.ValueExists('ShowProgress') then
        ShowProgress := Registry.ReadBool('ShowProgress')
      else 
        ShowProgress := true;

      if Registry.ValueExists('LineCenterColor') then
        LineCenterColor := Registry.ReadInteger('LineCenterColor')
      else 
        LineCenterColor := $FFFFFF;

      if Registry.ValueExists('LineThirdsColor') then
        LineThirdsColor := Registry.ReadInteger('LineThirdsColor')
      else 
        LineThirdsColor := $0000FF;

      if Registry.ValueExists('LineGRColor') then
        LineGRColor := Registry.ReadInteger('LineGRColor')
      else 
        LineGRColor := $00FF00;

      if Registry.ValueExists('EnableGuides') then
        EnableGuides := Registry.ReadBool('EnableGuides')
      else
        EnableGuides := false;

      { FormRender }
      if Registry.ValueExists('SaveIncompleteRenders') then 
        SaveIncompleteRenders := Registry.ReadBool('SaveIncompleteRenders')
      else 
        SaveIncompleteRenders := false;

      if Registry.ValueExists('ShowRenderStats') then
        ShowRenderStats := Registry.ReadBool('ShowRenderStats')
      else
        ShowRenderStats := false;
      if Registry.ValueExists('ShowRenderImage') then  // AV
        ShowRenderImage := Registry.ReadBool('ShowRenderImage')
      else
        ShowRenderImage := false;
      if Registry.ValueExists('LowerRenderPriority') then
        LowerRenderPriority := Registry.ReadBool('LowerRenderPriority')
      else
        LowerRenderPriority := false;

      if Registry.ValueExists('PNGTransparency') then begin
        PNGTransparency := Registry.ReadInteger('PNGTransparency');
        if PNGTransparency > 1 then PNGTransparency := 1; // tmp
      end else 
        PNGTransparency := 0;

      if Registry.ValueExists('ShowTransparency') then 
        ShowTransparency := Registry.ReadBool('ShowTransparency')
      else 
        ShowTransparency := False;

      if Registry.ValueExists('ExtendMainPreview') then
        ExtendMainPreview := Registry.ReadBool('ExtendMainPreview')
      else 
        ExtendMainPreview := true;

      if Registry.ValueExists('MainPreviewScale') then begin
        MainPreviewScale := Registry.ReadFloat('MainPreviewScale');
        if MainPreviewScale < 1 then MainPreviewScale := 1
        else if MainPreviewScale > 3 then MainPreviewScale := 3;
      end else 
        MainPreviewScale := 1.2;

      if Registry.ValueExists('NrTreads') then begin
        NrTreads := Registry.ReadInteger('NrTreads');
        if NrTreads < 1 then NrTreads := 1;  // AV
      end else
        NrTreads := 1;

      if Registry.ValueExists('UseNrThreads') then begin
        UseNrThreads := Registry.ReadInteger('UseNrThreads');
        if UseNrThreads < 1 then UseNrThreads := 1;
      end else
        UseNrThreads := 1;
		
	(*
	  if Registry.ValueExists('StartupCheckForUpdates') then begin
        StartupCheckForUpdates := Registry.ReadBool('StartupCheckForUpdates');
      end else begin
        StartupCheckForUpdates := true;
      end;
	 *)

      // AV: animation defaults
      if Registry.ValueExists('AnimPrefix') then
        defAnimPrefix := Registry.ReadString('AnimPrefix')
      else
        defAnimPrefix := 'animate-';
      if Registry.ValueExists('AnimFPS') then
        AnimFPS := Registry.ReadInteger('AnimFPS')
      else
        AnimFPS := 25;
      if Registry.ValueExists('FrameExt') then
        defFrameExt := Registry.ReadInteger('FrameExt')
      else
        defFrameExt := 1;
      if Registry.ValueExists('CreateAnimFolder') then
        CreateAnimFolder := Registry.ReadBool('CreateAnimFolder')
      else
        CreateAnimFolder := True;

      if Registry.ValueExists('AutoOpenLog') then
        AutoOpenLog := Registry.ReadBool('AutoOpenLog')
      else
        AutoOpenLog := false;

      if Registry.ValueExists('ClassicListMode') then
        ClassicListMode := Registry.ReadBool('ClassicListMode')
      else
        ClassicListMode := true;

      if Registry.ValueExists('LastOpenFile') then
        LastOpenFile := Registry.ReadString('LastOpenFile')
      else
        LastOpenFile := '';

      if Registry.ValueExists('LastOpenFileEntry') then
        LastOpenFileEntry := Registry.ReadInteger('LastOpenFileEntry')
      else
        LastOpenFileEntry := 1;

      if Registry.ValueExists('RememberLastOpenFile') then 
        RememberLastOpenFile := Registry.ReadBool('RememberLastOpenFile')
      else 
        RememberLastOpenFile := false;

      if Registry.ValueExists('UseSmallThumbnails') then 
        UseSmallThumbnails := Registry.ReadBool('UseSmallThumbnails')
      else 
        UseSmallThumbnails := true;
		
      if Registry.ValueExists('HelpPath') then 
        HelpPath := Registry.ReadString('HelpPath')
      else 
        HelpPath := DefaultPath + 'Apophysis AV.chm'; // TODO

      if Registry.ValueExists('ChaoticaPath') then
        ChaoticaPath := Registry.ReadString('ChaoticaPath')
      else 
        ChaoticaPath := '';
      {
      if Registry.ValueExists('UseX64IfPossible') then
        UseX64IfPossible := Registry.ReadBool('UseX64IfPossible')
      else 
        UseX64IfPossible := false;
      }
    end
    else
    begin
      // StartupCheckForUpdates := true;
      AlwaysCreateBlankFlame := false;
      MainForm_RotationMode := 0;
      FlameEnumMode := 0;  // AV
      EditPrevQual := 1;
      MutatePrevQual := 0;  // AV: hack, to speed up the calculations
      AdjustPrevQual := 1;
      ThumbPrevQual := 1; // AV
      AnimPrevQual := 1; // AV
      GradientFile := '';
      defFlameFile := '';
      SavePath := DefaultPath + 'Flames.flame';
      WarnOnMissingPlugin := true;
      SetEngLayout := false;
      ApplyFlatten := true;
      LanguageFile := '';
      HelpPath := DefaultPath + 'Apophysis AV.chm';
      defSmoothPaletteFile := DefaultPath + 'Gradients\SmoothPalette.ugr';
      ConfirmDelete := True;
      ConfirmExit := True;
      ConfirmClearScript := False; // AV
      ConfirmResetUndo := False;   // AV
      OldPaletteFormat := false;
      NumTries := 10;
      TryLength := 100000;
      randMinTransforms := 2;
      randMaxTransforms := 3;
      mutantMinTransforms := 2;
      mutantMaxTransforms := 6;
      randGradient := 0;
      PreserveQuality := false;
      KeepBackground := False;
      RandBackColor := $000000;
      RandomizeTemplates := True;
      UPRPath := DefaultPath + 'ApophysisAV_export.upr'; // AV
      ImageFolder := GetEnvVarValue('USERPROFILE') + '\Pictures\'; // AV
      ParamFolder := DefaultPath;
      ScreenShotPath := DefaultPath + 'ScreenShots\';  // AV
      defScriptFile := '';  // AV
      AutoSaveXML := True;  // AV
      UPRWidth := 640;
      UPRHeight := 480;
      AnimFPS := 25;
      defFrameExt := 1;
      defAnimPrefix := 'animate-';
      CreateAnimFolder := True;
      RandomPrefix := 'ApoAV-';
      RandomIndex := 0;
      RandomDate := '';
      SymmetryType := 0;
      SymmetryOrder := 4;
      SymmetryNVars := 12;
      MinNodes := 2;
      MaxNodes := 10;
      MinHue := 0;
      MinSat := 0;
      MinLum := 0;
      MaxHue := 600;
      MaxSat := 100;
      MaxLum := 100;
      randGradientFile := '';
      randColorBlend := 0; // AV
      EqualStripes := True; // AV
      BatchSize := 10;
      ScriptPath := DefaultPath + 'Scripts\';
      defLibrary := DefaultPath + 'Scripts\Functions.asc';  // AV
      ExportFileFormat := 1;
      ExportWidth := 640;
      ExportHeight := 480;
      ExportDensity := 100;
      ExportOversample := 2;
      ExportFilter := 0.6;
	  (*
      ExportBatches := 3;
      SheepNick := '';
      SheepURL := '';
      SheepPW := '';
      SheepServer := 'http://v2d5.sheepserver.net/';
	  *)
	    flam3Path := GetEnvVarValue('PROGRAMFILES') + '\flam3-3.0.1\flam3-render.exe';  // AV
      ShowProgress := true;
      SaveIncompleteRenders := false;
      LowerRenderPriority := false;
      ShowRenderStats := false;
      ShowRenderImage := false;
      PNGTransparency := 0;
      ShowTransparency := False;
      MainPreviewScale := 1.2;
      ExtendMainPreview := true;
      NrTreads := 1;
      UseNrThreads := 1;
      AutoOpenLog := false;
      ClassicListMode := true;
      LastOpenFile := '';
      LastOpenFileEntry := 1;
      RememberLastOpenFile := false;
      UseSmallThumbnails := true;
      LineCenterColor := $FFFFFF;
      LineThirdsColor := $0000FF;
      LineGRColor := $00FF00;
      EnableGuides := false;
      ChaoticaPath := '';
      //UseX64IfPossible := false;
    end;
    Registry.CloseKey;

    SetLength(Variations, NRVAR);
    SetLength(FavouriteVariations, NRVAR);  // AV
    if Registry.OpenKey('Software\' + APP_NAME + '\Variations', False) then
    begin
      for i := 0 to NRVAR-1 do
      begin
        if Registry.ValueExists(Varnames(i)) then
        begin
          VarUsed := Registry.ReadInteger(Varnames(i));
          Variations[i] := (VarUsed and 1) <> 0;
          FavouriteVariations[i] := (VarUsed and 2) <> 0;
        end
        else
          Variations[i] := false;
      end;
    end
    else begin
       // AV: we dont't need multiple z- and pre_ variations by default...
       Variations[0] := True;  // linear
       Variations[3] := True;  // spherical
       for i := 10 to 14 do
          Variations[i] := True;
       Variations[46] := True;  // pdj
       Variations[47] := True;  // julian
    end;
    Registry.CloseKey;

    { Editor } // --Z-- moved from EditForm
    if Registry.OpenKey('Software\' + APP_NAME + '\Forms\Editor', False) then
    begin
      if Registry.ValueExists('UseTransformColors') then
        UseTransformColors := Registry.ReadBool('UseTransformColors')
      else
        UseTransformColors := False;
      if Registry.ValueExists('HelpersEnabled') then
        HelpersEnabled := Registry.ReadBool('HelpersEnabled')
      else
        HelpersEnabled := true;
      if Registry.ValueExists('ShowAllXforms') then
        ShowAllXforms := Registry.ReadBool('ShowAllXforms')
      else
        ShowAllXforms := true;

      if Registry.ValueExists('AllowResetCoefs') then  // AV
        AllowResetCoefs := Registry.ReadBool('AllowResetCoefs')
      else
        AllowResetCoefs := false;
      if Registry.ValueExists('AllowResetLinear') then  // AV
        AllowResetLinear := Registry.ReadBool('AllowResetLinear')
      else
        AllowResetLinear := true;
      if Registry.ValueExists('SyncTriangles') then  // AV
        UseTriangleSync := Registry.ReadBool('SyncTriangles')
      else
        UseTriangleSync := false;

      if Registry.ValueExists('EnableEditorPreview') then
        EnableEditorPreview := Registry.ReadBool('EnableEditorPreview')
      else
        EnableEditorPreview := false;
      if Registry.ValueExists('EditorPreviewTransparency') then
        EditorPreviewTransparency := Registry.ReadInteger('EditorPreviewTransparency')
      else
        EditorPreviewTransparency := 192;

      if Registry.ValueExists('BackgroundColor') then
        EditorBkgColor := Registry.ReadInteger('BackgroundColor')
      else
        EditorBkgColor := integer(clBlack);
      if Registry.ValueExists('GridColor1') then
        GridColor1 := Registry.ReadInteger('GridColor1')
      else
        GridColor1 := $444444;
      if Registry.ValueExists('GridColor2') then
        GridColor2 := Registry.ReadInteger('GridColor2')
      else
        GridColor2 := $333333;
      if Registry.ValueExists('HelpersColor') then
        HelpersColor := Registry.ReadInteger('HelpersColor')
      else
        HelpersColor := $808080;
      if Registry.ValueExists('ReferenceTriangleColor') then
        ReferenceTriangleColor := Registry.ReadInteger('ReferenceTriangleColor')
      else
        ReferenceTriangleColor := $7f7f7f;
      if Registry.ValueExists('FlipColor') then
        FlipColor := Registry.ReadInteger('FlipColor')
      else
        FlipColor := $808080;
      if Registry.ValueExists('ExtendedEdit') then
        ExtEditEnabled := Registry.ReadBool('ExtendedEdit')
      else ExtEditEnabled := true;
      if Registry.ValueExists('LockTransformAxis') then
        TransformAxisLock := Registry.ReadBool('LockTransformAxis')
      else TransformAxisLock := true;
      if Registry.ValueExists('RebuildXaosLinks') then
        RebuildXaosLinks := Registry.ReadBool('RebuildXaosLinks')
      else RebuildXaosLinks := true;
    end
    else begin
      UseTransformColors := false;
      HelpersEnabled := true;
      ShowAllXforms := true;
      EnableEditorPreview := false;
      EditorPreviewTransparency := 192;
      EditorBkgColor := $000000;
      GridColor1 := $444444;
      GridColor2 := $333333;
      HelpersColor := $808080;
      FlipColor := $808080;
      ReferenceTriangleColor := integer(clGray);
      ExtEditEnabled := true;
      TransformAxisLock := true;
      RebuildXaosLinks := true;
      AllowResetCoefs := false;  // AV
      AllowResetLinear := true;  // AV
      UseTriangleSync := false;  // AV
    end;
    Registry.CloseKey;

    { Render }
    if Registry.OpenKey('Software\' + APP_NAME + '\Render', False) then
    begin
      if Registry.ValueExists('Path') then
        RenderPath := Registry.ReadString('Path')
      else
        RenderPath := DefaultPath;

      if Registry.ValueExists('SampleDensity') then
        renderDensity := Registry.ReadFloat('SampleDensity')
      else
        renderDensity := 200;

      if Registry.ValueExists('FilterRadius') then
        renderFilterRadius := Registry.ReadFloat('FilterRadius')
      else
        renderFilterRadius := 0.4;

      if Registry.ValueExists('Oversample') then
        renderOversample := Registry.ReadInteger('Oversample')
      else
        renderOversample := 2;

      if Registry.ValueExists('Width') then
        renderWidth := Registry.ReadInteger('Width')
      else
        renderWidth := 1024;

      if Registry.ValueExists('Height') then
        renderHeight := Registry.ReadInteger('Height')
      else
        renderHeight := 768;

      if Registry.ValueExists('JPEGQuality') then
        JPEGQuality := Registry.ReadInteger('JPEGQuality')
      else
        JPEGQuality := 100;

      if Registry.ValueExists('FileFormat') then
        renderFileFormat := Registry.ReadInteger('FileFormat')
      else
        renderFileFormat := 3;

      if Registry.ValueExists('EmbedFlame') then   // AV
        EmbedFlame := Registry.ReadBool('EmbedFlame')
      else
        EmbedFlame := True;
      if Registry.ValueExists('SaveInFlame') then   // AV
        SaveInFlame := Registry.ReadBool('SaveInFlame')
      else
        SaveInFlame := True;
      {
      if Registry.ValueExists('BitsPerSample') then
        renderBitsPerSample := Registry.ReadInteger('BitsPerSample')
      else
        renderBitsPerSample := 0;

      if Registry.ValueExists('StoreEXIF') then begin
        StoreEXIF := Registry.ReadBool('StoreEXIF');
      end else begin
        StoreEXIF := false;
      end;
      if Registry.ValueExists('StoreParamsEXIF') then begin
        StoreParamsEXIF := Registry.ReadBool('StoreParamsEXIF');
      end else begin
        StoreParamsEXIF := false;
      end;
      if Registry.ValueExists('ExifAuthor') then begin
        ExifAuthor := Registry.ReadString('ExifAuthor');
      end else begin
        ExifAuthor := '';
      end;
      }
    end
    else
    begin
      renderFileFormat := 2;
      JPEGQuality := 100;
      renderPath := DefaultPath;
      renderDensity := 200;
      renderOversample := 2;
      renderFilterRadius := 0.4;
      renderWidth := 1024;
      renderHeight := 768;
      EmbedFlame := True;  // AV
      SaveInFlame := True;  // AV
      {
      renderBitsPerSample := 0;
      StoreEXIF := false;
      ExifAuthor := '';
      StoreParamsEXIF := false;
      }
    end;
    Registry.CloseKey;

    {UPR}
    if Registry.OpenKey('Software\' + APP_NAME + '\UPR', False) then
    begin
      if Registry.ValueExists('FlameColoringFile') then
        UPRColoringFile := Registry.ReadString('FlameColoringFile')
      else
        UPRColoringFile := 'apophysis.ucl';

      if Registry.ValueExists('FlameColoringIdent') then
        UPRColoringIdent := Registry.ReadString('FlameColoringIdent')
      else
        UPRColoringIdent := 'apophysis-205'; // AV: fixed

      if Registry.ValueExists('FlameFormulaFile') then
        UPRFormulaFile := Registry.ReadString('FlameFormulaFile')
      else
        UPRFormulaFile := 'mt.ufm';
      if Registry.ValueExists('FlameFormulaIdent') then
        UPRFormulaIdent := Registry.ReadString('FlameFormulaIdent')
      else
        UPRFormulaIdent := 'mt-pixel';

      if Registry.ValueExists('FlameIterDensity') then
        UPRSampleDensity := Registry.ReadInteger('FlameIterDensity')
      else
        UPRSampleDensity := 35;
      if Registry.ValueExists('FlameFilterRadius') then
        UPRFilterRadius := Registry.ReadFloat('FlameFilterRadius')
      else
        UPRFilterRadius := 0.7;
      if Registry.ValueExists('FlameOversample') then
        UPROversample := Registry.ReadInteger('FlameOversample')
      else
        UPROversample := 3;
      if Registry.ValueExists('FlameAdjustDensity') then
        UPRAdjustDensity := Registry.ReadBool('FlameAdjustDensity')
      else
        UPRAdjustDensity := true;
    end
    else
    begin
      UPRColoringFile := 'apophysis.ucl';
      UPRColoringIdent := 'apophysis-205';
      UPRFormulaFile := 'mt.ufm';
      UPRFormulaIdent := 'mt-pixel';
      UPRSampleDensity := 35;
      UPRFilterRadius := 0.7;
      UPROversample := 3;
      UPRAdjustDensity := True; ;
    end;
    Registry.CloseKey;
    
    if Registry.OpenKey('Software\' + APP_NAME + '\Display', False) then
    begin
      if Registry.ValueExists('SampleDensity') then
        defSampleDensity := Registry.ReadFloat('SampleDensity')
      else
        defSampleDensity := 5;
      if Registry.ValueExists('Gamma') then
        defGamma := Registry.ReadFloat('Gamma')
      else
        defGamma := 4;
      if Registry.ValueExists('Brightness') then
        defBrightness := Registry.ReadFloat('Brightness')
      else
        defBrightness := 4;
      if Registry.ValueExists('Contrast') then   // AV
        defContrast := Registry.ReadFloat('Contrast')
      else
        defContrast := 1;  // AV
      if Registry.ValueExists('Vibrancy') then
        defVibrancy := Registry.ReadFloat('Vibrancy')
      else
        defVibrancy := 1;
      if Registry.ValueExists('FilterRadius') then
        defFilterRadius := Registry.ReadFloat('FilterRadius')
      else
        defFilterRadius := 0.2;
      if Registry.ValueExists('GammaThreshold') then
        defGammaThreshold := Registry.ReadFloat('GammaThreshold')
      else
        defGammaThreshold := 0.01;
      if Registry.ValueExists('Oversample') then
        defOversample := Registry.ReadInteger('Oversample')
      else
        defOversample := 1;
      if Registry.ValueExists('Fuse') then  // AV
        Fuse := Registry.ReadInteger('Fuse')
      else
        Fuse := 15;

      if Registry.ValueExists('RhombicTileRadius') then  // AV
        RhombTR := Registry.ReadFloat('RhombicTileRadius')
      else
        RhombTR := 1;
      if Registry.ValueExists('SquareTileRadius') then  // AV
        SquareTR := Registry.ReadFloat('SquareTileRadius')
      else
        SquareTR := 1.414214; //Round6(sqrt(2));
      if Registry.ValueExists('HexagonalTileRadius') then  // AV
        HexTR := Registry.ReadFloat('HexagonalTileRadius')
      else
        HexTR := 2;

      if Registry.ValueExists('PreviewLowQuality') then
        prevLowQuality := Registry.ReadFloat('PreviewLowQuality')
      else
        prevLowQuality := 0.1;
      if Registry.ValueExists('PreviewMediumQuality') then
        prevMediumQuality := Registry.ReadFloat('PreviewMediumQuality')
      else
        prevMediumQuality := 1;
      if Registry.ValueExists('PreviewHighQuality') then
        prevHighQuality := Registry.ReadFloat('PreviewHighQuality')
      else
        prevHighQuality := 5;
    end
    else
    begin
      defSampleDensity := 5;
      defGamma := 4;
      defBrightness := 4;
      defVibrancy := 1;
      defContrast := 1; // AV
      defFilterRadius := 0.2;
      defOversample := 1;
      defGammaThreshold := 0.01;
      prevLowQuality := 0.1;
      prevMediumQuality := 1;
      prevHighQuality := 5;
      Fuse := 15;
      RhombTR := 1;
      HexTR := 2;
      SquareTR := 1.414214; //Round6(sqrt(2));
    end;
    Registry.CloseKey;

    if Registry.OpenKey('Software\' + APP_NAME + '\Autosave', False) then
    begin
      if Registry.ValueExists('AutoSaveEnabled') then
        AutoSaveEnabled := Registry.ReadBool('AutoSaveEnabled')
      else
        AutoSaveEnabled := false;

      if Registry.ValueExists('AutoSaveFreq') then
        AutoSaveFreq := Registry.ReadInteger('AutoSaveFreq')
      else
        AutoSaveFreq := 2;

      if Registry.ValueExists('AutoSavePath') then
        AutoSavePath := Registry.ReadString('AutoSavePath')
      else
        AutoSavePath := DefaultPath + 'autosave.flame';
    end else begin
      AutoSaveEnabled := false;
      AutoSaveFreq := 2;
      AutoSavePath := DefaultPath + 'autosave.flame';
    end;
    Registry.CloseKey;
  finally
    Registry.Free;
  end;

  PluginPath := ReadPluginDir;

  // AV: create a folder for Apophysis temp files
  AppData := GetEnvVarValue('APPDATA') + '\Apophysis AV\';
  if not DirectoryExists(AppData) then  // AV
    if not CreateDir(AppData) then AppData := AppPath;

  UseX64IfPossible := CheckX64;
end;

procedure SaveSettings;
var
  Registry: TRegistry;
  i: integer;
  VarUsed: byte;

  function VarState(const a, b: boolean): byte; inline;
  begin
    Result := 0;
    if a and b then Exit(3)
    else if a then Exit(1)
    else if b then Exit(2);
  end;

begin
  // SavePluginDir(PluginPath); // AV: moved into main procedure

  Registry := TRegistry.Create;
  try
    Registry.RootKey := HKEY_CURRENT_USER;
    { Defaults }
    if Registry.OpenKey('\Software\' + APP_NAME + '\Defaults', True) then
    begin
      // Registry.WriteBool('StartupCheckForUpdates', StartupCheckForUpdates);
      Registry.WriteBool('AlwaysCreateBlankFlame', AlwaysCreateBlankFlame);
      Registry.WriteString('GradientFile', GradientFile);
      Registry.WriteString('PluginPath', PluginPath); // AV
      Registry.WriteString('HelpPath', HelpPath);
      Registry.WriteString('SmoothPaletteFile', SmoothPaletteFile);
      Registry.WriteString('DefaultScript', defScriptFile);  // AV
      Registry.WriteBool('PlaySoundOnRenderComplete', PlaySoundOnRenderComplete);
      Registry.WriteString('RenderCompleteSoundFile', RenderCompleteSoundFile);
      Registry.WriteBool('AutoOpenLog', AutoOpenLog);
      Registry.WriteBool('ClassicListMode', ClassicListMode);

      Registry.WriteBool('WarnOnMissingPlugin', WarnOnMissingPlugin);
      Registry.WriteBool('SetEnglishLayout', SetEngLayout);
      Registry.WriteBool('RandomizeTemplates', RandomizeTemplates);
      Registry.WriteBool('ConfirmClearScript', ConfirmClearScript);
      Registry.WriteBool('ConfirmResetUndo', ConfirmResetUndo);
      Registry.WriteBool('AutoSaveXML', AutoSaveXML);
      Registry.WriteBool('ApplyFlatten', ApplyFlatten);
      Registry.WriteString('LanguageFile', LanguageFile);
      Registry.WriteString('LastOpenFile', LastOpenFile);
      Registry.WriteInteger('LastOpenFileEntry', LastOpenFileEntry);
      Registry.WriteBool('RememberLastOpenFile', RememberLastOpenFile);
      Registry.WriteBool('UseSmallThumbnails', UseSmallThumbnails);
      Registry.WriteInteger('LineCenterColor', LineCenterColor);
      Registry.WriteInteger('LineThirdsColor', LineThirdsColor);
      Registry.WriteInteger('LineGRColor', LineGRColor);
      Registry.WriteBool('EnableGuides', EnableGuides);
      Registry.WriteString('ChaoticaPath', ChaoticaPath);
      //Registry.WriteBool('UseX64IfPossible', UseX64IfPossible);

      Registry.WriteBool('ConfirmDelete', ConfirmDelete);
      Registry.WriteBool('OldPaletteFormat', OldPaletteFormat);
      Registry.WriteBool('ConfirmExit', ConfirmExit);
      Registry.WriteInteger('NumTries', NumTries);
      Registry.WriteInteger('TryLength', TryLength);
      Registry.WriteInteger('MinTransforms', randMinTransforms);
      Registry.WriteInteger('MaxTransforms', randMaxTransforms);
      Registry.WriteInteger('MutationMinTransforms', mutantMinTransforms);
      Registry.WriteInteger('MutationMaxTransforms', mutantMaxTransforms);
      Registry.WriteInteger('RandomGradient', randGradient);
      Registry.WriteString('ParameterFolder3D', ParamFolder);
      Registry.WriteString('UPRPath', UPRPath);
      Registry.WriteString('ImageFolder', ImageFolder);
      Registry.WriteString('SavePath3D', SavePath);
      Registry.WriteInteger('UPRWidth', UPRWidth);
      Registry.WriteInteger('UPRHeight', UPRHeight);
      Registry.WriteString('BrowserPath', BrowserPath);
      Registry.WriteInteger('EditPreviewQaulity', EditPrevQual);
      Registry.WriteInteger('MutatePreviewQaulity', MutatePrevQual);
      Registry.WriteInteger('AdjustPreviewQaulity', AdjustPrevQual);
      Registry.WriteInteger('ThumbPrevQuality', ThumbPrevQual);  // AV
      Registry.WriteInteger('AnimPrevQuality', AnimPrevQual);  // AV
      Registry.WriteString('RandomPrefix', RandomPrefix);
      Registry.WriteString('RandomDate', RandomDate);
      Registry.WriteInteger('RandomIndex', RandomIndex);
      Registry.WriteString('DefaultFlameFile3D', defFlameFile);
      Registry.WriteString('SmoothPalettePath', SmoothPalettePath);
      Registry.WriteString('GradientFile', GradientFile);
      Registry.WriteInteger('TryLength', TryLength);
      Registry.WriteInteger('NumTries', NumTries);
      Registry.WriteString('SmoothPaletteFile', defSmoothPaletteFile);
      Registry.WriteInteger('SymmetryType', SymmetryType);
      Registry.WriteInteger('SymmetryOrder', SymmetryOrder);
      Registry.WriteInteger('SymmetryNVars', SymmetryNVars);
      Registry.WriteInteger('RotationMode', MainForm_RotationMode);
      Registry.WriteInteger('EnumerationMode', FlameEnumMode);  // AV
      Registry.WriteInteger('MinNodes', MinNodes);
      Registry.WriteInteger('MinHue', MinHue);
      Registry.WriteInteger('MinSat', MinSat);
      Registry.WriteInteger('MinLum', MinLum);
      Registry.WriteInteger('MaxNodes', MaxNodes);
      Registry.WriteInteger('MaxHue', MaxHue);
      Registry.WriteInteger('MaxSat', MaxSat);
      Registry.WriteInteger('MaxLum', MaxLum);
      Registry.WriteString('RandomGradientFile', randGradientFile);
      Registry.WriteInteger('ColorBlendType', randColorBlend);  //AV
      Registry.WriteBool('EqualStripes', EqualStripes);  // AV
      Registry.WriteInteger('BatchSize', BatchSize);
      Registry.WriteString('ScriptPath', ScriptPath);
      Registry.WriteInteger('ExportFileFormat', ExportFileFormat);
      Registry.WriteInteger('ExportWidth', ExportWidth);
      Registry.WriteInteger('ExportHeight', ExportHeight);
      Registry.WriteFloat('ExportDensity', ExportDensity);
      Registry.WriteFloat('ExportFilter', ExportFilter);
      Registry.WriteInteger('ExportOversample', ExportOversample);
    (*
      Registry.WriteInteger('ExportBatches', ExportBatches);
      Registry.WriteString('Nick', SheepNick);
      Registry.WriteString('URL', SheepURL);
      Registry.WriteString('Server', SheepServer);
      Registry.WriteString('Pass', SheepPW);
	  *)
	    Registry.WriteString('Renderer', flam3Path);
      Registry.WriteBool('ShowProgress', ShowProgress);
      Registry.WriteBool('KeepBackground', KeepBackground);
      Registry.WriteInteger('RandBackColor', RandBackColor);
      Registry.WriteBool('PreserveQuality', PreserveQuality);
      Registry.WriteString('FunctionLibrary', defLibrary);
      Registry.WriteString('ScreenshotsFolder', ScreenShotPath);  // AV

      Registry.WriteBool('ShowTransparency', ShowTransparency);
      Registry.WriteInteger('PNGTransparency', PNGTransparency);
      Registry.WriteBool('ExtendMainPreview', ExtendMainPreview);
      Registry.WriteFloat('MainPreviewScale', MainPreviewScale);

      Registry.WriteBool('SaveIncompleteRenders', SaveIncompleteRenders);
      Registry.WriteBool('ShowRenderStats', ShowRenderStats);
      Registry.WriteBool('ShowRenderImage', ShowRenderImage);
      Registry.WriteBool('LowerRenderPriority', LowerRenderPriority);

      // AV: for animation
      Registry.WriteInteger('AnimFPS', AnimFPS);
      Registry.WriteString('AnimPrefix', defAnimPrefix);
      Registry.WriteInteger('FrameExt', defFrameExt);
      Registry.WriteBool('CreateAnimFolder', CreateAnimFolder);

      Registry.WriteInteger('NrTreads', NrTreads);
      Registry.WriteInteger('UseNrThreads', UseNrThreads);
    end;
    Registry.CloseKey;

    if Registry.OpenKey('\Software\' + APP_NAME + '\Variations', True) then
    begin
      for i := 0 to NRVAR-1 do
      begin
        VarUsed := 0;
        if Registry.ValueExists(Varnames(i)) then
        begin
          VarUsed := VarState(Variations[i], FavouriteVariations[i]);
          if Registry.ReadInteger(Varnames(i)) = VarUsed then continue; //?
        end;
        Registry.WriteInteger(Varnames(i), VarUsed);
      end;
    end;
    Registry.CloseKey;

    { Editor }
    if Registry.OpenKey('\Software\' + APP_NAME + '\Forms\Editor', True) then
    begin
      Registry.WriteBool('UseTransformColors', UseTransformColors);
      Registry.WriteBool('HelpersEnabled', HelpersEnabled);
      Registry.WriteBool('ShowAllXforms', ShowAllXforms);
      Registry.WriteBool('EnableEditorPreview', EnableEditorPreview);
      Registry.WriteInteger('EditorPreviewTransparency', EditorPreviewTransparency);
      Registry.WriteInteger('BackgroundColor', EditorBkgColor);
      Registry.WriteInteger('GridColor1', GridColor1);
      Registry.WriteInteger('GridColor2', GridColor2);
      Registry.WriteInteger('HelpersColor', HelpersColor);
      Registry.WriteInteger('FlipColor', FlipColor);
      Registry.WriteInteger('ReferenceTriangleColor', ReferenceTriangleColor);
      Registry.WriteBool('ExtendedEdit', ExtEditEnabled);
      Registry.WriteBool('LockTransformAxis', TransformAxisLock);
      Registry.WriteBool('RebuildXaosLinks', RebuildXaosLinks);
      Registry.WriteBool('AllowResetCoefs', AllowResetCoefs);  // AV
      Registry.WriteBool('AllowResetLinear', AllowResetLinear);  // AV
      Registry.WriteBool('SyncTriangles', UseTriangleSync);  // AV
    end;
    Registry.CloseKey;

    { Display }
    if Registry.OpenKey('\Software\' + APP_NAME + '\Display', True) then
    begin
      Registry.WriteFloat('SampleDensity', defSampleDensity);
      Registry.WriteFloat('Gamma', defGamma);
      Registry.WriteFloat('Brightness', defBrightness);
      Registry.WriteFloat('Contrast', defContrast);
      Registry.WriteFloat('Vibrancy', defVibrancy);
      Registry.WriteFloat('FilterRadius', defFilterRadius);
      Registry.WriteInteger('Oversample', defOversample);
      Registry.WriteInteger('Fuse', Fuse);
      Registry.WriteFloat('GammaThreshold', defGammaThreshold);
      Registry.WriteFloat('PreviewLowQuality', prevLowQuality);
      Registry.WriteFloat('PreviewMediumQuality', prevMediumQuality);
      Registry.WriteFloat('PreviewHighQuality', prevHighQuality);
      Registry.WriteFloat('HexagonalTileRadius', HexTR);
      Registry.WriteFloat('SquareTileRadius', SquareTR);
      Registry.WriteFloat('RhombicTileRadius', RhombTR);
    end;
    Registry.CloseKey;

    { UPR }
    if Registry.OpenKey('\Software\' + APP_NAME + '\UPR', True) then
    begin
      Registry.WriteString('FlameColoringFile', UPRColoringFile);
      Registry.WriteString('FlameColoringIdent', UPRColoringIdent);
      Registry.WriteString('FlameFormulaFile', UPRFormulaFile);
      Registry.WriteString('FlameFormulaIdent', UPRFormulaIdent);
      Registry.WriteInteger('FlameIterDensity', UPRSampleDensity);
      Registry.WriteFloat('FlameFilterRadius', UPRFilterRadius);
      Registry.WriteInteger('FlameOversample', UPROversample);
      Registry.WriteBool('FlameAdjustDensity', UPRAdjustDensity);
    end;
    Registry.CloseKey;

    if Registry.OpenKey('\Software\' + APP_NAME + '\Render', True) then
    begin
      Registry.WriteString('Path', renderPath);
      Registry.WriteFloat('SampleDensity', renderDensity);
      Registry.WriteInteger('Oversample', renderOversample);
      Registry.WriteFloat('FilterRadius', renderFilterRadius);
      Registry.WriteInteger('Width', renderWidth);
      Registry.WriteInteger('Height', renderHeight);
      Registry.WriteInteger('JPEGQuality', JPEGQuality);
      Registry.WriteInteger('FileFormat', renderFileFormat);
      Registry.WriteBool('EmbedFlame', EmbedFlame); // AV
      Registry.WriteBool('SaveInFlame', SaveInFlame); // AV
      {
      Registry.WriteBool('StoreEXIF', StoreEXIF);
      Registry.WriteBool('StoreParamsEXIF', StoreParamsEXIF);
      Registry.WriteString('ExifAuthor', ExifAuthor);
      }
    end;
    Registry.CloseKey;

    if Registry.OpenKey('\Software\' + APP_NAME + '\Autosave', True) then
    begin
      Registry.WriteBool('AutoSaveEnabled', AutoSaveEnabled);
      Registry.WriteInteger('AutoSaveFreq', AutoSaveFreq);
      Registry.WriteString('AutoSavePath', AutoSavePath);
    end;
    Registry.CloseKey;
  finally
    Registry.Free;
  end;
end;

end.

