/*

  Funktionsplotter in Storm C

*/

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

#include <iostream.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>

#include "fclass.h"

// ******** Zeichenroutine ********

// Windowdimensionen:
#define WW 640
#define WH 190

#pragma break -

void plot(Func *f, double minx, double maxx, double miny, double maxy)
{
  NewWindow mynewwin =
   { 0, 0, WW, WH+10, 2, 1, CLOSEWINDOW,
     ACTIVATE | WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | GIMMEZEROZERO,
     NULL, NULL, " Plot ++ ", NULL, NULL, 100, 50, 640, 200, WBENCHSCREEN};

  struct Window* mywin = OpenWindow(&mynewwin);
  if (!mywin) exit(1);

  RastPort *RP = mywin->RPort;

  double XS = WW / (maxx-minx), YS = WH / (maxy-miny);

  int X0 = int(-XS*minx), Y0 = int(-YS*miny);

  SetAPen(mywin->RPort, 3);
  if (miny < 0 && maxy > 0)
    { // y-Achse zeichnen:
      Move(RP,  0, WH-Y0);
      Draw(RP, WW, WH-Y0);
    }

  if (minx < 0 && maxx > 0)
    { // x-Achse zeichnen:
      Move(RP, X0, 0);
      Draw(RP, X0, WH);
    }

  SetAPen(mywin->RPort, 0);
  Move(mywin->RPort, 0, 0);

  for (int i=0; i<WW; i++)
    { double x = minx+i/XS, y = f->eval(x);
      int yp = int(YS*y+Y0);

      if (yp > -WH && yp < 2*WH) Draw(RP, i, WH-yp);
      SetAPen(RP, 1);
    }

  WaitPort(mywin->UserPort);
  CloseWindow(mywin);
}

#pragma break +

void main()
{
  char input[100], buf[200];

  cout << "\nPlot ++\nGeschrieben in StormC++\n\n";

  cout << "Funktion: f(x) = "; cin.get(input, 100);

  Func *MyExp = Parse(input);

  if (MyExp)
    { double minX, maxX, minY, maxY;

      for(;;)
       { cout << "X-Bereich: von "; cin >> minX;
         cout << "           bis "; cin >> maxX;
         if (minX < maxX) break;
         cout << "Das Minimum muß kleiner als das Maximum sein.\n";
       }

      for(;;)
       { cout << "Y-Bereich: von "; cin >> minY;
         cout << "           bis "; cin >> maxY;
         if (minY < maxY) break;
         cout << "Das Minimum muß kleiner als das Maximum sein.\n";
       }

      cout << "\nFunktion: "; MyExp->print(buf); cout << "\n";

      plot(MyExp, minX, maxX, minY, maxY);

      delete MyExp;
    }
  else
    cout << "Versuch's doch gleich noch mal!\n";

}

