(*********************************************************************)
(*                                                                   *)
(* Module TestPlots Copyright © 1994 by Computer Inspirations        *)
(*                                                                   *)
(*********************************************************************)

MODULE TestPlots;


(* Amiga-specific operating system module *)
FROM DOSProcess    IMPORT Delay;

(* General Modula-2 modules *)
FROM MathLib0      IMPORT exp, sin, pi, cos, log;
FROM RandomNumbers IMPORT Random;

(* Custom module developed to support PlotLibrary *)
FROM PlotLibrary   IMPORT PlotType, PlotKindType, LineType,
                          PositionType, InitPlot,
                          PlotFx, LabelMinMax, DonePlot,
                          InformationBox, SetPlotColour,
                          SetColourMap, SetPlotOffset,
                          SetLabelRoutine, SetTextColour,
                          CenterLabelX, CenterLabelY,
                          SetPlotLimits, ClearPlot,
                          SetScatterPlot, SetZeroLine,
                          SetPlotScale, InitOffsetPlot;


CONST
  LGrey   = 0;
  Black   = 1;
  White   = 2;
  Blue    = 3;
  Green   = 4;
  Red     = 5;
  Pink    = 6;
  Grey    = 7;
  Colours = 8;
  Time    = 500;   (* 10 seconds *)

VAR
  Plot  : PlotType;                (* plot variable *)
  Title : ARRAY [0..80] OF CHAR;   (* screen title  *)


PROCEDURE DefineColours;
BEGIN
  SetColourMap(Plot, LGrey, 10, 10, 10);
  SetColourMap(Plot, Black,  0,  0,  0);
  SetColourMap(Plot, White, 15, 15, 15);
  SetColourMap(Plot, Blue,   0,  0, 15);
  SetColourMap(Plot, Green,  0, 15,  0);
  SetColourMap(Plot, Red,   15,  0,  0);
  SetColourMap(Plot, Pink,  15,  3,  7);
  SetColourMap(Plot, Grey,   8,  8,  8);
END DefineColours;


PROCEDURE DampSine(x : REAL) : REAL;
VAR
  xpi : REAL;
BEGIN
  xpi := x * pi;
  RETURN exp(-xpi/10.0) * sin(xpi);
END DampSine;


PROCEDURE Cubic(x : REAL) : REAL;
BEGIN
  RETURN ((2.0 * x - 7.0) * x - 7.0) * x + 5.0;
END Cubic;


PROCEDURE RandomSine(x : REAL) : REAL;
VAR
  xpi, y : REAL;
BEGIN
  xpi := x * pi;
  y := sin(xpi) / 1000.0;
  SetPlotColour(Plot, Random(5) + 1);
  RETURN FLOAT(Random(1000)) * y;
END RandomSine;


PROCEDURE AmpModulated(x : REAL) : REAL;
VAR
  xpi : REAL;
BEGIN
  xpi := x * pi;
  RETURN sin(xpi) * sin(10.0 * xpi);
END AmpModulated;


PROCEDURE Response(x : REAL) : REAL;
VAR
  xi, y : REAL;
BEGIN
  xi := 2.0 * pi * (log(x) - 1.0) / 8.0;
  y  := 30.0 * sin(xi);
  RETURN y * y;
END Response;


PROCEDURE StockPrices(x : REAL) : REAL;
BEGIN
  RETURN 0.3 * (10.0 - x) * (FLOAT(Random(10)) - 5.0);
END StockPrices;


PROCEDURE RawProfit(x : REAL) : REAL;
VAR
  Gx : INTEGER;
BEGIN
  Gx := TRUNC(x);
  CASE Gx OF
    1  : RETURN 5.3   |
    2  : RETURN 7.5   |
    3  : RETURN 3.6   |
    4  : RETURN -1.5  |
    5  : RETURN -6.3  |
    6  : RETURN 2.4   |
    7  : RETURN 3.8   |
    8  : RETURN 4.8   |
    9  : RETURN 3.9   |
    10 : RETURN 3.3   |
    11 : RETURN -3.6  |
    12 : RETURN 4.8   |
    ELSE RETURN 0.0;
  END;
END RawProfit;


PROCEDURE ProfitValues2(x : REAL) : REAL;
VAR
  Gx : INTEGER;
  y  : REAL;
BEGIN
  Gx := TRUNC(x);
  CASE Gx OF
    1  : y := 6.2   |
    2  : y := 8.0   |
    3  : y := 4.3   |
    4  : y := -2.1  |
    5  : y := -8.0  |
    6  : y := 3.1   |
    7  : y := 4.3   |
    8  : y := 5.2   |
    9  : y := 4.2   |
    10 : y := 5.6   |
    11 : y := -3.9  |
    12 : y := 6.0   |
    ELSE y := 0.0;
  END;
  IF y > 0.0 THEN
    SetPlotColour(Plot, Grey);  (* positive y's *)
  ELSE
    SetPlotColour(Plot, Pink);  (* negative y's *)
  END;
  RETURN y;
END ProfitValues2;


PROCEDURE ProfitValues(x : REAL) : REAL;
VAR
  y  : REAL;
BEGIN
  y := RawProfit(x);
  IF y > 0.0 THEN
    SetPlotColour(Plot, Black);  (* positive y's *)
  ELSE
    SetPlotColour(Plot, Red);    (* negative y's *)
  END;
  RETURN y;
END ProfitValues;


PROCEDURE BarLabels(index   : INTEGER;         (* x div *)
                    VAR str : ARRAY OF CHAR);  (* label *)
BEGIN
  CASE index OF
    1  : str := "Jan" |
    2  : str := "Feb" |
    3  : str := "Mar" |
    4  : str := "Apr" |
    5  : str := "May" |
    6  : str := "Jun" |
    7  : str := "Jul" |
    8  : str := "Aug" |
    9  : str := "Sep" |
    10 : str := "Oct" |
    11 : str := "Nov" |
    12 : str := "Dec" |
    ELSE str := "";
  END;
END BarLabels;


PROCEDURE NoLabels(index   : INTEGER;         (* x div *)
                   VAR str : ARRAY OF CHAR);  (* label *)
BEGIN
  str := "";
END NoLabels;


PROCEDURE LinePlot;
VAR
  LineArray : ARRAY [1..3] OF LineType;
  Plot2 : PlotType;
BEGIN
  Title := "Line-Style Plot";
  IF InitPlot(Plot, Title, Line, 0.0, 13.0, -10.0, 10.0,
              640, 400, 13, 10, 5, 5, 0, 0, Colours) THEN
    (* define the colours *)
    DefineColours;

    (* draw the plot 1 *)
    SetLabelRoutine(Plot, BarLabels);
    PlotFx(Plot, StockPrices);

    (* label the axis *)
    SetTextColour(Plot, Blue);
    CenterLabelX(Plot, "Month", 395);
    CenterLabelY(Plot, "Profit (Thousands $)", 15);

    (* draw the information box *)
    LineArray[1] := "Albrania Stock Market";
    LineArray[2] := "";
    LineArray[3] := "January 1892 - December 1892";
    SetTextColour(Plot, White);
    InformationBox(Plot,UpperRight,LineArray,Black,Blue);

    (* delay and exit *)
    Delay(Time);
    DonePlot(Plot);
  END;
END LinePlot;


PROCEDURE ScientificPlot;
VAR
  LineArray : ARRAY [1..6] OF LineType;
BEGIN
  Title := "Normal Plot";
  IF InitPlot(Plot, Title, Normal, 0.0, 7.0, -1.0, 1.0,
              640, 400, 7, 10, 5, 5, 0, 1, Colours) THEN
    (* define the colours *)
    DefineColours;

    (* draw the plot *)
    PlotFx(Plot, DampSine);

    (* label minima and maxima *)
    LabelMinMax(Plot, DampSine);

    (* draw the information box *)
    LineArray[1] := "Dampened sine wave plot";
    LineArray[2] := "";
    LineArray[3] := "y=exp(-x·pi÷10)·sin(x·pi)";
    LineArray[4] := "";
    LineArray[5] := "Procedures imported from";
    LineArray[6] := "the PlotLibrary module";
    SetTextColour(Plot, White);
    InformationBox(Plot,LowerRight,LineArray,Black,Blue);

    (* delay and exit *)
    Delay(Time);
    DonePlot(Plot);
  END;
END ScientificPlot;


PROCEDURE ScaledPlot;
VAR
  LineArray : ARRAY [1..8] OF LineType;
BEGIN
  Title := "Scaled Plot";
  IF InitPlot(Plot, Title, Normal, -6.0, 11.0,
              -100.0, 100.0, 640, 400, 7, 10, 5, 5, 1, 0,
              Colours) THEN
    (* define the colours *)
    DefineColours;

    (* draw the plot *)
    PlotFx(Plot, Cubic);

    (* 2 x magnification on y-axis *)
    SetPlotScale(Plot, 1.0, 2.0);
    SetPlotColour(Plot, Red);
    PlotFx(Plot, Cubic);

    (* 2 x magnification on x-axis *)
    SetPlotScale(Plot, 2.0, 1.0);
    SetPlotColour(Plot, Blue);
    PlotFx(Plot, Cubic);

    (* 2 x magnification on both axes *)
    SetPlotScale(Plot, 2.0, 2.0);
    SetPlotColour(Plot, Green);
    PlotFx(Plot, Cubic);

    (* draw the information box *)
    LineArray[1] := "Cubic Function plot";
    LineArray[2] := "";
    LineArray[3] := "y = 2x³ - 7x² - 7x + 5";
    LineArray[4] := "";
    LineArray[5] := " Black - Unscaled";
    LineArray[6] := " Red   - 2 x Y Mag";
    LineArray[7] := " Blue  - 2 x X Mag";
    LineArray[8] := " Green - 2 x X & Y Mag";
    SetTextColour(Plot, White);
    InformationBox(Plot,UpperLeft,LineArray,Black,Blue);

    (* delay and exit *)
    Delay(Time);
    DonePlot(Plot);
  END;
END ScaledPlot;


PROCEDURE QuadPlot;
VAR
  LineArray : ARRAY [1..9] OF LineType;
  OK        : BOOLEAN;
  Cnt       : INTEGER;
  Plots     : ARRAY [1..4] OF PlotType;
BEGIN
  (* create the initial plot canvas *)
  Title := "Four Plots on a Screen";
  IF InitPlot(Plot, Title, Normal, 0.0, 7.0, -1.0, 1.0,
              640, 400, 7, 10, 5, 5, 0, 1, Colours) THEN
    (* define the colours *)
    DefineColours;

    (* set up the first plot in upper left of screen *)
    OK := InitOffsetPlot(Plots[1], Normal, 0.0, 7.0,
                         -1.0, 1.0, 320, 200, 3, 5, 0, 0,
                         1, 1, 0, 0, Plot);
    PlotFx(Plots[1], AmpModulated);

    (* set up the second plot below the first *)
    OK := InitOffsetPlot(Plots[2], Normal, 0.0, 7.0,
                         -1.0, 1.0, 320, 200, 3, 5, 0, 0,
                         1, 1, 0, 200, Plot);
    SetPlotScale(Plots[2], 6.0, 1.0);
    SetPlotColour(Plots[2], Red);
    PlotFx(Plots[2], AmpModulated);

    (* set up the third plot at the top right *)
    OK := InitOffsetPlot(Plots[3], Normal, -6.0, 11.0,
                         -100.0, 100.0, 320, 200,
                         3, 5, 0, 0, 1, 0, 320, 0, Plot);
    PlotFx(Plots[3], Cubic);

    (* set up the final plot at the bottom right *)
    OK := InitOffsetPlot(Plots[4], Normal, -6.0, 11.0,
                         -100.0, 100.0, 320, 200,
                         3, 5, 0, 0, 1, 0, 320, 200, Plot);
    SetPlotScale(Plots[4], 2.0, 2.0);
    SetPlotColour(Plots[4], Red);
    PlotFx(Plots[4], Cubic);

    (* delay and exit *)
    Delay(Time);
    FOR Cnt := 1 TO 4 DO
      DonePlot(Plots[Cnt]);
    END;
    DonePlot(Plot);
  END;
END QuadPlot;


PROCEDURE ShadowPlot;
VAR
  LineArray : ARRAY [1..6] OF LineType;
  Cnt : CARDINAL;
BEGIN
  Title := "Shadow Plot";
  IF InitPlot(Plot, Title, Normal, 0.0, 7.0, -1.0, 1.0,
              640, 400, 7, 10, 5, 5, 0, 1, Colours) THEN
    (* define the colours *)
    DefineColours;

    (* draw a thick shadow plot *)
    SetPlotColour(Plot, Black);
    SetZeroLine(Plot, FALSE);       (* no zero line *)
    FOR Cnt := 0 TO 2 DO
      SetPlotOffset(Plot, Cnt, -1);
      PlotFx(Plot, AmpModulated);
    END;

    (* draw the plot *)
    SetPlotOffset(Plot, 0, 0);
    SetZeroLine(Plot, TRUE);        (* zero is drawn *)
    SetPlotColour(Plot, Red);
    PlotFx(Plot, AmpModulated);

    (* label the axis *)
    SetTextColour(Plot, Blue);
    CenterLabelX(Plot, "Modulation Time", 395);
    CenterLabelY(Plot, "Modulated Amplitude", 15);

    (* delay and exit *)
    Delay(Time);
    DonePlot(Plot);
  END;
END ShadowPlot;


PROCEDURE ResponsePlot;
VAR
  LineArray : ARRAY [1..1] OF LineType;
BEGIN
  Title := "Response Plot";
  IF InitPlot(Plot, Title, Log, 10.0, 100000.0, 0.1, 1000.0,
              640, 400, 4, 4, 10, 10, 0, 1, Colours) THEN
    (* define the colours *)
    DefineColours;

    (* draw the plot *)
    PlotFx(Plot, Response);

    (* label the axis *)
    SetTextColour(Plot, Blue);
    CenterLabelX(Plot, "Frequency (Hz)", 395);
    CenterLabelY(Plot, "Power Output (W)", 15);

    (* draw the information box *)
    LineArray[1] := "Stereo Response Plot";
    SetTextColour(Plot, White);
    InformationBox(Plot,LowerMiddle,LineArray,Black,Blue);

    (* delay and exit *)
    Delay(Time);
    DonePlot(Plot);
  END;
END ResponsePlot;


PROCEDURE BarChart;
VAR
  LineArray : ARRAY [1..7] OF LineType;
BEGIN
  Title := "Bar Chart Plot";
  IF InitPlot(Plot, Title, Bar, 0.0, 13.0, -10.0, 10.0,
              640, 400, 13, 10, 0, 0, 0, 0, Colours) THEN
    (* define the colours *)
    DefineColours;

    (* draw the plot 1 *)
    SetLabelRoutine(Plot, BarLabels);
    SetPlotOffset(Plot, -4, 0);
    PlotFx(Plot, ProfitValues);

    (* draw the plot 2 *)
    SetPlotOffset(Plot, 4, 0);
    PlotFx(Plot, ProfitValues2);

    (* label minima and maxima *)
    LabelMinMax(Plot, ProfitValues2);

    (* label the axis *)
    SetTextColour(Plot, Blue);
    CenterLabelX(Plot, "Month", 395);
    CenterLabelY(Plot, "Profit (Thousands $)", 15);

    (* draw the information box *)
    LineArray[1] := "XYZ Corporation";
    LineArray[2] := "Monthly Profit Bar Graph";
    LineArray[3] := "January 1991 - December 1992";
    LineArray[4] := "   Black = Profit 1991";
    LineArray[5] := "   Grey  = Profit 1992";
    LineArray[6] := "   Red   = Loss 1991";
    LineArray[7] := "   Pink  = Loss 1992";
    SetTextColour(Plot, White);
    InformationBox(Plot,LowerRight,LineArray,Black,Blue);

    (* delay and exit *)
    Delay(Time);
    DonePlot(Plot);
  END;
END BarChart;


PROCEDURE ScatterPlot;
VAR
  LineArray : ARRAY [1..7] OF LineType;
BEGIN
  Title := "Scatter Plot";
  IF InitPlot(Plot, Title, Normal, 0.0, 7.0, -1.0, 1.0,
              640, 400, 7, 10, 0, 0, 0, 1, Colours) THEN
    (* define the colours *)
    DefineColours;

    (* set to a scatter plot *)
    SetScatterPlot(Plot);

    (* draw the plot *)
    PlotFx(Plot, RandomSine);

    (* label the axis *)
    SetTextColour(Plot, Blue);
    CenterLabelX(Plot, "Random Sinusoid", 395);
    CenterLabelY(Plot, "Amplitude", 15);

    (* delay and exit *)
    Delay(Time);
    DonePlot(Plot);
  END;
END ScatterPlot;


BEGIN
  ScientificPlot;
  ResponsePlot;
  LinePlot;
  BarChart;
  ScatterPlot;
  ShadowPlot;
  ScaledPlot;
  QuadPlot;
END TestPlots.