unit tpPeg; interface uses Classes, tpGatherTree, ZhAPI, mPegFilter; type TtpPegNode = class private FRelaNode: TtpGatherTreeNode; FRelaGclNodes: TList; FBeginPeg: string; FEndPeg: string; FBeginPegNum: Double; FEndPegNum: Double; procedure LoadGclNodes(ANode: TtpGatherTreeNode); function GetPeg: string; function GetPegLength: Double; public constructor Create(ANode: TtpGatherTreeNode; APegFilter: TPegFilter); destructor Destroy; override; function IsPegIn(ABeginPegNum, AEndPegNum: Double): Boolean; function IsPegRela(ABeginPegNum, AEndPegNum: Double): Boolean; procedure LoadRelaGclNodes; property RelaNode: TtpGatherTreeNode read FRelaNode; property RelaGclNodes: TList read FRelaGclNodes; property Peg: string read GetPeg; property BeginPeg: string read FBeginPeg; property EndPeg: string read FEndPeg; property BeginPegNum: Double read FBeginPegNum; property EndPegNum: Double read FEndPegNum; property PegLength: Double read GetPegLength; end; TtpPegList = class private FPegNodes: TList; FBeginPegNum: Double; FEndPegNum: Double; FTotalPrice: Double; function GetPeg(AIndex: Integer): TtpPegNode; function GetCount: Integer; function GetBeginPeg: string; function GetEndPeg: string; public constructor Create; destructor Destroy; override; procedure Clear; procedure SortPegs; procedure SaveDebugData(const AFileName: string); procedure AddPegs(APeg: TtpPegNode); procedure LoadRelaGclNodes; function TrialTotalPrice(ABeginPegNum, AEndPegNum: Double): Double; property Count: Integer read GetCount; property Peg[AIndex: Integer]: TtpPegNode read GetPeg; property BeginPegNum: Double read FBeginPegNum; property BeginPeg: string read GetBeginPeg; property EndPegNum: Double read FEndPegNum; property EndPeg: string read GetEndPeg; property TotalPrice: Double read FTotalPrice; end; implementation uses Math, SysUtils, UtilMethods, CacheTree; { TtpPegNode } constructor TtpPegNode.Create(ANode: TtpGatherTreeNode; APegFilter: TPegFilter); begin FRelaNode := ANode; FRelaGclNodes := TList.Create; FBeginPeg := APegFilter.BeginPeg; FBeginPegNum := APegFilter.BeginPegNum; if APegFilter.EndPeg = '' then begin FEndPeg := FBeginPeg; FEndPegNum := FBeginPegNum; end else begin FEndPeg := APegFilter.EndPeg; FEndPegNum := APegFilter.EndPegNum; end; end; destructor TtpPegNode.Destroy; begin FRelaGclNodes.Free; inherited; end; function TtpPegNode.GetPeg: string; begin Result := RelaNode.Name; end; function TtpPegNode.GetPegLength: Double; begin Result := FEndPegNum - FBeginPegNum; end; function TtpPegNode.IsPegIn(ABeginPegNum, AEndPegNum: Double): Boolean; begin Result := (FBeginPegNum >= ABeginPegNum) and (FEndPegNum <= AEndPegNum); end; function TtpPegNode.IsPegRela(ABeginPegNum, AEndPegNum: Double): Boolean; begin Result := ((FBeginPegNum < ABeginPegNum) and (FEndPegNum > ABeginPegNum)) or ((FBeginPegNum < AEndPegNum) and (FEndPegNum > AEndPegNum)); end; procedure TtpPegNode.LoadGclNodes(ANode: TtpGatherTreeNode); var vChild: TtpGatherTreeNode; begin if not Assigned(ANode) then Exit; if Assigned(ANode.FirstChild) then begin vChild := TtpGatherTreeNode(ANode.FirstChild); while Assigned(vChild) do begin LoadGclNodes(vChild); vChild := TtpGatherTreeNode(vChild.NextSibling); end; end else if ANode.B_Code <> '' then begin FRelaGclNodes.Add(ANode); ANode.RelaPeg := True; end; end; procedure TtpPegNode.LoadRelaGclNodes; begin FRelaGclNodes.Clear; LoadGclNodes(FRelaNode); end; { TtpPegList } procedure TtpPegList.Clear; begin FTotalPrice := 0; ClearObjects(FPegNodes); end; constructor TtpPegList.Create; begin FPegNodes := TList.Create; FBeginPegNum := 0; FEndPegNum := 0; FTotalPrice := 0; end; destructor TtpPegList.Destroy; begin Clear; FPegNodes.Free; inherited; end; function TtpPegList.GetPeg(AIndex: Integer): TtpPegNode; begin Result := TtpPegNode(FPegNodes.Items[AIndex]); end; function TtpPegList.GetCount: Integer; begin Result := FPegNodes.Count; end; procedure TtpPegList.SaveDebugData(const AFileName: string); var i: Integer; sgs: TStringList; vPeg: TtpPegNode; begin sgs := TStringList.Create; try for i := 0 to Count - 1 do begin vPeg := Peg[i]; sgs.Add(Format('×®ºÅ%s: Æðµã: %f ÖÕµã: %f', [vPeg.Peg, vPeg.BeginPegNum, vPeg.EndPegNum])); end; finally sgs.SaveToFile(AFileName); sgs.Free; end; end; procedure TtpPegList.SortPegs; function PegCompare(Item1, Item2: Pointer): Integer; var vPeg1, vPeg2: TtpPegNode; begin vPeg1 := TtpPegNode(Item1); vPeg2 := TtpPegNode(Item2); if vPeg1.BeginPegNum > vPeg2.BeginPegNum then Result := 1 else if vPeg1.BeginPegNum < vPeg2.BeginPegNum then Result := -1 else if vPeg1.PegLength > vPeg2.PegLength then Result := 1 else if vPeg1.PegLength < vPeg2.PegLength then Result := -1 else Result := 0; end; begin FPegNodes.Sort(@PegCompare); end; procedure TtpPegList.AddPegs(APeg: TtpPegNode); begin FPegNodes.Add(APeg); FBeginPegNum := Min(FBeginPegNum, APeg.BeginPegNum); FEndPegNum := Max(FEndPegNum, APeg.EndPegNum); FTotalPrice := FTotalPrice + APeg.RelaNode.TotalPrice; end; procedure TtpPegList.LoadRelaGclNodes; var iPeg: Integer; vPeg: TtpPegNode; begin for iPeg := 0 to FPegNodes.Count - 1 do begin vPeg := TtpPegNode(FPegNodes.Items[iPeg]); vPeg.LoadRelaGclNodes; end; end; function TtpPegList.GetBeginPeg: string; begin Result := Num2Peg(FBeginPegNum); end; function TtpPegList.GetEndPeg: string; begin Result := Num2Peg(FEndPegNum); end; function TtpPegList.TrialTotalPrice(ABeginPegNum, AEndPegNum: Double): Double; var iPeg: Integer; vPegNode: TtpPegNode; begin Result := 0; for iPeg := 0 to FPegNodes.Count - 1 do begin vPegNode := Peg[iPeg]; if vPegNode.IsPegIn(ABeginPegNum, AEndPegNum) then Result := Result + vPegNode.RelaNode.TotalPrice; end; end; end.