(*
	
	This module handles the control panel for the 
	Chaos program.
        
        Created: 8/22/87 by Richie Bielak
        
        Copyright (c) 1987 by Richie Bielak
        
        This program maybe freely distributed, but please leave
        my name in. Thanks.....Richie

*)
IMPLEMENTATION MODULE ChaosPanel;

FROM SYSTEM    IMPORT ADR, BYTE, ADDRESS, LONG, SHORT, LONGWORD;
FROM Ports     IMPORT WaitPort, ReplyMsg, GetMsg, MessagePtr;
FROM SimpleWindows IMPORT CreateWindow;
FROM SimpleGadgets IMPORT BeginGadgetList, EndGadgetList, FreeGadgetList,
               LastGadget, AddGadgetTextButton, AddGadgetString,
	       AddGadgetInteger;
FROM Rasters   IMPORT Jam2, Jam1, DrawModeSet;
FROM Intuition IMPORT
               (* Types *)
	       WindowPtr, ScreenPtr, WindowFlags, CustomScreen,
	       WindowFlagsSet, IDCMPFlags, IDCMPFlagsSet, Gadget, BoolGadget,
	       IntuiText, GadgetTypeSet, GadgetFlagsSet, Border,
	       GadgetActivationSet, GadgetActivation, GadgetMutualExcludeSet,
	       IntuiMessagePtr, GadgetPtr, StringInfoPtr,
	       (* Procedures *)
	       OpenWindow, CloseWindow;
FROM RealConversions IMPORT ConvStringToReal, ConvRealToString, Decimal;
FROM Conversions IMPORT ConvStringToNumber, ConvNumberToString;
FROM ChaosUtil IMPORT InitTextItem;

CONST
  LeftCol  = 30;
  RightCol = 220;
  BuffSize = 10;

TYPE
  PanelGadgetType = (OKGad, CancelGad, aCoeffGad, xIncGad, yIncGad,
                     MaxIterGad, MaxOrbGad, MaxClrGad, ZoomGad);
  Buffer = ARRAY [0..BuffSize-1] OF CHAR;
  Buffp  = POINTER TO Buffer;

VAR
  GListPtr : GadgetPtr;
  GadText  : ARRAY [aCoeffGad..ZoomGad] OF IntuiText;
  BuffPtr  : ARRAY [aCoeffGad..ZoomGad] OF Buffp;

(*++++++++++++++++++++++++++++++++++++++ *)
(* Initialize and open a window.         *)
PROCEDURE InitWindow (sp : ScreenPtr) : WindowPtr;
  BEGIN
    RETURN
      CreateWindow (0, 12, 320, 188,
                    IDCMPFlagsSet {GadgetUp, GadgetDown},
                    WindowFlagsSet {Activate}, GListPtr, sp,
	            ADR ("Control Panel"));
  END InitWindow;

(* +++++++++++++++++++++++++++++++ *)
PROCEDURE SetGadgetValues ();
  BEGIN
    WITH ControlValues DO
      ConvRealToString (a, BuffPtr[aCoeffGad]^, 6, Decimal);
      ConvRealToString (xInc, BuffPtr[xIncGad]^, 6, Decimal);
      ConvRealToString (yInc, BuffPtr[yIncGad]^, 6, Decimal);
      ConvRealToString (ZoomFactor, BuffPtr[ZoomGad]^, 6, Decimal);
      ConvNumberToString (BuffPtr[MaxIterGad]^, LONG(IterPerOrbit), 
                          FALSE, 10, 6, " ");
      ConvNumberToString (BuffPtr[MaxOrbGad]^, LONG(MaxOrbits), 
                          FALSE, 10, 6, " ");
      ConvNumberToString (BuffPtr[MaxClrGad]^, LONG(MaxColors), 
                          FALSE, 10, 6, " ");
    END;
  END SetGadgetValues;

(* +++++++++++++++++++++++++++++++ *)
PROCEDURE GetGadgetValues ();
  VAR succ : BOOLEAN; lw : LONGWORD;
  BEGIN
    WITH ControlValues DO
      a := ConvStringToReal (BuffPtr[aCoeffGad]^);
      xInc := ConvStringToReal (BuffPtr[xIncGad]^);
      yInc := ConvStringToReal (BuffPtr[yIncGad]^);
      ZoomFactor := ConvStringToReal  (BuffPtr[ZoomGad]^);
      succ := ConvStringToNumber (BuffPtr[MaxIterGad]^, lw,
                                  FALSE, 10);
      IF succ THEN IterPerOrbit := INTEGER(lw) END;
      succ := ConvStringToNumber (BuffPtr[MaxOrbGad]^, lw,
                                  FALSE, 10);
      IF succ THEN MaxOrbits := INTEGER(lw) END;
      succ := ConvStringToNumber (BuffPtr[MaxClrGad]^, lw,
                                  FALSE, 10);
      IF succ THEN MaxColors := INTEGER(lw) END;

    END;
  END GetGadgetValues;

(* +++++++++++++++++++++++++++++++ *)
PROCEDURE ProcessGadgets (gptr : GadgetPtr; VAR quit : BOOLEAN);
  BEGIN
    CASE PanelGadgetType (gptr^.GadgetID) OF
      OKGad:  
        GetGadgetValues ();
        quit := TRUE;  |
      CancelGad:
        quit := TRUE;
    END; (* CASE *)
  END ProcessGadgets;

(* +++++++++++++++++++++++++++++++ *)
(* Open a window with some gadgets *)
PROCEDURE ControlPanel (sp : ScreenPtr);
  VAR
    wp : WindowPtr;
    class  : IDCMPFlagsSet;
    msgptr : IntuiMessagePtr;
    gptr : GadgetPtr;
    quit : BOOLEAN;
  BEGIN
    SetGadgetValues ();
    quit := FALSE;
    wp := InitWindow (sp);
    (* Now wait for gadget messages *)
    REPEAT
      msgptr := WaitPort (wp^.UserPort^);
      LOOP
        msgptr := GetMsg (wp^.UserPort^);
        IF msgptr = NIL THEN EXIT END;
        class := msgptr^.Class; gptr := msgptr^.IAddress;        
        ReplyMsg (MessagePtr (msgptr));
	IF class = IDCMPFlagsSet {GadgetUp} THEN
          ProcessGadgets (gptr, quit);	  
	END;
      END; (* LOOP *)
    UNTIL quit;
    CloseWindow (wp^)
  END ControlPanel;

(* ++++++++++++++++++++++++++++++++++++++++ *)
PROCEDURE InitStringGad (gad : PanelGadgetType; text : ADDRESS;
                         L, T : INTEGER);
  VAR
    sp : StringInfoPtr;
  BEGIN
    AddGadgetString (L, T, BuffSize-1, BuffSize, NIL);
    InitTextItem (GadText[gad], text, 0, -10);
    LastGadget^.GadgetText := ADR(GadText[gad]);
    (* Now get the pointer to the buffer *)
    sp := LastGadget^.SpecialInfo;
    BuffPtr[gad] := sp^.Buffer;
  END InitStringGad;

(* ++++++++++++++++++++++++++++++++++++++++ *)
PROCEDURE SetUpPanelGadgets ();
  BEGIN
    BeginGadgetList ();
    AddGadgetTextButton (RightCol, 160, ADR("  OK  "));
    AddGadgetTextButton (LeftCol,  160, ADR("Cancel"));    
    InitStringGad (aCoeffGad, ADR('"A" coeff'), LeftCol, 40);
    InitStringGad (xIncGad, ADR('"X" inc'), LeftCol, 75);
    InitStringGad (yIncGad, ADR('"Y" inc'), LeftCol, 110);
    InitStringGad (MaxIterGad, ADR('Iter/Orbit'), RightCol, 40);
    InitStringGad (MaxOrbGad, ADR(' Orbits'), RightCol, 75);
    InitStringGad (MaxClrGad,  ADR(' Colors'), RightCol, 110);
    InitStringGad (ZoomGad,  ADR('Zoom Factor'), 
                   (LeftCol+RightCol) DIV 2, 140);
    (* Adjust the text slightly for the ZOOM factor gadget *)
    GadText[ZoomGad].LeftEdge := -6;
    GListPtr := EndGadgetList ();
  END SetUpPanelGadgets;

(* ++++++++++++++++++++++++++++++++++++++++ *)
PROCEDURE CleanUpPanelGadgets ();
  BEGIN
    FreeGadgetList (GListPtr^);
  END CleanUpPanelGadgets;

BEGIN
  (* Put in some initial values *)
  WITH ControlValues DO
    a := 1.5732;
    xInc := 0.02; yInc := 0.02;
    ZoomFactor := 1.0;
    IterPerOrbit := 1000;
    MaxOrbits := 100;
    MaxColors := 15;
  END;
END ChaosPanel.
