/************************************************************
 *
 *  funktzeich.c
 *
 *  zeigt eingegebene Funktionen auf dem Bildschirm mit nach
 *  Wunsch beschrifteten Achsen in gewünschtem Bereich.
 *
 *  Peter Gober, 15-May-88
 *               12-Oct-88  Überarbeitung für 3 Funktionen
 *
 ************************************************************/


#include <exec/types.h>
#include <intuition/intuition.h>
#include <functions.h>

double atof();

/*
 *  definiert in intuistr.c:
 */

extern struct NewWindow mynewwindow;
extern struct Requester myrequester;
extern UBYTE func1buf[], func2buf[], func3buf[];
extern UBYTE minxbuf[], maxxbuf[], minybuf[], maxybuf[];
extern UBYTE dxbuf[], dybuf[];

/*
 *  Globals (für cleanup() zu 0L initialisiert)
 */

struct IntuitionBase *IntuitionBase = 0L;
struct GfxBase *GfxBase = 0L;

struct Window *mywindow = 0L;

main()
{
   struct IntuiMessage *intuimsg;
   ULONG intuiclass;

   /*
    *  Libraries öffnen
    */

   if ( (IntuitionBase = (struct IntuitionBase *)
      OpenLibrary("intuition.library", 0L)) == NULL)
   {
      cleanup();
      exit(0);
   }
   if ( (GfxBase = (struct GfxBase *)
      OpenLibrary("graphics.library", 0L)) == NULL)
   {
      cleanup();
      exit(0);
   }

   /*
    *  Fenster öffnen
    */

   if ( (mywindow = (struct Window *) OpenWindow(&mynewwindow))
      == NULL)
   {
      cleanup();
      exit(0);
   }

   /*
    *  Zeige Requester zum ersten Mal, zeichne!
    */

   request();
   redraw();

   for (;;)
   {
      /*
       *  Aktiviere DMRequester
       */

      if (SetDMRequest(mywindow, &myrequester) == FALSE)
      {
         cleanup();
         exit(0);
      }

      /*
       *  Warte, bis Benutzer etwas tut
       */

      Wait(1L << mywindow->UserPort->mp_SigBit);

      /*
       *  Nimm DMRequester weg
       */

      while (!ClearDMRequest(mywindow, &myrequester))
      {
         /*
          *  Requester ist noch im Bild, warte bis er weg ist
          */

         Wait(1L << mywindow->UserPort->mp_SigBit);
      }

      /*
       *  Guck nach, was uns der IDCMP beschert hat
       */

      while (intuimsg = (struct IntuiMessage *) GetMsg(mywindow->UserPort))
      {
         intuiclass = intuimsg->Class;
         ReplyMsg(intuimsg);
         switch(intuiclass)
         {
            case CLOSEWINDOW:
               cleanup();
               exit(0);
            case REQCLEAR:
            case NEWSIZE:
               /*
                *  Neu zeichnen
                */

               redraw();
               break;
         }
      }
   }
}

/*
 *  redraw() ruft die Routinen zur Zeichnung der Achsen und der Funktionen
 *  selbst auf
 */

redraw()
{
   int error;

   do
   {
      SetRast(mywindow->RPort, 0L);     /* Schirm löschen */

      SetAPen(mywindow->RPort, 1L);     /* Stiftfarbe 1 (weiß) */
      axisdraw(mywindow->RPort, (int) mywindow->GZZWidth,
         (int) mywindow->GZZHeight,
         atof(minxbuf), atof(maxxbuf),
         atof(minybuf), atof(maxybuf),
         atof(dxbuf), atof(dybuf));
                                        /* Achsen zeichnen */
      error = 0;

      if (*func1buf != '\0')
      {
         SetAPen(mywindow->RPort, 1L);
         error = funcdraw(func1buf, mywindow->RPort,
                    (int) mywindow->GZZWidth, (int) mywindow->GZZHeight,
                    atof(minxbuf), atof(maxxbuf),
                    atof(minybuf), atof(maxybuf));
      }

      if (!error && *func2buf != '\0')
      {
         SetAPen(mywindow->RPort, 2L);
         error = funcdraw(func2buf, mywindow->RPort,
                    (int) mywindow->GZZWidth, (int) mywindow->GZZHeight,
                    atof(minxbuf), atof(maxxbuf),
                    atof(minybuf), atof(maxybuf));
      }

      if (!error && *func3buf != '\0')
      {
         SetAPen(mywindow->RPort, 3L);
         error = funcdraw(func3buf, mywindow->RPort,
                    (int) mywindow->GZZWidth, (int) mywindow->GZZHeight,
                    atof(minxbuf), atof(maxxbuf),
                    atof(minybuf), atof(maxybuf));
      }

      if (error)
      {
         /*
          *  Fehler in Formel/Bereich, "beepe" und zeige Requester nochmal
          */

         DisplayBeep(0L);
         request();
      }

   }
   while(error);

   return(0);
}

/*
 *  request() zeigt Requester, wartet bis er beantwortet ist
 */

request()
{
   ModifyIDCMP(mywindow, REQCLEAR);     /* Nur diese Messages zulassen */

   if (Request(&myrequester,mywindow) == FALSE)
   {
      cleanup();
      exit(0);
   }
   Wait (1L << mywindow->UserPort->mp_SigBit);
   GetMsg(mywindow->UserPort);

   ModifyIDCMP(mywindow, CLOSEWINDOW | REQCLEAR | NEWSIZE);

   return(0);
}

cleanup()
{
   if (mywindow) CloseWindow(mywindow);
   if (GfxBase) CloseLibrary(GfxBase);
   if (IntuitionBase) CloseLibrary(IntuitionBase);

   return(0);
}
