#include "struct.c"
#include "WinPlot.h"
#include "OutlineFont.h"
#include "amigawin.h"

/* like mui.h KeyButton, but with AmigaGuide node */
#define KeyButtonGuide(name, key, helpnode)\
	TextObject,\
		ButtonFrame,\
		MUIA_Text_Contents, name,\
		MUIA_Text_PreParse, "\33c",\
		MUIA_Text_SetMax  , FALSE,\
		MUIA_Text_HiChar  , key,\
		MUIA_ControlChar  , key,\
		MUIA_InputMode    , MUIV_InputMode_RelVerify,\
		MUIA_Background   , MUII_ButtonBack,\
                MUIA_HelpNode     , helpnode,\
		End

#define CheckMarkGuide(selected, helpnode)\
	ImageObject,\
		ImageButtonFrame,\
		MUIA_InputMode        , MUIV_InputMode_Toggle,\
		MUIA_Image_Spec       , MUII_CheckMark,\
		MUIA_Image_FreeVert   , TRUE,\
		MUIA_Selected         , selected,\
		MUIA_Background       , MUII_ButtonBack,\
		MUIA_ShowSelState     , FALSE,\
                MUIA_HelpNode         , helpnode,\
		End

#define CycleGuide(entries, helpnode)\
        CycleObject,\
         MUIA_Cycle_Entries , entries,\
         MUIA_HelpNode      , helpnode,\ 
        End

#define RangeObject(object, name)\
         Child, Label2(name"Min:"),\
         Child, object.Min = StringObject, MUIA_HelpNode, name"range", StringFrame, End,\
         Child, Label2(name"Max:"),\
         Child, object.Max = StringObject, MUIA_HelpNode, name"range", StringFrame, End,\
         Child, Label("Auto_"name":"),\
         Child, object.Auto = CheckMarkGuide(FALSE, "autoscale")

#define LogScaleObject(object, name)\
         Child, Label("LogScale_"name":"),\
         Child, object.LogScale = CheckMark(FALSE),\
         Child, Label2("LogBase:"),\
         Child, object.Base = StringObject, MUIA_Weight, 200, StringFrame, End

#define LabelObject(object, name)\
         Child, Label(name),\
         Child, object.Label = StringObject, StringFrame,\
          MUIA_HelpNode, name,\
         End,\
         Child, Label("X"),\
         Child, object.XOff = StringObject, StringFrame,\
          MUIA_Weight, 50,\
          MUIA_String_MaxLen, 6,\
          MUIA_String_Integer, 0,\
          MUIA_HelpNode, name,\
         End,\
         Child, Label("Y"),\
         Child, object.YOff = StringObject, StringFrame,\
          MUIA_Weight, 50,\
          MUIA_String_MaxLen, 6,\
          MUIA_String_Integer, 0,\
          MUIA_HelpNode, name,\
         End

#define WSpace(x) \
         MUI_NewObject(MUIC_Rectangle, \
                       MUIA_HorizWeight, 0, \
                       MUIA_VertWeight, x, \
		       TAG_DONE)

/* the ContourCycle labels */
static char *ContourEntries[] =
{
 "no", "base", "surface", "both", NULL
};

/* the Mapping labels */
static char *MappingEntries[] =
{
 "cartesian", "spherical", "cylindrical", NULL
};

/* the StyleCycle labels */
char *StyleEntries[] =
{
 "lines", "points", "impulses", "linespoints", "dots", "errorbars", "boxes",
 "boxerrorbars", "steps", NULL
};

/* the Settings pagegroup labels */
char *SetPages[] =
{
 "PlotRanges", "LogScales", "3D-Options", "Misc", "Fonts", "Labels", "Colors", 
 "User Defined", NULL,
};

/* the Gadget IDs */
enum IDs
{
 ID_ReqOk=1, ID_Load, ID_Save, ID_CD, ID_NewFont, ID_Color, ID_About,
 ID_Variable, ID_Function, ID_NewWindow, ID_Close                    /* ID_Close must be last !! */
};

/* some simple menu */
static struct NewMenu Menu[] =
{
 { NM_TITLE, "Project",   0,   0, 0, NULL},
 { NM_ITEM,  "About...",  "?", 0, 0, (APTR)ID_About},
 { NM_ITEM,  NM_BARLABEL, 0,   0, 0, 0},
 { NM_ITEM,  "Load",      "L", 0, 0, (APTR)ID_Load},
 { NM_ITEM,  "Save",      "S", 0, 0, (APTR)ID_Save},
 { NM_ITEM,  "CD",        "C", 0, 0, (APTR)ID_CD},
 { NM_ITEM,  NM_BARLABEL, 0,   0, 0, 0},
 { NM_ITEM,  "Quit",      "Q", 0, 0, (APTR)MUIV_Application_ReturnID_Quit},
 { NM_END,   NULL,        0,   0, 0, 0}
};

/* the MUI objects */
       APTR AP_WinPlot    = NULL; /* Application */
static APTR WI_Settings   = NULL; /* Settings window */
static APTR WI_Request    = NULL; /* Request window */
static APTR BT_ReqOk      = NULL; /* Quit Requester button */
       APTR LV_Font       = NULL; /* Font ListView */
static APTR TO_Req        = NULL; /* Requester text */
static APTR CY_Contour    = NULL; /* Contour gadget */
static APTR CY_Function   = NULL; /* Function Style gadget */
static APTR CY_Data       = NULL; /* Data Style gadget */
static APTR CY_Mapping    = NULL; /* Mapping gadget */
static APTR CM_Hidden3d   = NULL; /* Hidden3D button */
static APTR CM_Surface    = NULL;
static APTR SO_RotX       = NULL;
static APTR SO_RotZ       = NULL;
static APTR SO_Scale      = NULL;
static APTR SO_ScaleZ     = NULL;
static APTR SO_RePlot     = NULL; /* last plot command */
static APTR CM_Parametric = NULL;
static APTR CM_Polar      = NULL;
static APTR CM_Grid       = NULL;
static APTR CM_Border     = NULL;
static APTR CM_XZero      = NULL;
static APTR CM_YZero      = NULL;
static APTR PO_Color      = NULL;
static APTR BT_Color      = NULL;
static APTR LV_Variable   = NULL; /* user defined variables */
static APTR LV_Function   = NULL; /* user defined functions */
static APTR SO_Variable   = NULL;
static APTR SO_Function   = NULL;
       APTR RG_Set        = NULL; /* the settings register group */

static struct RangeObject    XRange, YRange, ZRange, RRange, TRange, URange, VRange;
static struct LogScaleObject XLog, YLog, ZLog;
static struct LabelObject    Title, XLabel, YLabel, ZLabel;

/* These are the plotwindows */
struct PlotWindow Windows[5];
LONG              ActiveWindow = 0;

/* this routine freshes the plot, e.g. after a font change */
void Refresh(void)
{
 struct Window *MainWindow;
 struct Gadget *PlotGadget;

 get(Windows[ActiveWindow].WI_Plot, MUIA_Window_Window, &MainWindow);
 get(Windows[ActiveWindow].BO_Plot, MUIA_Boopsi_Object, &PlotGadget);
 if (MainWindow && PlotGadget)
  RefreshGList(PlotGadget, MainWindow, NULL, 1);
}

/* build the fontlist */
static void InsertFonts(void)
{
 struct FileInfoBlock *fib;
 struct DevProc        *devproc = NULL;

 if (fib = AllocDosObject(DOS_FIB, NULL))
  {
   /* sometimes FONTS: is a MultiAssign */
   while (devproc = GetDeviceProc("FONTS:", devproc))
    {
     /* see Guru-Book  page.437 */
     struct MsgPort *old;
     BPTR dup;

     old = SetFileSysTask(devproc->dvp_Port);
     dup = DupLock(devproc->dvp_Lock);
     SetFileSysTask(old);

     if (dup)
      {
       Examine(dup, fib);
       while (ExNext(dup, fib) && (IoErr() != ERROR_NO_MORE_ENTRIES))
	DoMethod(LV_Font, MUIM_List_InsertSingle, fib, MUIV_List_Insert_Sorted);
       UnLock(dup);
      }
    }
   FreeDeviceProc(devproc);
   FreeDosObject(DOS_FIB, fib);
  }
}

/* Notifation for a RangeObject */
static void NotifyRange(APTR GUI, struct RangeObject *ro, char *name, char *command)
{
 DoMethod(ro->Min, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	  GUI, 4, MUIM_CallHook, &RangeHook, ro, name);
 DoMethod(ro->Max, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	  GUI, 4, MUIM_CallHook, &RangeHook, ro, name);
 DoMethod(ro->Auto, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	  ro->Auto, 3, MUIM_CallHook, &CheckHook, command);
}

/* Notification for a LogScaleObject */
static void NotifyLogScale(APTR GUI, struct LogScaleObject *lco, char *command)
{
 DoMethod(lco->LogScale, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	  lco->LogScale, 4, MUIM_CallHook, &LogScaleHook, lco, command);
 DoMethod(lco->Base, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	  GUI, 4, MUIM_CallHook, &LogScaleHook, lco, command);
}

/* Notification for a LabelObject */
static void NotifyLabel(APTR GUI, struct LabelObject *lo, char *title)
{
 DoMethod(lo->Label, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	  GUI, 4, MUIM_CallHook, &LabelHook, lo, title);
 DoMethod(lo->XOff, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	  GUI, 4, MUIM_CallHook, &LabelHook, lo, title);
 DoMethod(lo->YOff, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	  GUI, 4, MUIM_CallHook, &LabelHook, lo, title);
}

/* Build the Plot Window */
void InitPlotWindow(APTR GUI, int n)
{
 sprintf(Windows[n].Title, "WinPlot_%d", n+1);
 Windows[n].WI_Plot = WindowObject,
                       MUIA_Window_Title, Windows[n].Title,
                       MUIA_Window_ID,MAKE_ID('P','L','T','0'+n),
                       WindowContents, VGroup, 
                        Child, HGroup, GroupFrame,
                         MUIA_Group_SameSize, TRUE,
                         Child, Windows[n].BT_Plot = KeyButtonGuide("RePlot", 'p', "replot"),
                         Child, Windows[n].BT_Load = KeyButtonGuide("Load", 'l', "load"),
                         Child, Windows[n].BT_Save = KeyButtonGuide("Save", 's', "save"),
                         Child, Windows[n].BT_CD   = KeyButtonGuide("CD", 'c', "cd"),
                         Child, Windows[n].BT_Set  = KeyButtonGuide("Edit", 'e', "set-show"),
                         Child, Windows[n].BT_New  = KeyButton("New Window", 'n'),
                        End,
                        Child, Windows[n].BO_Plot = BoopsiObject,
                         GroupFrame,
                         MUIA_Boopsi_Class, PlotImgClass,
                         MUIA_Boopsi_MinWidth, 30,
                         MUIA_Boopsi_MinHeight, 30,
                         GA_LEFT, 0,
                         GA_TOP, 0,
                         GA_WIDTH, 0,
                         GA_HEIGHT, 0,
                        End,
                       End,
                      End;
 if (Windows[n].WI_Plot)
  {
   DoMethod(Windows[n].WI_Plot, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
	    GUI, 2, MUIM_Application_ReturnID, ID_Close + n);
   DoMethod(Windows[n].BT_Plot, MUIM_Notify, MUIA_Pressed, FALSE,
	    GUI, 3, MUIM_CallHook, &RexxCommandHook, "replot");
   DoMethod(Windows[n].BT_Load, MUIM_Notify, MUIA_Pressed, FALSE,
	    GUI, 2, MUIM_Application_ReturnID, ID_Load);
   DoMethod(Windows[n].BT_Save, MUIM_Notify, MUIA_Pressed, FALSE,
	    GUI, 2, MUIM_Application_ReturnID, ID_Save);
   DoMethod(Windows[n].BT_CD, MUIM_Notify, MUIA_Pressed, FALSE,
	    GUI, 2, MUIM_Application_ReturnID, ID_CD);
   DoMethod(Windows[n].BT_New, MUIM_Notify, MUIA_Pressed, FALSE,
	    GUI, 2, MUIM_Application_ReturnID, ID_NewWindow);
   DoMethod(Windows[n].BT_Set, MUIM_Notify, MUIA_Pressed, FALSE,
	    WI_Settings, 3, MUIM_Set, MUIA_Window_Open, TRUE);
   DoMethod(Windows[n].WI_Plot, MUIM_Notify, MUIA_Window_Activate, TRUE,
	    GUI, 3, MUIM_WriteLong, n, &ActiveWindow);
   DoMethod(GUI, OM_ADDMEMBER, Windows[n].WI_Plot);
  }
}

/* Build the GUI */
APTR GetGUI(void)
{
 APTR GUI;

 GUI = ApplicationObject,
	MUIA_Application_Title, "WinPlot",
	MUIA_Application_Version, "$VER: WinPlot 2.1  "__AMIGADATE__,
        MUIA_Application_Copyright, "Copyright © 1994 by Michael Illgner",
        MUIA_Application_Author, "Michael Illgner",
        MUIA_Application_Description, "A MUI GnuPlot Frontend",
        MUIA_Application_Base, "WINPLOT",
        MUIA_Application_SingleTask, TRUE,
        MUIA_Application_Menu, Menu,
	MUIA_HelpFile, "PROGDIR:gnuplot.guide",
        SubWindow, WI_Settings = WindowObject,
         MUIA_Window_Title, "GnuPlot settings",
         MUIA_Window_ID, MAKE_ID('P','S','E','T'),
         MUIA_HelpNode, "set-show",
         WindowContents, VGroup,
          Child, RG_Set = RegisterGroup(SetPages),
           MUIA_Register_Frame, TRUE,
            Child, VGroup,
            Child, WSpace(100), 
            Child, ColGroup(6),
             RangeObject(XRange, "X"),
             RangeObject(YRange, "Y"),
             RangeObject(ZRange, "Z"),
             RangeObject(RRange, "R"),
             RangeObject(TRange, "T"),
             RangeObject(URange, "U"),
             RangeObject(VRange, "V"),
            End,
            Child, WSpace(100),
           End,
           Child, VGroup,
            Child, WSpace(100),
            Child, ColGroup(4), MUIA_HelpNode, "logscale",
             LogScaleObject(XLog, "X"),
             LogScaleObject(YLog, "Y"),
             LogScaleObject(ZLog, "Z"),
            End,
            Child, WSpace(100),
           End,
           Child, VGroup,
            Child, WSpace(100),
            Child, VGroup,
             Child, ColGroup(4),
              Child, HSpace(0),
              Child, Label("Contour:"),
              Child, CY_Contour = CycleGuide(ContourEntries, "contour"),
              Child, HSpace(0),
              Child, HSpace(0),
              Child, Label("Mapping:"),
              Child, CY_Mapping = CycleGuide(MappingEntries, "mapping"),
              Child, HSpace(0),
             End,
             Child, WSpace(50),
             Child, ColGroup(4),
              Child, HSpace(0),
              Child, Label("Hidden3D:"),
              Child, CM_Hidden3d = CheckMarkGuide(FALSE, "hidden3d"),
              Child, HSpace(0),
              Child, HSpace(0),
              Child, Label("Surface"),
              Child, CM_Surface = CheckMarkGuide(FALSE, "surface"),
              Child, HSpace(0),
             End,
             Child, WSpace(50),
             Child, ColGroup(2),
              Child, Label("Rotation_X:"),
              Child, SO_RotX = StringObject, StringFrame,
               MUIA_HelpNode, "view",
              End,
              Child, Label("Rotation_Z:"),
              Child, SO_RotZ = StringObject, StringFrame,
               MUIA_HelpNode, "view",
              End,
              Child, Label("Scale:"),
              Child, SO_Scale = StringObject, StringFrame,
               MUIA_HelpNode, "view",
              End,
              Child, Label("Scale_Z:"),
              Child, SO_ScaleZ = StringObject, StringFrame,
               MUIA_HelpNode, "view",
              End,
             End,
            End,
            Child, WSpace(100),
           End,
           Child, VGroup,
            Child, WSpace(100),
            Child, ColGroup(6),
             Child, HSpace(0),
             Child, Label("Functionstyle:"),
             Child, CY_Function = CycleGuide(StyleEntries, "style"),
             Child, Label("Datastyle:"),
             Child, CY_Data = CycleGuide(StyleEntries, "style"),
             Child, HSpace(0),
             Child, HSpace(0),
             Child, WSpace(25),
             Child, WSpace(25),
             Child, WSpace(25),
             Child, WSpace(25),
             Child, HSpace(0),
             Child, HSpace(0),
             Child, Label("Parametric:"),
             Child, CM_Parametric = CheckMarkGuide(FALSE, "parametric"),
             Child, Label("Polar:"),
             Child, CM_Polar = CheckMarkGuide(FALSE, "polar"),
             Child, HSpace(0),
             Child, HSpace(0),
             Child, Label("Grid:"),
             Child, CM_Grid = CheckMarkGuide(FALSE, "grid"),
             Child, Label("Border:"),
             Child, CM_Border = CheckMarkGuide(FALSE, "border"),
             Child, HSpace(0),
             Child, HSpace(0),
             Child, Label("xzeroaxis"),
             Child, CM_XZero = CheckMarkGuide(FALSE, "xzeroaxis"),
             Child, Label("yzeroaxis"),
             Child, CM_YZero = CheckMarkGuide(FALSE, "yzeroaxis"),
             Child, HSpace(0),
            End,
            Child, WSpace(100),
           End,
           Child, LV_Font = ListviewObject, InputListFrame,
            MUIA_Listview_List, ListObject,
             MUIA_List_ConstructHook, &ConFontHook,
             MUIA_List_DestructHook, &DesFontHook,
            End,
           End,
           Child, VGroup,
            Child, WSpace(100),
            Child, ColGroup(6),
             LabelObject(Title, "Title"),
             LabelObject(XLabel, "XLabel"),
             LabelObject(YLabel, "YLabel"),
             LabelObject(ZLabel, "ZLabel"),
            End,
            Child, WSpace(100),
           End,
           Child, VGroup,
            Child, WSpace(100),
            Child, PO_Color = PaletteObject, GroupFrame,
             MUIA_Palette_Entries, ColorEntries,
             MUIA_Palette_Names, ColorNames,
            End,
            Child, WSpace(50),
            Child, BT_Color = KeyButton("Change Colors", 'c'),
            Child, WSpace(100),
           End,
           Child, VGroup,
            MUIA_HelpNode, "user-defined",
            Child, VGroup, InputListFrame,
             Child, LV_Variable = ListviewObject,
              MUIA_FrameTitle, "User defined Variables",
              MUIA_Listview_List, ListObject,
               MUIA_List_ConstructHook, &ConVarHook,
               MUIA_List_DestructHook, &DesVarHook,
              End,
             End,
             Child, VSpace(1),
             Child, SO_Variable = StringObject, StringFrame, 
              MUIA_String_AttachedList, LV_Variable,
             End,
            End,
            Child, VSpace(5),
            Child, VGroup, InputListFrame,
             Child, LV_Function = ListviewObject,
              MUIA_FrameTitle, "User defined Functions",
              MUIA_Listview_List, ListObject, End,
             End,
             Child, VSpace(1),
             Child, SO_Function = StringObject, StringFrame,
              MUIA_String_AttachedList, LV_Function,
              End,
            End,
           End,
          End,
          Child, VGroup,
           MUIA_Frame, MUIV_Frame_String,
           MUIA_FrameTitle, "Last Plot",
           Child, SO_RePlot = StringObject,
            MUIA_HelpNode, "plot",
           End,
          End,
         End,
        End,
        SubWindow, WI_Request = WindowObject,
         MUIA_Window_Title, "WinPlot Requester",
         MUIA_Window_SizeGadget, FALSE,
         MUIA_Window_CloseGadget, FALSE,
         MUIA_Window_ID, MAKE_ID('P','R','E','Q'),
         WindowContents, VGroup,
 	  MUIA_Background, MUII_RequesterBack,
          Child, TO_Req = TextObject, TextFrame,
	   MUIA_Background, MUII_TextBack,
           MUIA_Text_PreParse, "\33c",
          End,
	  Child, BT_ReqOk = TextObject,
           ButtonFrame,
	   MUIA_Text_Contents, "Ok",
           MUIA_Text_PreParse, "\33c",
           MUIA_Text_SetMax, TRUE,
           MUIA_Text_HiChar, '\r',
           MUIA_ControlChar, '\r',
           MUIA_InputMode, MUIV_InputMode_RelVerify,
           MUIA_Background, MUII_ActiveBack,
          End,
         End,
        End,
       End;

 if (GUI)
  {
   DoMethod(WI_Settings, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
            WI_Settings, 3, MUIM_Set, MUIA_Window_Open, FALSE);
   DoMethod(SO_RePlot, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	    SO_RePlot, 2, MUIM_CallHook, &StringCommandHook);
   DoMethod(BT_ReqOk, MUIM_Notify, MUIA_Pressed, FALSE,
	    GUI, 2, MUIM_Application_ReturnID, ID_ReqOk);
   DoMethod(LV_Font, MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
	    GUI, 2, MUIM_Application_ReturnID, ID_NewFont);
   NotifyRange(GUI, &XRange, "xrange", "set %sautoscale x");
   NotifyRange(GUI, &YRange, "yrange", "set %sautoscale y");
   NotifyRange(GUI, &ZRange, "zrange", "set %sautoscale z");
   NotifyRange(GUI, &RRange, "rrange", "set %sautoscale r");
   NotifyRange(GUI, &TRange, "trange", "set %sautoscale t");
   NotifyRange(GUI, &URange, "urange", "set %sautoscale u");
   NotifyRange(GUI, &VRange, "vrange", "set %sautoscale v");
   DoMethod(CM_Hidden3d, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_Hidden3d, 3, MUIM_CallHook, &CheckHook, "set %shidden3d");
   DoMethod(CM_Parametric, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_Parametric, 3, MUIM_CallHook, &CheckHook, "set %sparametric");
   DoMethod(CM_Polar, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_Polar, 3, MUIM_CallHook, &CheckHook, "set %spolar");
   DoMethod(CM_Grid, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_Grid, 3, MUIM_CallHook, &CheckHook, "set %sgrid");
   DoMethod(CM_Border, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_Border, 3, MUIM_CallHook, &CheckHook, "set %sborder");
   DoMethod(CM_XZero, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_XZero, 3, MUIM_CallHook, &CheckHook, "set %sxzeroaxis");
   DoMethod(CM_YZero, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_YZero, 3, MUIM_CallHook, &CheckHook, "set %syzeroaxis");
   DoMethod(CM_Surface, MUIM_Notify, MUIA_Selected, MUIV_EveryTime,
	    CM_Surface, 3, MUIM_CallHook, &CheckHook, "set %ssurface");
   DoMethod(CY_Contour, MUIM_Notify, MUIA_Cycle_Active, 0,
            GUI, 3, MUIM_CallHook, &RexxCommandHook, "set nocontour");
   DoMethod(CY_Contour, MUIM_Notify, MUIA_Cycle_Active, 1,
            GUI, 3, MUIM_CallHook, &RexxCommandHook, "set contour base");
   DoMethod(CY_Contour, MUIM_Notify, MUIA_Cycle_Active, 2,
            GUI, 3, MUIM_CallHook, &RexxCommandHook, "set contour surface");
   DoMethod(CY_Contour, MUIM_Notify, MUIA_Cycle_Active, 3,
            GUI, 3, MUIM_CallHook, &RexxCommandHook, "set contour both");
   DoMethod(CY_Mapping, MUIM_Notify, MUIA_Cycle_Active, 0,
	    GUI, 3, MUIM_CallHook, &RexxCommandHook, "set mapping cartesian");
   DoMethod(CY_Mapping, MUIM_Notify, MUIA_Cycle_Active, 1,
	    GUI, 3, MUIM_CallHook, &RexxCommandHook, "set mapping spherical");
   DoMethod(CY_Mapping, MUIM_Notify, MUIA_Cycle_Active, 2,
	    GUI, 3, MUIM_CallHook, &RexxCommandHook, "set mapping cylindrical");
   DoMethod(SO_RotX, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	    SO_RotX, 3, MUIM_CallHook, &ViewHook, "set view %s");
   DoMethod(SO_RotZ, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	    SO_RotZ, 3, MUIM_CallHook, &ViewHook, "set view ,%s");
   DoMethod(SO_Scale, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	    SO_Scale, 3, MUIM_CallHook, &ViewHook, "set view ,,%s");
   DoMethod(SO_ScaleZ, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	    SO_ScaleZ, 3, MUIM_CallHook, &ViewHook, "set view ,,,%s");
   DoMethod(CY_Function, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
	    CY_Function, 3, MUIM_CallHook, &StyleHook, "set function style %s");
   DoMethod(CY_Data, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime,
	    CY_Data, 3, MUIM_CallHook, &StyleHook, "set data style %s");
   NotifyLogScale(GUI, &XLog, "set %slogscale x %s");
   NotifyLogScale(GUI, &YLog, "set %slogscale y %s");
   NotifyLogScale(GUI, &ZLog, "set %slogscale z %s");
   NotifyLabel(GUI, &Title, "title");
   NotifyLabel(GUI, &XLabel, "xlabel");
   NotifyLabel(GUI, &YLabel, "ylabel");
   NotifyLabel(GUI, &ZLabel, "zlabel");
   DoMethod(BT_Color, MUIM_Notify, MUIA_Pressed, FALSE,
	    GUI, 2, MUIM_Application_ReturnID, ID_Color);
   DoMethod(LV_Variable ,MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
	    GUI, 2, MUIM_Application_ReturnID, ID_Variable);
   DoMethod(SO_Variable, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	    SO_Variable, 2, MUIM_CallHook, &StringCommandHook);
   DoMethod(LV_Function ,MUIM_Notify, MUIA_Listview_DoubleClick, TRUE,
	    GUI, 2, MUIM_Application_ReturnID, ID_Function);
   DoMethod(SO_Function, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
	    SO_Function, 2, MUIM_CallHook, &StringCommandHook);
   InsertFonts();
   LoadConf();
   InitPlotWindow(GUI, 0); ActiveWindow = 0;

   DoMethod(WI_Settings, MUIM_Window_SetCycleChain,
	    SO_RePlot,
	    XRange.Min, XRange.Max, XRange.Auto,
	    YRange.Min, YRange.Max, YRange.Auto,
	    ZRange.Min, ZRange.Max, ZRange.Auto,
	    RRange.Min, RRange.Max, RRange.Auto,
	    TRange.Min, TRange.Max, TRange.Auto,
	    URange.Min, URange.Max, URange.Auto,
	    VRange.Min, VRange.Max, VRange.Auto,
	    XLog.LogScale, XLog.Base,
	    YLog.LogScale, YLog.Base,
	    ZLog.LogScale, ZLog.Base,
	    CY_Contour, CY_Mapping, CM_Hidden3d, CM_Surface,
	    SO_RotX, SO_RotZ, SO_Scale, SO_ScaleZ,
	    CY_Data, CY_Function,
            CM_Parametric, CM_Polar, CM_Grid, CM_Border, CM_XZero, CM_YZero,
	    LV_Font,
	    Title.Label, Title.XOff, Title.YOff,
	    XLabel.Label, XLabel.XOff, XLabel.YOff,
	    YLabel.Label, YLabel.XOff, YLabel.YOff,
	    ZLabel.Label, ZLabel.XOff, ZLabel.YOff,
            PO_Color, BT_Color,
	    LV_Variable, SO_Variable,
	    LV_Function, SO_Function,
            NULL);
  }

 return GUI;
}

/* the 'please press <return>' requester */
/* it looks like a requester, but is in fact a window */
void WaitRequest(char *Text)
{
 BOOL Quit = FALSE;
 int  i;
  
 set(TO_Req, MUIA_Text_Contents, Text);
 set(WI_Request, MUIA_Window_Open, TRUE);

 /* disable the mainbuttons in all PlotWindows */
 for(i=0; i<MAXWINDOW; i++)
  if (Windows[i].WI_Plot)
   DoMethod(WI_Request, MUIM_MultiSet, MUIA_Disabled, TRUE,
	    Windows[i].BT_Plot, Windows[i].BT_CD, Windows[i].BT_Load,
	    Windows[i].BT_Save, Windows[i].BT_New,
	    NULL);

 while (!Quit)
  {
   ULONG ID, Signals;
   
   ID = DoMethod(AP_WinPlot, MUIM_Application_Input, &Signals);
   switch (ID)
    {
    case ID_ReqOk:
     Quit = TRUE;
     break;
    }
   if (Signals) Wait(Signals);
  }

 /* enable the main buttons */
 for(i=0; i<MAXWINDOW; i++)
  if (Windows[i].WI_Plot)
   DoMethod(WI_Request, MUIM_MultiSet, MUIA_Disabled, FALSE,
	    Windows[i].BT_Plot, Windows[i].BT_CD, Windows[i].BT_Load,
	    Windows[i].BT_Save, Windows[i].BT_New,
	    NULL);

 set(WI_Request, MUIA_Window_Open, FALSE);
}

/* set StringObject to double*/
static void SetString(APTR so, double val)
{
 char Buffer[255];
 
 sprintf(Buffer, "%lg", val);
 nnset(so, MUIA_String_Contents, Buffer);
 nnset(so, MUIA_String_BufferPos, 0);
}

/* set RangeObject values */
static void SetRange(struct RangeObject ro, double min, double max, BOOL autorange)
{
 SetString(ro.Min, min);
 SetString(ro.Max, max);
}

/* set LogScaleObject values */
static void SetLogScale(struct LogScaleObject lco, double base, BOOL logscale)
{
 if (base != 0.0)
  SetString(lco.Base, base);
 nnset(lco.LogScale, MUIA_Selected, logscale);
}

/* set LabelObject values */
static void SetLabel(struct LabelObject lo, char *Title, int XOff, int YOff)
{
 nnset(lo.Label, MUIA_String_Contents, Title);
 nnset(lo.Label, MUIA_String_BufferPos, 0);
 nnset(lo.XOff, MUIA_String_Integer, XOff);
 nnset(lo.YOff, MUIA_String_Integer, YOff);
}

void Settings(struct SetVar *sv)
{
 udvt_entry *udv;
 udft_entry *udf;

 if (sv)
  {
   SetRange(XRange, sv->xmin, sv->xmax, sv->autox);
   SetRange(YRange, sv->ymin, sv->ymax, sv->autoy);
   SetRange(ZRange, sv->zmin, sv->zmax, sv->autoz);
   SetRange(RRange, sv->rmin, sv->rmax, sv->autor);
   SetRange(TRange, sv->tmin, sv->tmax, sv->autot);
   SetRange(URange, sv->umin, sv->umax, sv->autou);
   SetRange(VRange, sv->vmin, sv->vmax, sv->autov);

   SetLogScale(XLog, sv->basex, sv->logx);
   SetLogScale(YLog, sv->basey, sv->logy);
   SetLogScale(ZLog, sv->basez, sv->logz);

   nnset(CY_Contour, MUIA_Cycle_Active, sv->contour);
   nnset(CY_Mapping, MUIA_Cycle_Active, sv->mapping);
   nnset(CM_Hidden3d, MUIA_Selected, sv->hidden3d);
   nnset(CM_Surface, MUIA_Selected, sv->surface);
   SetString(SO_RotX, sv->rotx);
   SetString(SO_RotZ, sv->rotz);
   SetString(SO_Scale, sv->scale);
   SetString(SO_ScaleZ, sv->zscale);
   nnset(CY_Function, MUIA_Cycle_Active, sv->functionstyle);
   nnset(CY_Data, MUIA_Cycle_Active, sv->datastyle);
   
   nnset(CM_Parametric, MUIA_Selected, sv->parametric);
   nnset(CM_Polar, MUIA_Selected, sv->polar);
   nnset(CM_Grid, MUIA_Selected, sv->grid);
   nnset(CM_Border, MUIA_Selected, sv->border);
   nnset(CM_XZero, MUIA_Selected, sv->xzeroaxis);
   nnset(CM_YZero, MUIA_Selected, sv->yzeroaxis);

   SetLabel(Title, sv->title, sv->title_xoff, sv->title_yoff);
   SetLabel(XLabel, sv->xlabel, sv->xlabel_xoff, sv->xlabel_yoff);
   SetLabel(YLabel, sv->ylabel, sv->ylabel_xoff, sv->ylabel_yoff);
   SetLabel(ZLabel, sv->zlabel, sv->zlabel_xoff, sv->zlabel_yoff);

   nnset(SO_RePlot, MUIA_String_Contents, sv->replot);
   nnset(SO_RePlot, MUIA_String_BufferPos, 0);

   set(LV_Variable, MUIA_List_Quiet, TRUE);
   DoMethod(LV_Variable, MUIM_List_Clear);
   for(udv = sv->user_variables; udv; udv=udv->next_udv)
    DoMethod(LV_Variable, MUIM_List_InsertSingle, udv, MUIV_List_Insert_Bottom);
   set(LV_Variable, MUIA_List_Quiet, FALSE);

   set(LV_Function, MUIA_List_Quiet, TRUE);
   DoMethod(LV_Function, MUIM_List_Clear);
   for(udf = sv->user_functions; udf; udf=udf->next_udf)
    DoMethod(LV_Function, MUIM_List_InsertSingle, udf->definition, MUIV_List_Insert_Bottom);
   set(LV_Function, MUIA_List_Quiet, FALSE);
  }
}

BOOL HandleMUI(LONG Id)
{
 BOOL   Quit = FALSE;
 int    i, NewWindow;
 char  *s;

 switch(Id)
  {
  case MUIV_Application_ReturnID_Quit:
   if (MUI_Request(AP_WinPlot, NULL, 0, NULL, "Ok|*Cancel", "Do you really want to quit ?!"))
    {
     if (FindPort(GNUREPLY))
      SendRexxMsg("quit");
     else Quit = TRUE;
    }
   break;
  case ID_NewFont:
   DoMethod(LV_Font, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &s);
   CloseOutlineFont();
   OpenOutlineFont(s);
   Refresh();
   break;
  case ID_Load:
   LoadFunc();
   break;
  case ID_Save:
   SaveFunc();
   break;
  case ID_CD:
   CDFunc();
   break;
  case ID_Color:
   Refresh();
   break;
  case ID_About:
   MUI_Request(AP_WinPlot, NULL, 0, NULL, "OK",
	       "\033c\0338WinPlot\n\n"
	       "\0332Version 2.1  ("__DATE__")\n"
	       "Copyright 1994 by Michael Illgner.\n"
	       "\nThis is a MUI-Application.\n"
	       "MUI is copyrighted by Stefan Stuntz.");
   break;
  case ID_Variable:
   DoMethod(LV_Variable, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &s);
   set(SO_Variable, MUIA_String_Contents, s);
   break;
  case ID_Function:
   DoMethod(LV_Function, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &s);
   set(SO_Function, MUIA_String_Contents, s);
   break;
  case ID_NewWindow:
   NewWindow = -1; i = 0;
   while(NewWindow < 0 && i < MAXWINDOW)
    {
     if (Windows[i].WI_Plot == NULL)
      NewWindow = i;
     i++;
    }
   if (NewWindow >= 0 && NewWindow < MAXWINDOW)
    {
     InitPlotWindow(AP_WinPlot, NewWindow);
     set(Windows[NewWindow].WI_Plot, MUIA_Window_Open, TRUE);
     ActiveWindow = NewWindow;
    }
   else
    WaitRequest("Sorry, No more Windows available");
   break;
  default:
   if (Id >= ID_Close && Id < ID_Close+MAXWINDOW)
    {
     int OpenWindows = 0;
     
     for(i=0; i<MAXWINDOW; i++)
      if (Windows[i].WI_Plot)
       OpenWindows++;
     
     if (OpenWindows != 1)
      {
       set(Windows[Id-ID_Close].WI_Plot, MUIA_Window_Open, FALSE);
       DoMethod(AP_WinPlot, OM_REMMEMBER, Windows[Id-ID_Close].WI_Plot);
       MUI_DisposeObject(Windows[Id-ID_Close].WI_Plot);
       Windows[Id-ID_Close].WI_Plot = NULL;
      }
     else /* Last Window is closed */
      if (MUI_Request(AP_WinPlot, NULL, 0, NULL, "Ok|*Cancel", "Do you really want to quit ?!"))
       {
	if (FindPort(GNUREPLY))
	 SendRexxMsg("quit");
	else Quit = TRUE;
       }
    }
   break;
  }

 return Quit;
}
