unit u_lingraph;

// Purpose: Handles Time Display of data

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Graphics;

const nPoints = 500;
type tTrace = array[0..nPoints + 1] of integer;
var
  Trace0, Trace1, Trace2, Trace3, Trace4, Trace5, Trace6: Ttrace;
  Marker: integer;

procedure LinGraph_Init;
procedure LinGraph_DispTrace (Trace: tTrace; Color: integer);
procedure LinGraph_Refresh;
procedure LinGraph_Update;
procedure LinGraph_Update_FP;
procedure LinGraph_SaveImageToFile (ToFileName: string);
procedure LinGraph_TextUpperLeft (Txt: shortstring);

implementation

uses u_main, u_messages, u_calc, u_timestrings;

procedure LinGraph_TextUpperLeft (Txt: shortstring);
begin
  with FrmMain.LinGraph.Canvas do
  begin
    //SetTextStyle (ScriptFont, HorizDir, 10);
    font.color:= clWhite;
    font.size:= 10;
    Textout (2, 2, Txt);
  end;
end;

procedure LinGraph_SaveImageToFile (ToFileName: string);
var
  RectangleFrom, RectangleTo: tRect;
  myPNG: TportableNetworkGraphic; // .PNG file
begin
  with FrmMain.LinGraph.Canvas do
  begin
    //rectangleFrom:=rect (left, bottom, right, top);
    RectangleFrom:= rect (0, 0, 510, 330);
    //rectangleTo:=rect (0,0,right-left+1,top-bottom+1);
    RectangleTo:= rect (0, 0, 510+1, 330+1);
    myPNG:= tPortableNetworkGraphic.create;
    myPNG.width:= 510+1;
    myPNG.height:= 330+1;
    myPNG.canvas.copyRect (rectangleTo, FrmMain.LinGraph.Canvas, RectangleFrom);
    myPNG.SaveToFile (toFileName + '.PNG');
    myPNG.free;
  end;
end;

procedure LinGraph_Init;
var
  I, X, Y: integer;
begin
  With FrmMain.LinGraph do
  begin
    Height:= 330;
    Width:= 510;
    With Canvas do
    begin
      Brush.Color:= clBlack;
      Pen.Color:= clWhite;
      AutoReDraw:= true;
      Pen.Style := psSolid;
      Rectangle (0, 0, 510, 330);
    end;
    for I:= 0 to 10 do // 11 vertical lines at 50 pixels distance
    begin
      X:= 5 + I * 50; // 10 divs
      Canvas.Line (X, 5, X, 325);
    end;
    for I:= 0 to 8 do // 9 horizontal lines at 40 pixels distanc
    begin
      Y:= 325 - I * 40;
      Canvas.Line (5, Y, 505, Y);
    end;
    LinGraph_TextUpperLeft (DateTimeStamp);
  end;
end;

procedure LinGraph_DispTrace (Trace: tTrace; Color: integer);
var
  X, Y: integer;
begin
  with FrmMain.LinGraph.Canvas do
  begin
    Pen.Color:= Color;
    Pen.Style:= psSolid;
    for X:= 0 to nPoints do
    begin
      Y:= round (Trace[X]);
      // clip the graph
      if Y < -160 Then Y:= -160;
      if Y > 160 Then Y:= 160;
      if X = 0 then Moveto (X + 5, 165 - Y) else Lineto (X + 5, 165 - Y);
    end;
  end;
end;

procedure LinGraph_Refresh;
begin
  LinGraph_Init;
  if FrmMain.CbxShowTdiff.Checked then LinGraph_DispTrace (Trace1, clYellow);
  if FrmMain.CbxShowAC.Checked then LinGraph_DispTrace (Trace2, clRed);
  if FrmMain.CbxShowARim.Checked then LinGraph_DispTrace (Trace3, clAqua);
  if FrmMain.CbxShowPrecessionAngle.Checked then LinGraph_DispTrace (Trace4, clLime);
  if FrmMain.CbxShowMinorAxis.Checked then LinGraph_DispTrace (Trace5, clFuchsia);
  if FrmMain.CbxShowWidthDrive.Checked then LinGraph_DispTrace (Trace6, clWhite);
end;

procedure LinGraph_Update;
// Updated each halfswing for ca 1000 sec per width of 500 px
var i: integer;
begin
  for i:= 2 to nPoints - 1 do // shift traces 1 pixel left
  begin
    Trace1[i]:= Trace1[i + 1];
    Trace2[i]:= Trace2[i + 1];
    Trace3[i]:= Trace3[i + 1];
    Trace6[i]:= Trace6[i + 1];
  end;
  Trace1[500]:= TPassCenterDiff;                    // scale from mid of graph
  Trace2[500]:= APeakCenter - 165;                  // scale from bottom of graph
  Trace3[500]:= round (AmplitudeFromRim_mm - 165);   // scale from bottom of graph
  Trace5[500]:= round (EllipseShortAxis_mm);
  if UseMinimalDriveWidth then Trace6[500]:= -150;  // scale from bottom of graph
  if UseMaximalDriveWidth then Trace6[500]:= -140;  // scale from bottom of graph
  LinGraph_Refresh;
end;

procedure LinGraph_Update_FP;
// Updated each 12 minutes for 100 hours per width of 500 pixels
var i: integer;
begin
  for i:= 2 to nPoints - 1 do // shift traces 1 pixel left
  begin
    Trace4[i]:= Trace4[i + 1]; // FP angle
    Trace5[i]:= Trace5[i + 1]; // short axis
  end;
  Trace4[500]:= round (PrecessionAngle_Degrees / 180 * 160); // scale for 45 degrees per div
  Trace5[500]:= round (EllipseShortAxis_mm * 4); // scale for 10 mm / div
  LinGraph_Refresh;
end;

begin
// no initialisation code
end.

