unit cuWindows;

interface

uses
  Windows, Classes, SysUtils,
  //
  untTypes;

type
  TLineWindow = class;

  { TWindowList }

  TWindowList = class(TComponent)
  private
    function GetItem(Index: Integer): TLineWindow;
    function GetCount: Integer;
  public
    constructor CreateDirect(AOwner: TComponent; Y, X, VH, VW, WH, WW: Integer);
    procedure Clear;
    property Count: Integer read GetCount;
    property Items[Index: Integer]: TLineWindow read GetItem; default;
  end;

  { TLineWindow }

  TLineWindow = class(TComponent)
  private
    FHeight: Integer;
    FWidth: Integer;
    FPorts: TList;
    function Get_Caption: string;
    function Get_Index: Integer;
  public
    constructor CreateDirect(AOwner: TComponent; Y, X, VH, VW, WH, WW: Integer);
    destructor Destroy; override;
    procedure AddViewPort(Y, X, VH, VW: Integer);
    procedure ClearViewPorts;
    function ViewPortsBounds: TBounds; 
    property Caption: string read Get_Caption;
    property Index: Integer read Get_Index;
    property Height: Integer read FHeight;
    property Width: Integer read FWidth;
  end;

implementation

{ TWindowList }

constructor TWindowList.CreateDirect(AOwner: TComponent;
 Y, X, VH, VW, WH, WW: Integer);
begin
  inherited Create(AOwner);
  TLineWindow.CreateDirect(Self, Y, X, VH, VW, WH, WW);
end;

function TWindowList.GetItem(Index: Integer): TLineWindow;
begin
  Result := Components[Index] as TLineWindow;
end;

function TWindowList.GetCount: Integer;
begin
  Result := ComponentCount;
end;

procedure TWindowList.Clear;
begin
  DestroyComponents;
end;

{ TLineWindow }

procedure TLineWindow.AddViewPort(Y, X, VH, VW: Integer);
var
  B: ^TBounds;
begin
  New(B);
  B.Left := X;
  B.Top := Y;
  B.Width := VW;
  B.Height := VH;
  if FPorts = nil then FPorts := TList.Create;
  FPorts.Add(B);
end;

constructor TLineWindow.CreateDirect(AOwner: TComponent;
  Y, X, VH, VW, WH, WW: Integer);
begin
  inherited Create(AOwner);
  if (VH > 0) and (VW > 0) then
    AddViewPort(Y, X, VH, VW);
  FHeight := WH;
  FWidth := WW;
end;

destructor TLineWindow.Destroy;
begin
  ClearViewPorts;
  inherited Destroy
end;

function TLineWindow.Get_Caption: string;
begin
  Result := Format(' %d', [Index]);
end;

function TLineWindow.Get_Index: Integer;
begin
  Result := ComponentIndex;
end;

procedure TLineWindow.ClearViewPorts;
var
  B: ^TBounds;
  I: Integer;
begin
  if FPorts <> nil then
  begin
    for I := 0 to FPorts.Count - 1 do
    begin
      B := FPorts[I];
      Dispose(B);
    end;
    FPorts.Free;
    FPorts := nil;
  end;
end;

function TLineWindow.ViewPortsBounds: TBounds;
var
  I: Integer;
  R1, R2: TRect;
begin
  Result := MakeBounds(0, 0, 0, 0);
  if FPorts = nil then Exit;
  BoundsToRect(TBounds(FPorts[0]^), R1);
  for I := 1 to FPorts.Count - 1 do
  begin
    BoundsToRect(TBounds(FPorts[I]^), R2);
    if R1.Left > R2.Left then R1.Left := R2.Left;
    if R1.Top > R2.Top then R1.Top := R2.Top;
    if R1.Right < R2.Right then R1.Right := R2.Right;
    if R1.Bottom < R2.Bottom then R1.Bottom := R2.Bottom;
  end;
  RectToBounds(R1, Result);
end;

end.
