(*
  .name       Settings
  .task       save & load settings
  .release    1.0
  .language   Oberon-2
  .translator Amiga Oberon 3.11
  .system     AmigaOS 2.04/2.1/3.0
  .author     Joachim Barheine
  .address    Hochgrevestraße 3, D-38640 Goslar
  .copyright  (c) 1994 by Joachim Barheine
*)

(* .info: 05/09/94, 16:35:01, version 36 *)

MODULE Settings;

IMPORT
  SYS:= SYSTEM,

  EArgs,
  Dos,
  Gfx:= Graphics,
  I:= Intuition,
  OberonLib;

CONST
  (* autosave *)

  autosaveOff*  = 0;    (* autosave off *)
  autosaveReq*  = 1;    (* autosave after requester *)
  autosaveAuto* = 2;    (* auto-autosave *)

  (* backup *)

  backupsOff*   = 0;    (* no backup *)

  (* screen *)

  screenWb*     = 0;    (* workbench screen *)
  screenPublic* = 1;    (* public screen *)
  screenCustom* = 2;    (* custom-public screen *)

  (* folds *)
  foldHInvers*    = 0;        (* header is invers *)
  foldHHighlight* = 1;        (* header is highlighted *)
  foldHBold*      = 2;        (* header is bold typed *)

  (* print *)

  pitch10*      = 0;    (* 10 cpi *)
  pitch12*      = 1;    (* 12 cpi *)
  pitch15*      = 2;    (* 15-17 cpi *)
  pitchAdjust*  = 3;    (* adjust at printer *)

  spacing6*     = 0;    (* 6 lpi *)
  spacing8*     = 1;    (* 8 lpi *)

  qualityDraft* = 0;    (* draft *)
  qualityLetter*= 1;    (* letter *)

  formattingOff*= 0;    (* no formatting *)
  formatting2*  = 1;    (* 2-column formatting *)
  formatting3*  = 2;    (* 3-column formatting *)

  lineNumbers*  = 0;    (* line-numbering on *)
  hTitle*       = 1;    (* filename *)
  hNumbers*     = 2;    (* page-numbering *)
  hDate*        = 3;    (* current date *)
  hTime*        = 4;    (* current time *)

  (* search/replace flags *)

  srIgnoreCase* = 0;
  srFindWord*   = 1;
  repAll*       = 2;
  repLinkChgs*  = 3;

  (* replace flags *)
  (* macro flags *)

  recMouse*     = 0;
  recText*      = 1;
  recRxCmdLine* =       2;
  recRxPrg* =   3;
  recLinkChgs* =        4;

  (* scroller size *)
  scrSizeNormal* = 0;
  scrSizeLarge* = 1;

  defConfig* = "Default";

(* $IF M2Amiga THEN *)
  envDir = "ENV:M2Edt";
  envarcDir = "ENVARC:M2Edt";
(* $ELSE *)
  envDir = "ENV:Edt";
  envarcDir = "ENVARC:Edt";
(* $END *)

TYPE
  Prefs= STRUCT
    wLeft, wTop, wWidth, wHeight, tabAlign, undoBufSize, margin: INTEGER;
    autoIndent, cleanLines, insert, wordWrap: BOOLEAN;
    backups: SHORTINT;          (* backup-mode *)
    sType: SHORTINT;           (* screen-type *)
    sName: ARRAY 80 OF CHAR;    (* screen-name *)
    sMode: LONGINT;             (* screen-mode *)
    sWidth, sHeight: LONGINT;   (* screen-dimensions *)
    sDepth: INTEGER;            (* screen-depth *)
    autosave: SHORTINT;         (* autosave-mode *)
    autosaveDelay: INTEGER;     (* minutes *)
    fontSpec: Gfx.TextAttr;     (* font for text *)
    fontName: ARRAY 256 OF CHAR;(* font name *)
    foldHeader: SHORTINT;             (* type of foldheader-mark *)
    srFlags: SHORTSET;          (* flags of search/replace *)
    fileReqWidth, fileReqHeight: INTEGER;           (* dimensions of file-requester *)
    fileReqPattern: ARRAY 256 OF CHAR;
    leftMargin, rightMargin, lines,  colSpacing: INTEGER;       (* paper *)
    pitch, spacing, quality,
    formatting: SHORTINT;       (* font, formatting *)
    printFlags: SHORTSET;       (* options *)
    macroFlags: LONGSET;
    convTabs, closeFlds, rmbPos, rmbChgs: BOOLEAN;
    scrollerSize: SHORTINT;
    null: CHAR;                 (* null termination *)
  END;

  PrefsDummy= UNTRACED POINTER TO ARRAY SIZE(Prefs) OF CHAR;

VAR
  recording* : BOOLEAN;    (* recording macro? *)
  configName- : ARRAY 80 OF CHAR;
  wLeft* , wTop* , wWidth* , wHeight*, tabAlign*, undoBufSize*, margin* : INTEGER;
  fontSpec*: Gfx.TextAttr;
  autoIndent* , icons*, cleanLines*, insert*, wordWrap*,
  convTabs*, closeFlds*, rmbPos*, rmbChgs* : BOOLEAN;
  backups* : SHORTINT;
  sType*  : SHORTINT;
  sName* : ARRAY 80 OF CHAR;  (* screen or default *)
  sMode* : LONGINT;
  sWidth*, sHeight* : LONGINT;
  sDepth* : INTEGER;
  autosave* : SHORTINT;
  autosaveDelay* : INTEGER;
  defFontSpec- : Gfx.TextAttr;
  fontName, defFontName: ARRAY 256 OF CHAR;
  foldHeader*: SHORTINT;              (* type of foldheader-mark *)
  srFlags* : SHORTSET;
  fileReqWidth*, fileReqHeight* : INTEGER;
  fileReqPattern* : ARRAY 256 OF CHAR;
  leftMargin*, rightMargin*, lines*, colSpacing* : INTEGER;
  pitch*, spacing*, quality*, formatting* : SHORTINT;
  printFlags* : SHORTSET;
  macroFlags* : LONGSET;
  scrollerSize*: SHORTINT;

PROCEDURE Save* (configName: ARRAY OF CHAR): BOOLEAN;

VAR
  p: Prefs;

  PROCEDURE SaveSettings(dir, configName: ARRAY OF CHAR; VAR p: Prefs): BOOLEAN;

  VAR
    name: ARRAY 128 OF CHAR;
    pd: PrefsDummy;
    lock: Dos.FileLockPtr;

  (* $CopyArrays- *)

  BEGIN
    lock:= Dos.Lock(dir, Dos.sharedLock);
    IF lock = NIL THEN lock:= Dos.CreateDir(dir) END;
    IF lock # NIL THEN Dos.UnLock(lock) END;

    pd:= SYS.ADR(p);
    COPY(dir, name);
    RETURN Dos.AddPart(name, configName, SIZE(name))
         & Dos.SetVar(name, pd^, SIZE(p), LONGSET{Dos.globalOnly, Dos.binaryVar});
  END SaveSettings;

(* $CopyArrays- *)

BEGIN
  p.wLeft:= wLeft;
  p.wTop:= wTop;
  p.wWidth:= wWidth;
  p.wHeight:= wHeight;
  p.undoBufSize:= undoBufSize;
  p.tabAlign:= tabAlign;
  p.fontSpec:= fontSpec;
  COPY(fontSpec.name^, p.fontName);
  p.foldHeader:= foldHeader;
  p.autoIndent:= autoIndent;
  p.cleanLines:= cleanLines;
  p.insert:= insert;
  p.wordWrap:= wordWrap;
  p.margin:= margin;
  p.backups:= backups;
  p.sType:= sType;
  COPY(sName, p.sName);
  p.sMode:= sMode;
  p.sWidth:= sWidth;
  p.sHeight:= sHeight;
  p.sDepth:= sDepth;
  p.autosave:= autosave;
  p.autosaveDelay:= autosaveDelay;
  p.srFlags:= srFlags;
  p.fileReqWidth:= fileReqWidth;
  p.fileReqHeight:= fileReqHeight;
  COPY(fileReqPattern, p.fileReqPattern);
  p.leftMargin:= leftMargin;
  p.rightMargin:= rightMargin;
  p.lines:= lines;
  p.colSpacing:= colSpacing;
  p.pitch:= pitch;
  p.spacing:= spacing;
  p.quality:= quality;
  p.formatting:= formatting;
  p.printFlags:= printFlags;
  p.macroFlags:= macroFlags;
  p.convTabs:= convTabs;
  p.closeFlds:= closeFlds;
  p.rmbPos:= rmbPos;
  p.rmbChgs:= rmbChgs;
  p.scrollerSize:= scrollerSize;
  p.null:= 0X;
  RETURN SaveSettings(envarcDir, configName, p)
       & SaveSettings(envDir, configName, p);
END Save;

PROCEDURE Load(configName: ARRAY OF CHAR): BOOLEAN;

VAR
  p: Prefs;

  PROCEDURE LoadSettings(dir, configName: ARRAY OF CHAR; VAR p: Prefs): BOOLEAN;

  VAR
    name: ARRAY 128 OF CHAR;
    pd: PrefsDummy;

  (* $CopyArrays- *)

  BEGIN
    pd:= SYS.ADR(p);
    COPY(dir, name);
    RETURN Dos.AddPart(name, configName, SIZE(name))
         & (Dos.GetVar(name, pd^, SIZE(p), LONGSET{Dos.globalOnly, Dos.binaryVar}) = SIZE(p) - 1);
  END LoadSettings;

(* $CopyArrays- *)

BEGIN
  IF LoadSettings(envDir, configName, p) THEN
    wLeft:= p.wLeft;
    wTop:= p.wTop;
    wWidth:= p.wWidth;
    wHeight:= p.wHeight;
    undoBufSize:= p.undoBufSize;
    tabAlign:= p.tabAlign;
    fontSpec:= p.fontSpec;
    COPY(p.fontName, fontName);
    fontSpec.name:= SYS.ADR(fontName);
    autoIndent:= p.autoIndent;
    cleanLines:= p.cleanLines;
    insert:= p.insert;
    wordWrap:= p.wordWrap;
    margin:= p.margin;
    backups:= p.backups;
    sType:= p.sType;
    COPY(p.sName, sName);
    sMode:= p.sMode;
    sWidth:= p.sWidth;
    sHeight:= p.sHeight;
    sDepth:= p.sDepth;
    autosave:= p.autosave;
    autosaveDelay:= p.autosaveDelay;
    foldHeader:= p.foldHeader;
    srFlags:= p.srFlags;
    fileReqWidth:= p.fileReqWidth;
    fileReqHeight:= p.fileReqHeight;
    COPY(p.fileReqPattern, fileReqPattern);
    leftMargin:= p.leftMargin;
    rightMargin:= p.rightMargin;
    lines:= p.lines;
    colSpacing:= p.colSpacing;
    pitch:= p.pitch;
    spacing:= p.spacing;
    quality:= p.quality;
    formatting:= p.formatting;
    printFlags:= p.printFlags;
    macroFlags:= p.macroFlags;
    convTabs:= p.convTabs;
    closeFlds:= p.closeFlds;
    rmbPos:= p.rmbPos;
    rmbChgs:= p.rmbChgs;
    scrollerSize:= p.scrollerSize;
    RETURN TRUE;
  ELSE
    RETURN FALSE;
  END;
END Load;

PROCEDURE SetDefaults(argScreenType: SHORTINT; argScreenName: ARRAY OF CHAR);

(* $CopyArrays- *)

BEGIN
  wLeft:= 0;
  wTop:= 11;
  wWidth:= 640;
  wHeight:= 200;
  tabAlign:= 8;
  undoBufSize:= 10;
  fontSpec:= defFontSpec;
  COPY(defFontName, fontName);
  autoIndent:= TRUE;
  cleanLines:= TRUE;
  insert:= TRUE;
  wordWrap:= FALSE;
  margin:= 75;
  sType:= argScreenType;
  COPY(argScreenName, sName);
  sMode:= Gfx.hiresKey;
  sWidth:= I.stdScreenWidth;
  sHeight:= I.stdScreenHeight;
  sDepth:= 2;
  backups:= backupsOff;
  autosave:= autosaveOff;
  autosaveDelay:= 15;
  foldHeader:= foldHInvers;
  srFlags:= SHORTSET{};
  fileReqWidth:= 300;
  fileReqHeight:= 200;
  fileReqPattern:= "~(#?(.info|$?))";
  leftMargin:= 0;
  rightMargin:= 120;
  lines:= 88;
  colSpacing:= 2;
  pitch:= pitch15;
  spacing:= spacing8;
  quality:= qualityDraft;
  formatting:= formattingOff;
  printFlags:= SHORTSET{};
  macroFlags:= LONGSET{};
  convTabs:= FALSE;
  closeFlds:= FALSE;
  rmbPos:= TRUE;
  rmbChgs:= TRUE;
  scrollerSize:= scrSizeNormal;
END SetDefaults;

BEGIN
  recording:= FALSE;
  icons:= OberonLib.wbStarted;
  COPY(Gfx.gfx.defaultFont.message.node.name^, defFontName);
  defFontSpec.name:= SYS.ADR(defFontName);
  defFontSpec.style:= Gfx.gfx.defaultFont.style;
  defFontSpec.flags:= Gfx.gfx.defaultFont.flags;
  defFontSpec.ySize:= Gfx.gfx.defaultFont.ySize;
  IF EArgs.pubScreen # "" THEN (* extra public sType *)
    COPY(EArgs.pubScreen, sName);
    COPY(sName, configName);
    IF sName = "Workbench" THEN sType:= screenWb ELSE sType:= screenPublic END;
    IF ~Load(configName) THEN SetDefaults(sType, sName) END;
  ELSE
    configName:= defConfig;
    IF ~Load(defConfig) THEN SetDefaults(screenWb, "Workbench") END;
  END;
END Settings.