unit tpPegBlock;

interface

uses
  Classes, tpPeg, Math;

type
  TtpPegBlock = class
  private
    FPegs: TList;

    FBeginPeg: TtpPegNode;
    FEndPeg: TtpPegNode;
    FBeginNum: Double;
    FEndNum: Double;

    FTotalPrice: Double;
    function GetPeg(AIndex: Integer): TtpPegNode;
    function GetPegCount: Integer;
    function GetLength: Double;
  public
    constructor Create(APeg: TtpPegNode);
    destructor Destroy; override;

    procedure AddPeg(APeg: TtpPegNode);
    function IsRelaPeg(APeg: TtpPegNode; ARange: Double): Boolean;

    property BeginNum: Double read FBeginNum;
    property EndNum: Double read FEndNum;

    property BeginPeg: TtpPegNode read FBeginPeg;
    property EndPeg: TtpPegNode read FEndPeg;

    property Length: Double read GetLength;
    property TotalPrice: Double read FTotalPrice;

    property PegCount: Integer read GetPegCount;
    property Peg[AIndex: Integer]: TtpPegNode read GetPeg;
  end;

  TtpPegBlockList = class
  private
    FBlocks: TList;
    function GetBlockCount: Integer;
    function GetPegBlock(AIndex: Integer): TtpPegBlock;
  public
    constructor Create;
    destructor Destroy; override;

    procedure Clear;

    property BlockCount: Integer read GetBlockCount;
    property PegBlock[AIndex: Integer]: TtpPegBlock read GetPegBlock;
  end;

implementation

uses
  ZhAPI;

{ TtpPegBlock }

procedure TtpPegBlock.AddPeg(APeg: TtpPegNode);
begin
  FPegs.Add(APeg);
  if APeg.BeginPegNum < FBeginNum then
  begin
    FBeginNum := APeg.BeginPegNum;
    FBeginPeg := APeg
  end;
  if APeg.EndPegNum > FEndNum then
  begin
    FEndNum := APeg.EndPegNum;
    FEndPeg := APeg;
  end;
  FTotalPrice := FTotalPrice + APeg.RelaNode.TotalPrice;
end;

constructor TtpPegBlock.Create(APeg: TtpPegNode);
begin
  FPegs := TList.Create;
  FPegs.Add(APeg);
  FBeginNum := APeg.BeginPegNum;
  FEndNum := APeg.EndPegNum;
  FBeginPeg := APeg;
  FEndPeg := APeg;
  FTotalPrice := APeg.RelaNode.TotalPrice;
end;

destructor TtpPegBlock.Destroy;
begin
  FPegs.Free;
  inherited;
end;

function TtpPegBlock.GetLength: Double;
begin
  Result := FEndNum - FBeginNum;
end;

function TtpPegBlock.GetPeg(AIndex: Integer): TtpPegNode;
begin
  Result := TtpPegNode(FPegs.Items[AIndex]);
end;

function TtpPegBlock.GetPegCount: Integer;
begin
  Result := FPegs.Count;
end;

function TtpPegBlock.IsRelaPeg(APeg: TtpPegNode; ARange: Double): Boolean;
var
  fRela: Double;
begin
  if APeg.PegLength > 0 then
  begin
    fRela := 0;
    if (APeg.BeginPegNum <= FBeginNum) then
    begin
      if (APeg.EndPegNum > FBeginNum) and (APeg.EndPegNum < FEndNum) then
        fRela := APeg.EndPegNum - FBeginNum
      else if APeg.EndPegNum >= FEndNum then
        fRela := Length;
    end
    else if (APeg.BeginPegNum > FBeginNum) and (APeg.BeginPegNum < FEndNum) then
    begin
      if (APeg.EndPegNum > FBeginNum) and (APeg.EndPegNum < FEndNum) then
        fRela := APeg.EndPegNum - APeg.BeginPegNum
      else if (APeg.EndPegNum >= FEndNum) then
        fRela := FEndNum - APeg.BeginPegNum;
    end
    else
      fRela := 0;
    Result := (fRela <> 0) and (fRela >= Min(Min(Length, APeg.PegLength), ARange));
  end
  else if APeg.PegLength = 0 then
    Result := (APeg.BeginPegNum > FBeginNum) and (APeg.BeginPegNum < FEndNum)
  else
    Result := False;
end;

{ TtpPegBlockList }

procedure TtpPegBlockList.Clear;
begin
  ClearObjects(FBlocks);
  FBlocks.Free;
end;

constructor TtpPegBlockList.Create;
begin
  FBlocks := TList.Create;
end;

destructor TtpPegBlockList.Destroy;
begin
  Clear;
  FBlocks.Free;
  inherited;
end;

function TtpPegBlockList.GetBlockCount: Integer;
begin
  Result := FBlocks.Count;
end;

function TtpPegBlockList.GetPegBlock(AIndex: Integer): TtpPegBlock;
begin
  Result := TtpPegBlock(FBlocks.Items[AIndex]);
end;

end.
