#include <stdio.h>
#include <exec/types.h>
#include "struct.h"
#include "plot.h"
#include "howto1.h"
#include "howto2.h"

extern char *gets();
extern char *getwrd();
extern struct Window *FrontWindow;
extern struct Screen *screen;

extern struct NewWindow NewFrontWindow;
extern struct RastPort *p;
extern struct ViewPort *vp;

extern int debug;

#define LINEPLOT 0
#define POINTPLOT 1
#define BOTHPLOT 2

USHORT PlotType;
USHORT PointType;
USHORT Colour;
USHORT PlotPrefs;
USHORT SkipPlot;
USHORT StopPlot;


#define DEFAULT 0
#define CHOOSE 1
#define STOP 0
#define GO 1

extern int QuitFrontFlag;
short firstcall = TRUE;


void GetHowTo(Pict)
struct Pict *Pict;
{
   short i,j;
   struct Plot *Plot;
   struct IntuiMessage  *p_message;         /* pointer to message */
   void ProcHowMes(), ProcCustMes(), GadMXSel();
   SHORT border[] ={
                   336, 76,
                   400, 76,
                   400,140,
                   336,140,
                   336, 76
                 };

   QuitFrontFlag=GO;

   if (firstcall) {
      firstcall = FALSE;
      /*** ESTABLISH DEFAULTS ***/
      PlotType=LINEPLOT;
      PointType=6;
      Pict->Grid = FALSE;
      Pict->ShowErr = Pict->ErrBar;
      Pict->Tics->NX = Pict->Tics->NY = 5;
   }

   PlotPrefs=DEFAULT;
   Colour=DEFAULT;
   Gadget45.GadgetRender = (APTR)&Colour1;
   Gadget18.Flags=(GADGHIMAGE+GADGIMAGE);


   if (Pict->Grid == TRUE) Gadget15.Flags=(GADGHIMAGE+SELECTED+GADGIMAGE);
   else Gadget15.Flags=(GADGHIMAGE+GADGIMAGE);

   if (PlotType == POINTPLOT) Gadget16.GadgetRender = (APTR)&Image6b;
   else if (PlotType == BOTHPLOT) Gadget16.GadgetRender = (APTR)&Image6c;
   else Gadget16.GadgetRender = (APTR)&Image6a;

   if (Pict->ErrBar==FALSE) Gadget14.Flags=(GADGHIMAGE+SELECTED+GADGDISABLED+GADGIMAGE);
   else if (Pict->ShowErr==FALSE) Gadget14.Flags=(GADGHIMAGE+SELECTED+GADGIMAGE);
   else Gadget14.Flags=(GADGHIMAGE+GADGIMAGE);

   NewFrontWindow.Title = title0;
   NewFrontWindow.FirstGadget = &Gadget13;
   NewFrontWindow.Screen = screen;
   if (!(FrontWindow = (struct Window *)OpenWindow(&NewFrontWindow)))
     {
         ErrorAlert(0);
         CloseScreen(screen);
         sexit(FALSE);
     }
   p = FrontWindow->RPort;
   PrintIText(p,&IText11,0,0);

  while (QuitFrontFlag !=STOP)
    {
       Wait(1l<<FrontWindow->UserPort->mp_SigBit);        /* wait for a message */
       while (p_message = (struct IntuiMessage *)GetMsg(FrontWindow->UserPort))
         ProcHowMes(p_message,Pict);
     }

   CloseWindow(FrontWindow);
   if (Gadget17SInfo.LongInt<1)     /* Number of X Ticks */
      {
         Gadget17SInfo.LongInt=1;
         strcpy(Gadget17SIBuff,"1");
      }
   if (Gadget17SInfo.LongInt>20)
      {
         Gadget17SInfo.LongInt=20;
         strcpy(Gadget17SIBuff,"20");
      }
   if (Gadget17aSInfo.LongInt<1)          /* Number of Y Ticks */
      {
         Gadget17aSInfo.LongInt=1;
         strcpy(Gadget17aSIBuff,"1");
      }
   if (Gadget17aSInfo.LongInt>20)
      {
         Gadget17aSInfo.LongInt=20;
         strcpy(Gadget17aSIBuff,"20");
      }
   Pict->Tics->NX = Gadget17SInfo.LongInt;
   Pict->Tics->NY = Gadget17aSInfo.LongInt;

   if (PlotPrefs==DEFAULT) {
      Plot = Pict->Plot;
      i = 0;
      while (Plot) {
         Plot->Enabled = TRUE;
         Plot->Color = PLOTCOLORBASE + i;
         Plot->PointType = PointType;
         if (PointType>1) PointType = PointType-1;
         else PointType = 6;
         if (PlotType==LINEPLOT) Plot->PointSize = 0;
         else Plot->PointSize = DEFAULT_POINT_SIZE;
         if (PlotType==POINTPLOT) Plot->Lines=FALSE;
         else Plot->Lines=TRUE;
         if (Plot->Continued) {
            Plot->NextPlot->Color = Plot->Color;
            Plot->NextPlot->PointSize = Plot->PointSize;
            Plot->NextPlot->Lines = Plot->Lines;
            Plot->NextPlot->Enabled = Plot->Enabled;
         }
         Plot = Plot->NextPlot;
         i++;
      }
   }

   else
    {            /* GET USER'S INSTRUCTIONS FOR EACH PLOT */
      Plot = Pict->Plot;

      for(i=0;i<Pict->NPlt;i++) {
        j=min(19,i);
        IText16.IText=SetText[j];
        NewFrontWindow.Title = title1;
        NewFrontWindow.FirstGadget = &Gadget43;
        NewFrontWindow.Screen = screen;
        if (!(FrontWindow = (struct Window *)OpenWindow(&NewFrontWindow)))
         {
            ErrorAlert(0);
            CloseScreen(screen);
            sexit(FALSE);
         }
        p = FrontWindow->RPort;
        PrintIText(p,&IText16,0,0);
        Move(p,336,76);
        PolyDraw(p,5,border);
        switch (PointType) {
                  case 6:  GadMXSel(FrontWindow,&GadgPoint6,&GadgPoint5,&GadgPoint4,&GadgPoint3,&GadgPoint2,&GadgPoint1);
                           break;
                  case 5:  GadMXSel(FrontWindow,&GadgPoint5,&GadgPoint6,&GadgPoint4,&GadgPoint3,&GadgPoint2,&GadgPoint1);
                           break;
                  case 4:  GadMXSel(FrontWindow,&GadgPoint4,&GadgPoint5,&GadgPoint6,&GadgPoint3,&GadgPoint2,&GadgPoint1);
                           break;
                  case 3:  GadMXSel(FrontWindow,&GadgPoint3,&GadgPoint5,&GadgPoint4,&GadgPoint6,&GadgPoint2,&GadgPoint1);
                           break;
                  case 2:  GadMXSel(FrontWindow,&GadgPoint2,&GadgPoint5,&GadgPoint4,&GadgPoint3,&GadgPoint6,&GadgPoint1);
                           break;
                  case 1:  GadMXSel(FrontWindow,&GadgPoint1,&GadgPoint5,&GadgPoint4,&GadgPoint3,&GadgPoint2,&GadgPoint6);
                           break;
                  default: PointType=6;
                           GadMXSel(FrontWindow,&GadgPoint6,&GadgPoint5,&GadgPoint4,&GadgPoint3,&GadgPoint2,&GadgPoint1);
                           break;
                  }

        QuitFrontFlag=GO;
        SkipPlot=FALSE;
        StopPlot=FALSE;

        while (QuitFrontFlag !=STOP)
         {
            Wait(1l<<FrontWindow->UserPort->mp_SigBit);        /* wait for a message */
            while (p_message = (struct IntuiMessage *)GetMsg(FrontWindow->UserPort))
              ProcCustMes(p_message,Pict);

         }

         if (SkipPlot) { Plot->Enabled = FALSE; SkipPlot=FALSE; }
         else if (StopPlot)
           {
             StopPlot=FALSE;
             i=Pict->NPlt;
           }
         else
           {
              Plot->Enabled = TRUE;
              Plot->PointType=PointType;

              if (Colour==DEFAULT) Plot->Color = PLOTCOLORBASE + i;
              else Plot->Color = Colour2.PlaneOnOff;

              if (PlotType==LINEPLOT) Plot->PointSize = 0;
              else Plot->PointSize = Gadget46SInfo.LongInt;

              if (PlotType==POINTPLOT) Plot->Lines = FALSE;
              else Plot->Lines = TRUE;
           }

         if (Plot->Continued) {
            Plot->NextPlot->Color = Plot->Color;
            Plot->NextPlot->PointSize = Plot->PointSize;
            Plot->NextPlot->Lines = Plot->Lines;
            Plot->NextPlot->Enabled = Plot->Enabled;
         }
         Plot = Plot->NextPlot;
         CloseWindow(FrontWindow);
      }
   }
}


void ProcHowMes(p_message,Pict)
struct IntuiMessage *p_message;
struct Pict *Pict;

{
ULONG MesClass;        /*     Fields for storing      */
USHORT MesCode;        /*     intuimessage data       */
APTR Pointer;          /*                             */
void HandleHowEvent();

   MesClass = p_message->Class;             /* Store values */
   MesCode = p_message->Code;
   Pointer = p_message->IAddress;
   ReplyMsg(p_message);                     /* Reply to message */
   HandleHowEvent(MesClass,MesCode,Pointer,Pict);
}

void ProcCustMes(p_message,Pict)
struct IntuiMessage *p_message;
struct Pict *Pict;

{
ULONG MesClass;        /*     Fields for storing      */
USHORT MesCode;        /*     intuimessage data       */
APTR Pointer;          /*                             */
void HandleCustEvent();

   MesClass = p_message->Class;             /* Store values */
   MesCode = p_message->Code;
   Pointer = p_message->IAddress;
   ReplyMsg(p_message);                     /* Reply to message */
   HandleCustEvent(MesClass,MesCode,Pointer,Pict);
}


void HandleHowEvent(MesClass,MesCode,Pointer,Pict)
struct Pict *Pict;

ULONG MesClass;        /*     Fields for storing      */
USHORT MesCode;        /*     intuimessage data       */
APTR Pointer;          /*                             */
{

  if ( MesClass == GADGETDOWN)
    {

      if (Pointer == (APTR)&Gadget13)  QuitFrontFlag = STOP;
      if (Pointer == (APTR)&Gadget14)
          {
            if (Gadget14.Flags & SELECTED) Pict->ShowErr = FALSE;
            else  Pict->ShowErr = Pict->ErrBar;
          }
      if (Pointer == (APTR)&Gadget15)
          {
            if (Pict->Grid==TRUE) Pict->Grid=FALSE;
            else Pict->Grid=TRUE;
          }
      if (Pointer == (APTR)&Gadget16)
          {
            RemoveGadget(FrontWindow,&Gadget16);
            if (PlotType==LINEPLOT)
              {
                  PlotType=POINTPLOT;
                  Gadget16.GadgetRender = (APTR)&Image6b;
              }
            else if (PlotType==POINTPLOT)

              {
                  PlotType=BOTHPLOT;
                  Gadget16.GadgetRender = (APTR)&Image6c;
              }
            else
              {
                  PlotType=LINEPLOT;
                  Gadget16.GadgetRender = (APTR)&Image6a;

              }
            AddGadget(FrontWindow,&Gadget16,-1L);
            RefreshGadgets(&Gadget16,FrontWindow,NULL);
          }
      if (Pointer == (APTR)&Gadget18)
          {
            if (PlotPrefs==DEFAULT) PlotPrefs=CHOOSE;
            else PlotPrefs=DEFAULT;
          }
      else ;
    }
  if ( MesClass == RAWKEY)
    {
      if (MesCode ==196)  /* RETURN key RELEASED */
         {
            QuitFrontFlag = STOP;
         }
      else ;
    }
  else ;
}

void HandleCustEvent(MesClass,MesCode,Pointer,Pict)
struct Pict *Pict;

ULONG MesClass;        /*     Fields for storing      */
USHORT MesCode;        /*     intuimessage data       */
APTR Pointer;          /*                             */
{

   if ( MesClass == GADGETDOWN)
     {
        if (Pointer == (APTR)&Gadget45)
          {
            RemoveGadget(FrontWindow,&Gadget45);
            if (Gadget45.GadgetRender == (APTR)&Colour1)
              {
                Colour=CHOOSE;
                Colour2.PlaneOnOff = 0x4;
                Gadget45.GadgetRender = (APTR)&Colour2;
              }
            else if (Colour2.PlaneOnOff==0xD)
              {
                Colour=DEFAULT;
                Colour2.PlaneOnOff=0x4;
                Gadget45.GadgetRender = (APTR)&Colour1;
              }
            else Colour2.PlaneOnOff++;
            AddGadget(FrontWindow,&Gadget45,-1L);
            RefreshGadgets(&Gadget45,FrontWindow,NULL);
          }
        else if (Pointer == (APTR)&Gadget47)
          {
            RemoveGadget(FrontWindow,&Gadget47);
            if (PlotType==LINEPLOT)
              {
                  PlotType=POINTPLOT;
                  Gadget47.GadgetRender = (APTR)&Image6b;
              }
            else if (PlotType==POINTPLOT)

              {
                  PlotType=BOTHPLOT;
                  Gadget47.GadgetRender = (APTR)&Image6c;
              }
            else
              {
                  PlotType=LINEPLOT;
                  Gadget47.GadgetRender = (APTR)&Image6a;
              }
            AddGadget(FrontWindow,&Gadget47,-1L);
            RefreshGadgets(&Gadget47,FrontWindow,NULL);
          }
        else if (Pointer == (APTR)&GadgPoint6)
          {
              GadMXSel(FrontWindow,&GadgPoint6,&GadgPoint5,&GadgPoint4,&GadgPoint3,&GadgPoint2,&GadgPoint1);
              PointType=6;
          }
        else if (Pointer == (APTR)&GadgPoint5)
          {
              GadMXSel(FrontWindow,&GadgPoint5,&GadgPoint6,&GadgPoint4,&GadgPoint3,&GadgPoint2,&GadgPoint1);
              PointType=5;
          }
        else if (Pointer == (APTR)&GadgPoint4)
          {
              GadMXSel(FrontWindow,&GadgPoint4,&GadgPoint5,&GadgPoint6,&GadgPoint3,&GadgPoint2,&GadgPoint1);
              PointType=4;
          }
        else if (Pointer == (APTR)&GadgPoint3)
          {
              GadMXSel(FrontWindow,&GadgPoint3,&GadgPoint5,&GadgPoint4,&GadgPoint6,&GadgPoint2,&GadgPoint1);
              PointType=3;
          }
        else if (Pointer == (APTR)&GadgPoint2)
          {
              GadMXSel(FrontWindow,&GadgPoint2,&GadgPoint5,&GadgPoint4,&GadgPoint3,&GadgPoint6,&GadgPoint1);
              PointType=2;
          }
        else if (Pointer == (APTR)&GadgPoint1)
          {
              GadMXSel(FrontWindow,&GadgPoint1,&GadgPoint5,&GadgPoint4,&GadgPoint3,&GadgPoint2,&GadgPoint6);
              PointType=1;
          }
        else if (Pointer == (APTR)&GadgetSkip)
         {
            QuitFrontFlag = STOP;
            SkipPlot=TRUE;
         }
        else if (Pointer == (APTR)&GadgetStop)
         {
            QuitFrontFlag = STOP;
            StopPlot=TRUE;
         }

        else if (Pointer == (APTR)&Gadget43) QuitFrontFlag = STOP;
        else ;
     }
   if ( MesClass == RAWKEY)
     {
      if (MesCode ==196)  /* RETURN key RELEASED */
         {
             QuitFrontFlag = STOP;
         }
      else ;
     }
   else ;
}

/**
*
*   This routine selects gad1 and deselects the previously selected one.
*   Maximum number of gadgets to be mutually excluded is six, obviously.
*   Extension to more gadgets is obvious, too. This routine assumes that
*   only one gadget is selected at a time.
*
**/

void GadMXSel(win,gad1,gad2,gad3,gad4,gad5,gad6)
struct Window *win;
struct Gadget *gad1,*gad2,*gad3,*gad4,*gad5,*gad6;
{
void GadMXSD();
static struct Gadget *gadprev;

   gadprev = NULL;
   if (gad1 != NULL)
      if (gad1->Flags & SELECTED) return;
   if (gad2 != NULL)
      if (gad2->Flags & SELECTED) gadprev = gad2;
   if (gad3 != NULL)
      if (gad3->Flags & SELECTED) gadprev = gad3;
   if (gad4 != NULL)
      if (gad4->Flags & SELECTED) gadprev = gad4;
   if (gad5 != NULL)
      if (gad5->Flags & SELECTED) gadprev = gad5;
   if (gad6 != NULL)
      if (gad6->Flags & SELECTED) gadprev = gad6;

   GadMXSD(win,gad1,gadprev);

   return;
}

/**
*
*   This routine selects gad1 and deselects gad2.
*   Notice, that this version removes gadgets from the gadget list and adds
*   them to the end. If you're sensitive to the location of the gadgets
*   in the gadgetlist, you have to use: gadloc = RemoveGadget... and
*   AddGadget(...,...,(long) gadloc), where gadloc is a USHORT. Then you
*   have to refresh all gadgets to make sure the two you changed get
*   refreshed.
*
**/

void GadMXSD(win,gad1,gad2)
struct Window *win;
struct Gadget *gad1,*gad2;
{
/*
*   First select gad2 (yes!) and refresh.
*/
   if (gad2 != NULL) {
      RemoveGadget(win,gad2);
      gad2->Flags |= SELECTED;
      AddGadget(win,gad2,-1L);
   }

   if (gad2 != NULL) RefreshGadgets(gad2,win,NULL);
/*
*   Now select gad1 and deselect gad2 and refresh.
*/
   if (gad1 != NULL) {
      RemoveGadget(win,gad1);
      gad1->Flags |= SELECTED;
      AddGadget(win,gad1,-1L);
   }

   if (gad2 != NULL) {
      RemoveGadget(win,gad2);
      gad2->Flags &= ~SELECTED;
      AddGadget(win,gad2,-1L);
   }

   if (gad1 != NULL) RefreshGadgets(gad1,win,NULL);

   return;
}






