unit fwTypes;

{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}

interface

uses Math;

type
  TfwCEColor       = Cardinal;

  TfwFloat         = Single;

  PCERect          = ^TCERect;
  TCERect          = record
    X                : Integer;
    Y                : Integer;
    Width            : Integer;
    Height           : Integer;
  end;

function CERectCreate(aX : Integer = 0; aY : Integer = 0; aWidth : Integer = 0; aHeight : Integer = 0) : TCERect;
function CERectIsEmpty(const aRect : TCERect) : Boolean;
function CERectIntersect(const aRect1, aRect2 : TCERect; var aRect : TCERect) : Boolean; overload;
function CERectIntersect(const aRect1, aRect2 : TCERect) : Boolean; overload;
function CERectPtInRect(const aRect : TCERect; aPtX, aPtY : Integer) : Boolean;

implementation

function CERectCreate(aX : Integer = 0; aY : Integer = 0; aWidth : Integer = 0; aHeight : Integer = 0) : TCERect;
begin
  Result.X      := aX;
  Result.Y      := aY;
  Result.Width  := aWidth;
  Result.Height := aHeight;
end;

function CERectIsEmpty(const aRect : TCERect) : Boolean;
begin
  with aRect do begin
    Result := (X = 0) and(Y = 0) and (Width = 0) and (Height = 0);
  end;
end;

function CERectIntersect(const aRect1, aRect2 : TCERect; var aRect : TCERect) : Boolean;
var
  x1               : Integer;
  y1               : Integer;
  x2               : Integer;
  y2               : Integer;
begin
  x1 := Max(aRect1.X, aRect2.X);
  y1 := Max(aRect1.Y, aRect2.Y);
  x2 := Min(aRect1.X + aRect1.Width, aRect2.X + aRect2.Width);
  y2 := Min(aRect1.Y + aRect1.Height, aRect2.Y + aRect2.Height);
  if ((x2 - x1) > 0) and ((y2 - y1) > 0) then begin
    aRect.X      := x1;
    aRect.Y      := y1;
    aRect.Width  := Abs(x2 - x1);
    aRect.Height := Abs(y2 - y1);
    Result := True;
  end else begin
    Result := False;
  end;
end;

function CERectIntersect(const aRect1, aRect2 : TCERect) : Boolean;
var
  x1               : Integer;
  y1               : Integer;
  x2               : Integer;
  y2               : Integer;
begin
  x1 := Max(aRect1.X, aRect2.X);
  y1 := Max(aRect1.Y, aRect2.Y);
  x2 := Min(aRect1.X + aRect1.Width, aRect2.X + aRect2.Width);
  y2 := Min(aRect1.Y + aRect1.Height, aRect2.Y + aRect2.Height);
  if ((x2 - x1) > 0) and ((y2 - y1) > 0) then begin
    Result := True;
  end else begin
    Result := False;
  end;
end;

function CERectPtInRect(const aRect : TCERect; aPtX, aPtY : Integer) : Boolean;
begin
  Result := False;
  with aRect do begin
    if ((aPtX >= X) and (aPtY >= Y) and (aPtX < (X + Width)) and (aPtY < (Y + Height)))
    then begin
      Result := True;
    end;
  end;
end;

end.
