(*************************************************************************

:Program.    AmokEd.mod
:Contents.   Top-Level Module for AmokEd
:Author.     Hartmut Goebel
:Address.    Aufseßplatz 5, D-8500 Nürnberg 40
:Copyright.  Copyright © 1990,1991 by Hartmut Goebel
:Copyright.  for further information see file Copyright.ReadMe
:Language.   Oberon
:Translator. Amiga Oberon Compiler V2.13
:Imports.    SupLib (Hartmut Goebel)
:History.    V0.1, 26 Sep 1990 Hartmut Goebel
:History.    V1.0, 14 Apr 1991 Hartmut Goebel [hG]
:History.    V1.1, 28 Apr 1991 [hG] ^Arguments-Checking (multi names)
:Date.       30 Jan 1992 12:55:46

*************************************************************************)

MODULE AmokEd;

IMPORT
  arg: Arguments,
  d  : Dos,
  e  : Exec,
  edL: EdLowLevel,
  ed1: EdCmd1,
  ed2: EdCmd2,
  edD: EdDisplay,
  edE: EdErrors,
  edF: EdFileTools,
  eGd: EdGadgets,
  edG: EdGlobalVars,
  edK: EdKeyboard,
  edM: EdMovement,
  eMn: EdMenu,
  edP: EdParser,
  edR: EdRexx,
  g  : Graphics,
  I  : Intuition,
  rx : Rexx,
  rxs: RexxSysLib,
  s  : SYSTEM,
  u  : Utility;

VAR
  iMsg: I.IntuiMessagePtr;
  PortBits, Mask: LONGSET;
  gadPtr: I.GadgetPtr;
  menuCmd: edG.StringPtr;
  rexxMsg: rx.RexxMsgPtr;
  GadNum: INTEGER;
  DontWait: BOOLEAN;
  Buffer: edG.String;
CONST
  NoGadget = -1;
  PropKlicked = -2;

(*-----------------------------------------------------------------------*)
(*------ StartUp --------------------------------------------------------*)

PROCEDURE StartUp;
TYPE
  scolArray = ARRAY 1 OF e.UWORD;
CONST
  scol = scolArray (-1);
  scrTags = u.Tags3 (I.saPens,s.ADR(scol),I.saOverscan,NIL,u.done,NIL);
  newScr = I.ExtNewScreen(
    0,0,0,0,0, (* left, top ||  width, height, depth filled in by program *)
    0,1,       (* pens *)
    {g.hires}, (* viewmodes *)
    I.customScreen+{I.nsExtended},      (* type *)
    NIL,s.ADR(edG.Copyright),NIL,NIL, (* font, title, gadgets, bitMap *)
    s.ADR(scrTags)); (* extension *)

VAR
  i, numArgs: INTEGER;
  oldLock: d.FileLockPtr;
  string: edG.StringPtr;
  long: LONGINT;
  WasNumber: BOOLEAN;
  sourceFile: INTEGER;
  ns: I.ExtNewScreen;
  wb: I.ScreenPtr;
BEGIN
  edG.Screen := I.OpenWorkBench();
  edG.WBScreenDepth := edG.Screen.bitMap.depth;

  sourceFile := -1;
  edF.GetConfig;
  numArgs := arg.NumArgs();
  IF numArgs > 0 THEN
    string := s.ADR(Buffer[2]);
    i := numArgs;
    REPEAT
      arg.GetArg(i,Buffer);
      IF Buffer[0] = "-" THEN
        WasNumber := edL.StrToInt(string,long) & (long < MAX(INTEGER));
        CASE CAP(Buffer[1]) OF
        "F": sourceFile := i; | (* source alternativ *)
        "S": IF WasNumber THEN (* open screen *)
               edG.Config.screenDepth := SHORT(long); END; |
        "L": IF WasNumber THEN
               edG.Config.edges.left := SHORT(long); END; |
        "T": IF WasNumber THEN
               edG.Config.edges.top := SHORT(long); END; |
        "W": IF WasNumber THEN
               edG.Config.edges.width := SHORT(long); END; |
        "H": IF WasNumber THEN
               edG.Config.edges.height := SHORT(long); END; |
        ELSE END;
      END;
      DEC(i);
    UNTIL i = 0;
  END;
  IF edG.Config.screenDepth > 0 THEN
    IF (edG.Config.screenDepth > 4) THEN
      edG.Config.screenDepth := 4 END;
    ns := newScr;
    ns.ns.depth := edG.Config.screenDepth;
    ns.ns.width := g.gfx.normalDisplayColumns;
    ns.ns.height := g.gfx.normalDisplayRows;
    IF ns.ns.height > 282 THEN
      ns.ns.viewModes := {g.hires,g.lace}; END;
    edG.Screen := I.OpenScreen(ns);
  END;
  IF numArgs > 0 THEN
    REPEAT
      INC(i);
      arg.GetArg(i,Buffer);
      IF Buffer[0] # "-" THEN
        ed2.dNewWindow;
        edG.Arg[0] := s.ADR(Buffer); edG.ArgSet := {edF.newFile};
        edF.dLoad;
        IF edG.Rc < edE.abortLevel THEN
          d.UnLock(edG.Text.dirLock);
          edG.Text.dirLock := d.DupLock(arg.GetLock(i));
        END;
        edL.WindowTitle;
      END;
    UNTIL i = numArgs;
  END;
  IF edG.Text = NIL THEN ed2.dNewWindow; END;
  edG.ArgSet := {edF.sourceDoNotTitle};
  edG.Arg[0] := s.ADR("s:.aedrc"); edF.dSource;
  IF sourceFile = -1 THEN
    edG.ArgSet := {edF.sourceDoNotTitle};
    edG.Arg[0] := s.ADR(".aedrc");
  ELSE
    arg.GetArg(sourceFile,Buffer);
    edG.ArgSet := {};
    edG.Arg[0] := s.ADR(Buffer[2]);
  END;
  edF.dSource;
END StartUp;

(*-----------------------------------------------------------------------*)
(*------ Intui Check ----------------------------------------------------*)

PROCEDURE IntuiCheck;
BEGIN
  INCL(edG.Status,edG.msgCheck);
  IF iMsg.idcmpWindow # edG.Text.win THEN
    IF edG.multiMode IN edG.Status THEN RETURN END;
    (*
     * Umschalten nicht erlaubt, wenn im MultiReplaceMode
     *)
    EXCL(edG.Text.status,edG.quit);
    edD.TextCursor(FALSE);
    IF edG.commLineMode IN edG.Status THEN
      ed1.EscapeCommLineMode; END;
    edD.SwitchEdit(edL.FindEdit(iMsg.idcmpWindow));
    edD.TextCursor(TRUE);
    GadNum := NoGadget;
    RETURN;
  END;

  edG.Mx := iMsg.mouseX;
  edG.My := iMsg.mouseY;

  IF I.gadgetDown IN iMsg.class THEN
    ed1.HandleQuitFlags;
    gadPtr := s.VAL(I.GadgetPtr,iMsg.iAddress);
    GadNum := gadPtr.gadgetID;
    eGd.DrawKnob(GadNum);
    (*IF GadNum := 1 THEN GadNum := NoGadget; END;*)
    RETURN;
  ELSIF I.gadgetUp IN iMsg.class THEN
    ed1.HandleQuitFlags;
    gadPtr := s.VAL(I.GadgetPtr,iMsg.iAddress);
    CASE gadPtr.gadgetID OF
      2..3: eGd.SetProp;
    | 1:    eGd.PropKnobAction;
    ELSE END;
  ELSIF I.rawKey IN iMsg.class THEN
    IF edG.multiMode IN edG.Status THEN
      edD.TextCursor(FALSE);
      ed2.MultiReplace(iMsg);
      edD.TextCursor(TRUE);
    ELSIF edK.GetKeyText(iMsg,CHR(iMsg.code),iMsg.qualifier,Buffer) > 0 THEN
      edP.dCommand(s.ADR(Buffer)); END;
  ELSIF I.mouseMove IN iMsg.class THEN
    ed1.unIconify;
    IF edK.GetKeyText(NIL,edK.qMove,iMsg.qualifier,Buffer) > 0 THEN
      edP.dCommand(s.ADR(Buffer)); END;
  ELSIF I.mouseButtons IN iMsg.class THEN
    CASE iMsg.code OF
      I.selectDown,I.menuDown,I.middleUp:
        IF edG.iconMode IN edG.Text.status THEN
          ed1.unIconify;
          edD.TextCursor(TRUE);
        ELSE
          I.ReportMouse(edG.Text.win,I.LTRUE);
          ed1.unIconify;
          IF edK.GetKeyText(NIL,CHR(iMsg.code),
                            iMsg.qualifier,Buffer) > 0 THEN
            edP.dCommand(s.ADR(Buffer)); END;
        END;
      |I.selectUp,I.menuUp,I.middleDown:
        I.ReportMouse(edG.Text.win,I.LFALSE);
    ELSE
    END;
  ELSIF I.menuPick IN iMsg.class THEN
     menuCmd := eMn.GetMenuCmd(iMsg);
     IF menuCmd#NIL THEN
       COPY(menuCmd^,Buffer);
       edP.dCommand(s.ADR(Buffer));
       eMn.ItemPicked := NIL;
     END;
  ELSIF I.newSize IN iMsg.class THEN
    ed1.HandleQuitFlags;
    edD.TextCursor(FALSE);
    IF edG.commLineMode IN edG.Status THEN
      ed1.EscapeCommLineMode;
    ELSE
      edD.PutBackLine;
    END;
    edD.SetWindowParams;
    edD.TextSync(TRUE);
    edD.TextCursor(TRUE);
  ELSIF I.closeWindow IN iMsg.class THEN
    IF edG.commLineMode IN edG.Status THEN
      ed1.EscapeCommLineMode;
    ELSE
      edD.PutBackLine;
    END;
    edD.SwitchEdit(edL.FindEdit(iMsg.idcmpWindow));
    ed1.dQuit;
  END;
  GadNum := NoGadget;
END IntuiCheck;

(*-----------------------------------------------------------------------*)
(*----- Programm Start --------------------------------------------------*)
(*-----------------------------------------------------------------------*)

BEGIN
  INCL(edG.Status,edG.noCursor);
  StartUp;
  EXCL(edG.Status,edG.noCursor);
  edD.TextCursor(TRUE);
  edL.Title(edG.Copyright); edG.Rc := edE.titleThreshhold+1;

(*-----------------------------------------------------------------------*)
(*----- Main Loop -------------------------------------------------------*)

  Mask := LONGSET{edG.MainPort.sigBit};
  IF edG.arexxAvail IN edG.Status THEN INCL(Mask,edR.AEdRxPortSigBit); END;
  DontWait := TRUE; GadNum := NoGadget;
  REPEAT (* Main *)
    IF NOT (edG.iconMode IN edG.Text.status) THEN edL.WindowTitle; END;
    EXCL(edG.Status,edG.memoryFail);
    IF DontWait THEN DontWait := FALSE;
                ELSE PortBits := e.Wait(Mask); END;
    (*
     *  NOTE: due to operation of edL.BreakCheck(), the userport signal
     *  may not be set even if there are messages pending.
     *)
    IF (edR.AEdRxPortSigBit IN PortBits) & ~(edG.multiMode IN edG.Status) THEN
(*---------- handle Rexx-Msg ---------------------------------------------*)
      LOOP
        rexxMsg := e.GetMsg(edR.AEdRxPort); IF rexxMsg = NIL THEN EXIT; END;
        IF rxs.IsRexxMsg(rexxMsg) OR edR.IsApplMsg(rexxMsg) THEN
          INCL(edG.Status,edG.isRexx);
          edG.Rc := edE.cmdValid0; ed1.HandleQuitFlags;
          edD.TextCursor(FALSE);
          edP.dCommand(rexxMsg.args[0]); (* Kommandos ausführen *)
          IF edG.Text # NIL THEN edD.TextCursor(TRUE); END;
          rexxMsg.result1 := edG.Rc;
          edG.Status := edG.Status-LONGSET{edG.isRexx,edG.isAppl};
        END;
        e.ReplyMsg(rexxMsg);
        IF edG.quitQuit IN edG.Status THEN EXIT; END;
      END;
(*---------- handle Intui-Msg --------------------------------------------*)
    ELSIF edG.MainPort.sigBit IN PortBits THEN  (* Port für alle Fenster *)
      LOOP
        iMsg := e.GetMsg(edG.MainPort); IF iMsg = NIL THEN EXIT; END;
        IntuiCheck;
        IF NOT (edG.dontReplyIntuiMsg IN edG.Status) THEN
          e.ReplyMsg(iMsg);
        END;
        EXCL(edG.Status,edG.dontReplyIntuiMsg);
        IF edG.quitQuit IN edG.Status THEN EXIT; END;
      END; (* LOOP *)
    END; (* sigBits *)
(*---------- handle Gadgets ----------------------------------------------*)
    IF GadNum # NoGadget THEN
      DontWait := TRUE;
      IF edG.commLineMode IN edG.Status THEN ed1.EscapeCommLineMode; END;
      edG.Rc := edE.cmdInitial;
      edD.TextCursor(FALSE);
      IF NOT (I.windowActive IN edG.Text.win.flags) THEN
        eGd.SetProp; END;
      CASE GadNum OF
       1: eGd.PropKnobAction; (* scrollbar *)
      |2: edM.dScrollUp;   (* arrow up   *)
      |3: edM.dScrollDown; (* arrow down *)
      ELSE END;
      edD.TextCursor(TRUE);
    END;
  UNTIL edG.quitQuit IN edG.Status; (* REPEAT: Main *)
END AmokEd.

