unit Plotu;
{
  (C) 2000 - 2001 Jindrich Jindrich, Pavel Pisa, PiKRON Ltd.

  Originators of the CHROMuLAN project:

  Jindrich Jindrich - http://www.jindrich.com
                      http://orgchem.natur.cuni.cz/Chromulan/
                      software developer, project coordinator
  Pavel Pisa        - http://cmp.felk.cvut.cz/~pisa
                      embeded software developer
  PiKRON Ltd.       - http://www.pikron.com
                      project initiator, sponsor, instrument developer

  The CHROMuLAN project is distributed under the GNU General Public Licence.
  See file COPYING for details.

  Originators reserve the right to use and publish sources
  under different conditions too. If third party contributors
  do not accept this condition, they can delete this statement
  and only GNU license will apply.
}

interface
uses
  Classes, SysUtils, Graphics,
  UlanType;

const
{plot commands:}
  pcMoveTo = 1;
  pcLineTo = 2;
  pcTextOut = 3;
  pcClearTextOut = 4;

type
  TPlotCommand = word;

{  PPlotRecord = ^TPlotRecord;}
  TPlotRecord = class(TObject)
    pc: TPlotCommand;
    X: TScreenX;
    Y: TScreenY;
    Info: string;
    constructor Create(APC: TPlotCommand; AX: TScreenX; AY: TScreenY; const AInfo: string);
    destructor Destroy; override;
  end;

{  PPlotting = ^TPlotting;}
  TPlotting = class(TList){of Pplotcommandrecs}
    CurRec:integer;
    CurX:TScreenX;
    CurY:TScreenY;
    {FCharHeight:TScreenY;
    FCharWidth:TScreenX; }
    FCanvas: TCanvas;
    constructor Create(ACanvas: TCanvas; ALimit: integer);
      { ACanvas just for finding out TextWidth, TextHeight. No output
        is going to FCanvas using Move.., Line..., .. commands.
        Only by method CopyToCanvas. }
    function Reset: boolean;
    function Read(var APlotRecord: TPlotRecord): boolean;

    {adding records:}
    function ClearTextOut(AX: TScreenX; AY: TScreenY; AText: string): boolean;
    function MoveTo(AX: TScreenX; AY: TScreenY): boolean;
    function LineTo(AX: TScreenX; AY: TScreenY): boolean;
    function TextOut(AX: TScreenX; AY: TScreenY; AText: string): boolean;
    function GetX: TScreenX;
    function GetY: TScreenY;
    function TextWidth(AText: string): TScreenX;
    function TextHeight(AText: string): TScreenY;
    function Line(X1: TScreenX; Y1: TScreenY; X2: TScreenX; Y2: TScreenY): boolean;
    function SetLineStyle(a, b, c: integer): boolean;
      {?see dos graph}
    function Rectangle(X1: TScreenX; Y1: TScreenY; X2: TScreenX; Y2: TScreenY): boolean;
    procedure Clear; override;{tlist reset, then free all}
    {procedure SetCharHeight(AHeight: TScreenY);
    procedure SetCharWidth(AWidth: TScreenX);}
    property Canvas: TCanvas read FCanvas write FCanvas;
  end;

implementation

constructor TPlotRecord.Create(APC:TPlotCommand; AX:TScreenX; AY:TScreenY; const AInfo: string);
begin
  inherited Create;
  pc := APC;
  X := AX;
  Y := AY;
  Info := AInfo;
end;

destructor TPlotRecord.Destroy;
begin
{  if (pc in [pcTextOut, pcClearTextOut]) then
   FreePString(@PString(Info));}
  inherited Destroy;
end;


constructor TPlotting.Create(ACanvas: TCanvas; ALimit:integer);
begin
  inherited Create;
  Capacity := ALimit;
  CurRec := 0;
  CurX := 0;
  CurY := 0;
  FCanvas := ACanvas;
{  FCharHeight := 12;
  FCharWidth := 8;}
end;

function TPlotting.Reset:boolean;
begin
  Reset := false;
  CurRec := 0;
  if Count = 0 then
    exit;
  Reset := true;
end;

function TPlotting.Read(var APlotRecord:TPlotRecord):boolean;
begin
  Read := false;
  if CurRec >= Count then
    exit;
  APlotRecord := Items[CurRec];
  case APlotRecord.pc of
    pcLineTo, pcMoveTo: begin
      CurX := APlotRecord.X;
      CurY := APlotRecord.Y;
    end;
  end;
  inc(CurRec);
  Read := true;
end;

function TPlotting.ClearTextOut(AX:TScreenX; AY:TScreenY ;AText:string):boolean;
begin
  ClearTextOut := TextOut(AX, AY, AText);
end;

function TPlotting.MoveTo(AX:TScreenX;AY:TScreenY):boolean;
begin
  MoveTo := true;
  Add(TPlotRecord.Create(pcMoveTo, AX, AY, ''));
  CurX := AX;
  CurY := AY;
end;

function TPlotting.LineTo(AX:TScreenX;AY:TScreenY):boolean;
begin
  LineTo := true;
  Add(TPlotRecord.Create(pcLineTo, AX, AY, ''));
  CurX := AX;
  CurY := AY;
end;

function TPlotting.TextOut(AX:TScreenX; AY:TScreenY; AText:string):boolean;

begin
  TextOut := true;
  Add(TPlotRecord.Create(pcTextOut, AX, AY, AText));
  {CurX := AX;
  CurY := AY;}
end;

function TPlotting.GetX:TScreenX;
begin
  GetX := CurX;
end;

function TPlotting.GetY:TScreenY;
begin
  GetY := CurY;
end;

function TPlotting.TextWidth(AText:String):TScreenX;
begin
  TextWidth := FCanvas.TextWidth(AText);{length(AText) * FCharWidth;}
end;

function TPlotting.TextHeight(AText:string):TScreenY;
begin
  TextHeight := FCanvas.TextHeight(AText);{FCharHeight;}
end;

function TPlotting.Line(X1:TScreenX; Y1:TScreenY; X2:TScreenX; Y2:TScreenY):boolean;
begin
  Line := false;
  if not MoveTo(X1, Y1) then
    exit;
  if not LineTo(X2, Y2) then
    exit;
  Line := true;
end;

function TPlotting.Rectangle(X1:TScreenX; Y1:TScreenY; X2:TScreenX; Y2:TScreenY):boolean;
begin
  Rectangle := false;
  if not MoveTo(X1, Y1) then
    exit;
  if not LineTo(X1, Y2) then
    exit;
  if not LineTo(X2, Y2) then
    exit;
  if not LineTo(X2, Y1) then
    exit;
  if not LineTo(X1, Y1) then
    exit;
  Rectangle := true;
end;

function TPlotting.SetLineStyle(a,b,c:integer):boolean;{?see dos graph}
begin
  SetLineStyle := false;
end;

procedure TPlotting.Clear;{free all}
var i:integer;
begin
  Reset;
  if Count > 0 then begin
    for i := 0 to Count - 1 do
      TObject(Items[i]).Free;
  end;
  inherited Clear;
{  FreeAll;}
end;

{procedure TPlotting.SetCharHeight(AHeight:TScreenY);
begin
  FCharHeight := AHeight;
end;

procedure TPlotting.SetCharWidth(AWidth:TScreenX);
begin
  FCharWidth := AWidth;
end;
 }
end.
