/************************************************************************
                         Parameter Requester                  2 August 87
************************************************************************/
#include <exec/types.h>
#include <intuition/intuition.h>

#include "shm_defines"

extern int hc,hcd,vc,vcd,hs,hsd,vs,vsd;
extern double hpp,hppd,vpp,vppd,hsp,hspd,vsp,vspd,di,did,sf,sfd,cp,cpd;

extern struct TextAttr Fnt;

/************************************************************************
                          Parameter Definitions
************************************************************************/
char horiz_centre_str[6],    vert_centre_str[6],
     horiz_size_str[6],      vert_size_str[6],
     horiz_pri_phase_str[6], vert_pri_phase_str[6],
     horiz_sec_phase_str[6], vert_sec_phase_str[6],
     decay_str[6],     freq_str[6],    coup_str[6];

struct IntuiText parms_txt =  {1, 0, JAM1, 132, 3, &Fnt,
                              (UBYTE *)"PARAMETER SETTINGS", NL};
struct IntuiText horiz_txt =  {1, 0, JAM1, 65, 14, &Fnt,
                              (UBYTE *)"Horizontal", &parms_txt};
struct IntuiText vert_txt  =  {1, 0, JAM1, 263, 14, &Fnt,
                              (UBYTE *)"Vertical", &horiz_txt};
struct IntuiText centre_txt = {1, 0, JAM1, 177, 27, &Fnt,
                              (UBYTE *)"CENTRE", &vert_txt};
struct IntuiText size_txt   = {1, 0, JAM1, 183, 41, &Fnt,
                              (UBYTE *)"SIZE", &centre_txt};
struct IntuiText pri_txt    = {1, 0, JAM1, 171, 53, &Fnt,
                              (UBYTE *)"Primary", &size_txt};
struct IntuiText phase_txt  = {1, 0, JAM1, 180, 63, &Fnt,
                              (UBYTE *)"PHASE", &pri_txt};
struct IntuiText sec_txt    = {1, 0, JAM1, 164, 71, &Fnt,
                              (UBYTE *)"Secondary", &phase_txt};
struct IntuiText decay_txt  = {1, 0, JAM1, 164, 84, &Fnt,
                              (UBYTE *)"DECAY", &sec_txt};
struct IntuiText freq_txt   = {1, 0, JAM1, 164, 98, &Fnt,
                              (UBYTE *)"FREQUENCY", &decay_txt};
struct IntuiText coup_txt   = {1, 0, JAM1, 164, 112, &Fnt,
                              (UBYTE *)"COUPLING", &freq_txt};
struct IntuiText horiz_centre_val_txt  = {1, 3, JAM2, -44, 2, &Fnt,
                              (UBYTE *)horiz_centre_str, NL};
struct IntuiText vert_centre_val_txt  = {1, 3, JAM2, 114, 2, &Fnt,
                              (UBYTE *)vert_centre_str, NL};
struct IntuiText horiz_size_val_txt  = {1, 3, JAM2, -44, 2, &Fnt,
                              (UBYTE *)horiz_size_str, NL};
struct IntuiText vert_size_val_txt  = {1, 3, JAM2, 114, 2, &Fnt,
                              (UBYTE *)vert_size_str, NL};
struct IntuiText horiz_pri_phase_val_txt  = {1, 3, JAM2, -44, 2, &Fnt,
                              (UBYTE *)horiz_pri_phase_str, NL};
struct IntuiText vert_pri_phase_val_txt  = {1, 3, JAM2, 114, 2, &Fnt,
                              (UBYTE *)vert_pri_phase_str, NL};
struct IntuiText horiz_sec_phase_val_txt  = {1, 3, JAM2, -44, 2, &Fnt,
                              (UBYTE *)horiz_sec_phase_str, NL};
struct IntuiText vert_sec_phase_val_txt  = {1, 3, JAM2, 114, 2, &Fnt,
                              (UBYTE *)vert_sec_phase_str, NL};
struct IntuiText decay_val_txt  = {1, 3, JAM2, -44, 2, &Fnt,
                              (UBYTE *)decay_str, NL};
struct IntuiText freq_val_txt  = {1, 3, JAM2, -44, 2, &Fnt,
                              (UBYTE *)freq_str, NL};
struct IntuiText coup_val_txt  = {1, 3, JAM2, -44, 2, &Fnt,
                              (UBYTE *)coup_str, NL};

/************************* Parameter Switches *************************/

struct Image parm_gad_img = {0,0, 154,11, 1, NL, 0, 2, NL};

struct IntuiText parm_cancel_txt = {3, 0, JAM1, 55, 2, &Fnt,
                                   (UBYTE *)"Cancel", NL};
struct Gadget parm_cancel_gad =
{
NL,
240, 84, 154, 11,
GADGHBOX | GADGIMAGE,
RELVERIFY,
BOOLGADGET | REQGADGET,
(APTR)&parm_gad_img, NL,
&parm_cancel_txt,
NL, NL, 1, NL
};

struct IntuiText parm_def_txt    = {3, 0, JAM1, 47, 2, &Fnt,
                                   (UBYTE *)"Default ", NL};
struct Gadget parm_def_gad =
{
&parm_cancel_gad,
240, 97, 154, 11,
GADGHBOX | GADGIMAGE,
RELVERIFY,
BOOLGADGET | REQGADGET,
(APTR)&parm_gad_img, NL,
&parm_def_txt,
NL, NL, 2, NL
};

struct IntuiText parm_ok_txt     = {3, 0, JAM1, 67, 2, &Fnt,
                                   (UBYTE *)"OK", NL};
struct Gadget parm_ok_gad =
{
&parm_def_gad,
240, 110, 154, 11,
GADGHBOX | GADGIMAGE,
RELVERIFY | ENDGADGET,
BOOLGADGET | REQGADGET,
(APTR)&parm_gad_img, NL,
&parm_ok_txt,
NL, NL, 3, NL
};
/************************* Parameter Sliders **************************/

struct Image horiz_centre_image, vert_centre_image,
             horiz_size_image, vert_size_image,
             horiz_pri_phase_image, vert_pri_phase_image,
             horiz_sec_phase_image, vert_sec_phase_image,
             decay_image, freq_image, coup_image;

struct PropInfo horiz_centre_prop, vert_centre_prop,
                horiz_size_prop, vert_size_prop,
                horiz_pri_phase_prop, vert_pri_phase_prop,
                horiz_sec_phase_prop, vert_sec_phase_prop,
                decay_prop, freq_prop, coup_prop;

struct Gadget horiz_centre_gad =
{
&parm_ok_gad,
50, 25, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&horiz_centre_image, NL,
&horiz_centre_val_txt, NL,
(APTR)&horiz_centre_prop,
4, NL
};

struct Gadget vert_centre_gad =
{
&horiz_centre_gad,
240, 25, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&vert_centre_image, NL,
&vert_centre_val_txt, NL,
(APTR)&vert_centre_prop,
5, NL
};

struct Gadget horiz_size_gad =
{
&vert_centre_gad,
50, 39, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&horiz_size_image, NL,
&horiz_size_val_txt, NL,
(APTR)&horiz_size_prop,
6, NL
};

struct Gadget vert_size_gad =
{
&horiz_size_gad,
240, 39, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&vert_size_image, NL,
&vert_size_val_txt, NL,
(APTR)&vert_size_prop,
7, NL
};

struct Gadget horiz_pri_phase_gad =
{
&vert_size_gad,
50, 53, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&horiz_pri_phase_image, NL,
&horiz_pri_phase_val_txt, NL,
(APTR)&horiz_pri_phase_prop,
8, NL
};

struct Gadget vert_pri_phase_gad =
{
&horiz_pri_phase_gad,
240, 53, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&vert_pri_phase_image, NL,
&vert_pri_phase_val_txt, NL,
(APTR)&vert_pri_phase_prop,
9, NL
};

struct Gadget horiz_sec_phase_gad =
{
&vert_pri_phase_gad,
50, 67, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&horiz_sec_phase_image, NL,
&horiz_sec_phase_val_txt, NL,
(APTR)&horiz_sec_phase_prop,
10, NL
};

struct Gadget vert_sec_phase_gad =
{
&horiz_sec_phase_gad,
240, 67, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&vert_sec_phase_image, NL,
&vert_sec_phase_val_txt, NL,
(APTR)&vert_sec_phase_prop,
11, NL
};

struct Gadget decay_gad =
{
&vert_sec_phase_gad,
50, 82, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&decay_image, NL,
&decay_val_txt, NL,
(APTR)&decay_prop,
12, NL
};

struct Gadget freq_gad =
{
&decay_gad,
50, 96, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&freq_image, NL,
&freq_val_txt, NL,
(APTR)&freq_prop,
13, NL
};

struct Gadget coup_gad =
{
&freq_gad,
50, 110, 110, 11,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY, PROPGADGET | REQGADGET,
(APTR)&coup_image, NL,
&coup_val_txt, NL,
(APTR)&coup_prop,
14, NL
};

#define PMX 400    /* Parameter requester size */
#define PMY 124

struct Requester parms_req;

SHORT parms_border_coords[] = {0,0, PMX-1,0, PMX-1,PMY-1, 0,PMY-1, 0,0};

struct Border parms_border =
{
0,0,
1,0,JAM1,
5,&parms_border_coords[0],
NL
};

/************************************************************************
                     Initialise Parameter Sliders
************************************************************************/ 
void init_parm_sliders(cW)
struct Window *cW;
{
horiz_centre_prop.HorizPot = (int) (65535*hc)/XMAX;
vert_centre_prop.HorizPot  = (int) (65535*vc)/YMAX;
horiz_size_prop.HorizPot   = (int) (65535*hs)/XMAX;
vert_size_prop.HorizPot    = (int) (65535*vs)/YMAX;
horiz_pri_phase_prop.HorizPot = (int) (65535*hpp)/TWOPI;
vert_pri_phase_prop.HorizPot  = (int) (65535*vpp)/TWOPI;
horiz_sec_phase_prop.HorizPot = (int) (65535*hsp)/TWOPI;
vert_sec_phase_prop.HorizPot  = (int) (65535*vsp)/TWOPI;
decay_prop.HorizPot = (int) (65535*di)/DMAX;
freq_prop.HorizPot  = (int) (65535*sf)/FMAX;
coup_prop.HorizPot  = (int) (65535*cp)/CMAX;

sprintf(horiz_centre_str,"%5d\0",hc);
sprintf(vert_centre_str,"%-5d\0",vc);
sprintf(horiz_size_str,"%5d\0",hs);
sprintf(vert_size_str,"%-5d\0",vs);
sprintf(horiz_pri_phase_str,"%5.3f\0",hpp);
sprintf(vert_pri_phase_str,"%5.3f\0",vpp);
sprintf(horiz_sec_phase_str,"%5.3f\0",hsp);
sprintf(vert_sec_phase_str,"%5.3f\0",vsp);
sprintf(decay_str,"%5.3f\0",di*TWOPI/DT);
sprintf(freq_str,"%5.3f\0",sf);
sprintf(coup_str,"%5.3f\0",cp);

RefreshGadgets(&coup_gad,cW,NL);
}
/************************************************************************
                          Parameter Function
************************************************************************/ 
parms(cW)
struct Window *cW;
{
FAST struct IntuiMessage *message;
FAST int class,item;
int hcb,vcb,hsb,vsb;                       /* backup parameters */
int hct,vct,hst,vst;                       /* temporary values  */
double hppb,vppb,hspb,vspb,dib,sfb,cpb;    /* backup parameters */
double hppt,vppt,hspt,vspt,dit,sft,cpt;    /* temporary values  */
BOOL loop;

hct = hcb = hc; vct = vcb = vc; hst = hsb = hs; vst = vsb = vs;
hppt = hppb = hpp; vppt = vppb = vpp;
hspt = hspb = hsp; vspt = vspb = vsp;
dit = dib = di; sft = sfb = sf; cpt = cpb = cp;

horiz_centre_prop.Flags    = vert_centre_prop.Flags = 
horiz_size_prop.Flags      = vert_size_prop.Flags = 
horiz_pri_phase_prop.Flags = vert_pri_phase_prop.Flags = 
horiz_sec_phase_prop.Flags = vert_sec_phase_prop.Flags = 
decay_prop.Flags           = freq_prop.Flags = 
coup_prop.Flags            = FREEHORIZ | AUTOKNOB;

horiz_centre_prop.HorizBody    = vert_centre_prop.HorizBody = 
horiz_size_prop.HorizBody      = vert_size_prop.HorizBody = 
horiz_pri_phase_prop.HorizBody = vert_pri_phase_prop.HorizBody = 
horiz_sec_phase_prop.HorizBody = vert_sec_phase_prop.HorizBody = 
decay_prop.HorizBody           = freq_prop.HorizBody = 
coup_prop.HorizBody            = 0x1000;

ModifyIDCMP(cW,GADGETUP | GADGETDOWN | REQCLEAR | MOUSEMOVE);

         /* Remember to set REPORTMOUSE flag in window structure
                                           for MOUSEMOVE to work */
InitRequester(&parms_req);
parms_req.LeftEdge = 120;
parms_req.TopEdge = 25;
parms_req.Width = PMX;
parms_req.Height = PMY;
parms_req.ReqGadget = &coup_gad;
parms_req.ReqText = &coup_txt;
parms_req.BackFill = 3;
parms_req.ReqBorder = &parms_border;
Request(&parms_req,cW);

init_parm_sliders(cW);

loop=TRUE;

while (loop)
      {
      Wait(1 << cW->UserPort->mp_SigBit); /* Be good and go to sleep till
                                             Intuition sends a message */

      while (message=(struct IntuiMessage *) GetMsg(cW->UserPort))
         {
         class = message->Class;   /* Process all outstanding Messages */
         ReplyMsg(message);

         if (class == REQCLEAR) loop = FALSE;           /* OK Selected */

         if ((class == GADGETDOWN) || (class == GADGETUP))
            item = ((struct Gadget *) message->IAddress)->GadgetID;
                             /* Get GadgetID for sliders on GADGETDOWN
                                             and Booleans on GADGETDUP */

         /* MOUSEMOVE events are not acknowledged specifically, but by
            generating a message cause the following code for cases >3
            to update the sliders */
         }
      switch (item)
             {
             case 1 : hc = hcb; vc = vcb; hs = hsb; vs = vsb;
                      hpp = hppb; vpp = vppb; hsp = hspb; vsp = vspb;
                      di = dib; sf = sfb; cp = cpb;
                      init_parm_sliders(cW);             /* Cancel */
                      item = 0;
                      break;
             case 2 : hc = hcd; vc = vcd; hs = hsd; vs = vsd;
                      hpp = hppd; vpp = vppd; hsp = hspd; vsp = vspd;
                      di = did; sf = sfd; cp = cpd;
                      init_parm_sliders(cW);            /* Default */
                      item = 0;
                      break;
             case 4 : /* Update slider only if the value has changed */
                      hct = (int) (XMAX*horiz_centre_prop.HorizPot)/65535;
                      if (hct != hc)
                         {
                         hc = hct;
                         sprintf(horiz_centre_str,"%5d\0",hc);
                         RefreshGList(&horiz_centre_gad,cW,&parms_req,1);
                         } 
                      break;
             case 5 : vct = (int) (YMAX*vert_centre_prop.HorizPot)/65535;
                      if (vct != vc)
                         {
                         vc = vct;
                         sprintf(vert_centre_str,"%-5d\0",vc);
                         RefreshGList(&vert_centre_gad,cW,&parms_req,1);
                         }
                      break;
             case 6 : hst = (int) (XMAX*horiz_size_prop.HorizPot)/65535;
                      if (hst != hs)
                         {
                         hs = hst; 
                         sprintf(horiz_size_str,"%5d\0",hs);
                         RefreshGList(&horiz_size_gad,cW,&parms_req,1);
                         }
                      break;
             case 7 : vst = (int) (YMAX*vert_size_prop.HorizPot)/65535;
                      if (vst != vs)
                         {
                         vs = vst;
                         sprintf(vert_size_str,"%-5d\0",vs);
                         RefreshGList(&vert_size_gad,cW,&parms_req,1);
                         }
                      break;
             case 8 : hppt = (double)
                             (TWOPI*horiz_pri_phase_prop.HorizPot)/65535;
                      if (hppt != hpp)
                         {
                         hpp = hppt;
                         sprintf(horiz_pri_phase_str,"%5.3f\0",hpp);
                         RefreshGList(&horiz_pri_phase_gad,cW,&parms_req,1);
                         }
                      break;
             case 9 : vppt = (double)
                             (TWOPI*vert_pri_phase_prop.HorizPot)/65535;
                      if (vppt != vpp)
                         {
                         vpp = vppt;
                         sprintf(vert_pri_phase_str,"%5.3f\0",vpp);
                         RefreshGList(&vert_pri_phase_gad,cW,&parms_req,1);
                         }
                      break;
             case 10 : hspt = (double)
                              (TWOPI*horiz_sec_phase_prop.HorizPot)/65535;
                       if (hspt != hsp)
                          {
                          hsp = hspt;
                          sprintf(horiz_sec_phase_str,"%5.3f\0",hsp);
                          RefreshGList(&horiz_sec_phase_gad,cW,&parms_req,1);
                          }
                       break;
             case 11 : vspt = (double)
                              (TWOPI*vert_sec_phase_prop.HorizPot)/65535;
                       if (vspt != vsp)
                          {
                          vsp = vspt;
                          sprintf(vert_sec_phase_str,"%5.3f\0",vsp);
                          RefreshGList(&vert_sec_phase_gad,cW,&parms_req,1);
                          }
                       break;
             case 12 : dit = (double) (DMAX*decay_prop.HorizPot)/65535;
                       if (dit != di)
                          {
                          di = dit;
                          sprintf(decay_str,"%5.3f\0",di*TWOPI/DT);
                          RefreshGList(&decay_gad,cW,&parms_req,1);
                          }
                       break;
             case 13 : sft = (double) (FMAX*freq_prop.HorizPot)/65535;
                       if (sft != sf)
                          {
                          sf = sft;
                          sprintf(freq_str,"%5.3f\0",sf);
                          RefreshGList(&freq_gad,cW,&parms_req,1);
                          }
                       break;
             case 14 : cpt = (double) (CMAX*coup_prop.HorizPot)/65535;
                       if (cpt != cp)
                          {
                          cp = cpt;
                          sprintf(coup_str,"%5.3f\0",cp);
                          RefreshGList(&coup_gad,cW,&parms_req,1);
                          }
             }
      }
ModifyIDCMP(cW,MENUPICK | ACTIVEWINDOW | REQCLEAR | INTUITICKS);
return(TRUE);
}
