unit dpointscontrol;

{$MODE FPC}
{$MODESWITCH AUTODEREF}
{$MODESWITCH DEFAULTPARAMETERS}
{$MODESWITCH OUT}
{$MODESWITCH RESULT}

interface

uses
  dvector2f,
  dvector4f,
  deng;

type
TPointsControl = object
public
  Points: array of TVec2f;
  Radius: Single;
  Normal, Active: TVec4f;
  Focus: LongInt;
  Dragging: Boolean;
  Drag: TVec2f;
  procedure Init(Template: Boolean = False);
  procedure Done;
  procedure Render(const Cursor: TVec2f);
  procedure Update;
  function InjectClickDown(const Cursor: TVec2f): Boolean;
  function InjectClickUp(const Cursor: TVec2f): Boolean;
  function InjectCursorMove(const Cursor: TVec2f): Boolean;
end;

implementation

procedure TPointsControl.Init(Template: Boolean = False);
begin
  Points := nil;
  if Template then begin
    SetLength(Points, 6);
    Points[0] := Vec2f( 50, 100);
    Points[1] := Vec2f(200, 50);
    Points[2] := Vec2f(120, 150);
    Points[3] := Vec2f(210, 130);
    Points[4] := Vec2f(150, 200);
    Points[5] := Vec2f(200, 250);
  end;
  Radius := 5;
  Normal := Vec4f(0.00, 0.50, 0.00, 1.00);
  Active := Vec4f(0.00, 0.75, 0.00, 1.00);
  Dragging := False;
end;

procedure TPointsControl.Done;
begin
end;

procedure TPointsControl.Render(const Cursor: TVec2f);
var
  I: LongInt;
begin
  for I := 0 to High(Points) do begin
    if Dist2f(Cursor, Points[I]) < Radius then begin
      Eng.Draw.Color(Active);
    end else
      Eng.Draw.Color(Normal);
    Eng.Draw.CircleFilled(Points[I], Radius);
  end;
end;

procedure TPointsControl.Update;
begin
end;

function TPointsControl.InjectClickDown(const Cursor: TVec2f): Boolean;
var
  I: LongInt;
begin
  for I := 0 to High(Points) do begin
    if Dist2f(Cursor, Points[I]) < Radius then begin
      Focus := I;
      Dragging := True;
      Drag := Vec2f(Points[I].X - Cursor.X, Points[I].Y - Cursor.Y);
      Exit(True);
    end;
  end;
  Exit(False);
end;

function TPointsControl.InjectClickUp(const Cursor: TVec2f): Boolean;
begin
  if Dragging then begin
    Points[Focus] := Cursor;
  end;
  Result := Dragging;
  Dragging := False;
end;

function TPointsControl.InjectCursorMove(const Cursor: TVec2f): Boolean;
begin
  if Dragging then
    Points[Focus] := Drag + Cursor;
  Exit(Dragging);
end;

end.
