unit U_PortsReIndex;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, siComp, siLngLnk, StdCtrls, ExtCtrls, Buttons, Spin, ComCtrls,
  ToolWin, U_SCSComponent, U_BaseCommon;

type
  TF_PortsReIndex = class(TForm)
    Button1: TButton;
    Button2: TButton;
    siLangLinked1: TsiLangLinked;
    RApplyFor: TRadioGroup;
    RComponIndexType: TRadioGroup;
    SheetsOrderList: TListBox;
    SheetOrderLabel: TLabel;
    RComplectIndexType: TRadioGroup;
    CheckBox1: TCheckBox;
    SpinEdit1: TSpinEdit;
    CheckBox2: TCheckBox;
    SpinEdit2: TSpinEdit;
    CantReidexChildCompon: TCheckBox;
    ToolBar1: TToolBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    ToolButton3: TToolButton;
    RComponSortOrder: TRadioGroup;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure RApplyForClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ToolButton2Click(Sender: TObject);
    procedure ToolButton1Click(Sender: TObject);
    procedure ToolButton3Click(Sender: TObject);
    Function GetComponListFromTreeSelection: TSCSComponents;
    destructor Destroy; override;
    procedure CantReidexChildComponClick(Sender: TObject);
    procedure RComponIndexTypeClick(Sender: TObject);
    procedure RComplectIndexTypeClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    Procedure StartReindex;
    Procedure DisableSheetsOrder;
    Procedure EnableSheetsOrder;
    Procedure LoadProjLists;
    Procedure GetSheetsList(aList: TList);
    procedure ReindexComponsPorts(aList: TList);
    Procedure RemoveChildsFromList(var aList: TSCSComponents);
  end;

var
  F_PortsReIndex: TF_PortsReIndex;
  CanReindexComplects, ByCreationOrder: Boolean;
  LastClickedCompon: TSCSComponent;
  currComponPortIndex, currChildComponPortIndex: integer;
  ComponType: TComponentType;
  Tree_Selection: TSCSComponents;

implementation

uses USCS_Main, U_MAIN, U_ESCadClasess, U_SCSClasses,
  U_SCSLists, U_LNG;

{$R *.dfm}

Procedure TF_PortsReIndex.RemoveChildsFromList(var aList: TSCSComponents);
var i: integer;
    currCompon, ParentCompon: TSCSComponent;
    ComponToRemoveList: TSCSComponents;
begin
  // сбросить выбранных чилдов (мало ли что там юзер выбрал...)
  ComponToRemoveList := TSCSComponents.Create(false); // список на удаление, если парент - в списке выбранных
  for I := 0 to aList.Count - 1  do
  begin
    currCompon := aList[i];
    if Assigned(currCompon.Parent) then
    begin
      if currCompon.Parent is TSCSComponent then
      begin
        ParentCompon := TSCSComponent(currCompon.Parent);
        if aList.IndexOf(ParentCompon) <> -1 then
        begin
          ComponToRemoveList.Add(currCompon);
        end;
      end;
    end;
  end;

  for i := 0 to ComponToRemoveList.Count - 1 do
    aList.Remove(ComponToRemoveList[i]);
  ComponToRemoveList.Free;
end;

Function TF_PortsReIndex.GetComponListFromTreeSelection: TSCSComponents;
var Node: TTreeNode;
    i: integer;
    currCompon: TSCSComponent;
begin
  Result := TSCSComponents.Create(false);
  for i := 0 to F_ProjMan.Tree_Catalog.SelectionCount - 1 do
  begin
    Node := F_ProjMan.Tree_Catalog.Selections[i];
    if Node <> nil then
    begin
      if Node.Data <> nil then
      begin
        if PObjectData(Node.Data).ObjectID > -1 then
          currCompon := F_ProjMan.GSCSBase.CurrProject.GetComponentFromReferencesList(PObjectData(Node.Data).ListID, PObjectData(Node.Data).ObjectID);
        if currCompon <> nil then
        begin
          if currCompon.IsLine = biFalse then
            Result.Add(currCompon);
        end;
      end;
    end;
  end;

  if Result.Count > 1 then
    RemoveChildsFromList(Result);
end;

destructor TF_PortsReIndex.Destroy;
begin
  Tree_Selection.Free;
  inherited;
end;

Procedure TF_PortsReIndex.GetSheetsList(aList: TList);
var i: integer;
    ComponList: TSCSComponents;
    CurrCompon: TSCSComponent;
    CurrList: TSCSList;
begin
  if RApplyFor.Enabled then
  begin
    case RApplyfor.ItemIndex of
      0: begin
           for i := 0 to Tree_Selection.Count - 1 do
           begin
             CurrList := F_ProjMan.GSCSBase.CurrProject.GetListByID(Tree_Selection[i].ListID);
             if aList.IndexOf(CurrList) = -1 then
               aList.Add(CurrList);
           end;
         end;
      1: aList.Add(F_ProjMan.GSCSBase.CurrProject.CurrList);
      2: begin
           for i := 0 to SheetsOrderList.Count - 1 do
           begin
             aList.Add(SheetsOrderList.Items.Objects[i]);
           end;
         end;
    end;
  end
  else
  begin
    for i := 0 to Tree_Selection.Count - 1 do
    begin
      CurrList := F_ProjMan.GSCSBase.CurrProject.GetListByID(Tree_Selection[i].ListID);
      if aList.IndexOf(CurrList) = -1 then
        aList.Add(CurrList);
    end;
  end;
end;

procedure TF_PortsReIndex.ReindexComponsPorts(aList: TList);
var i, j, k: integer;
    ComponList: TSCSComponents;
    CurrList: TSCSList;
    ComponIdex, StartChildIndex: Integer;
    CurrCompon: TSCSComponent;

    Procedure ReindexPorts(aCompon: TSCSComponent; var aIndex: Integer; aIsChild: Boolean = False);
    var i: integer;
        StartIndex: integer;
    begin
      // ReindexPorts
      for i := 0 to aCompon.Interfaces.Count - 1 do
      begin
        if aCompon.Interfaces[i].TypeI = itFunctional then
        begin
          if aCompon.Interfaces[i].IsPort = biTrue then
          begin
            aCompon.Interfaces[i].NppPort := aIndex;
            inc(aIndex);
          end;
        end;
      end;
      // ReindexChildPorts
      if CanReindexComplects then
      begin
        for i := 0 to aCompon.ChildComplects.Count - 1 do
        begin
          if RComplectIndexType.ItemIndex = 0 then
            ReindexPorts(aCompon.ChildComplects[i], aIndex, True)
          else
          begin
            StartIndex := 1;
            if CheckBox2.Checked then
              StartIndex := SpinEdit2.Value;
            ReindexPorts(aCompon.ChildComplects[i], aIndex, True)
          end;
        end;
      end;
    end;

    Procedure SortComponByUserOrder;
    var i: integer;
        CanSort: Boolean;
    begin
      if ComponList.Count > 0 then
      begin
        CanSort := True;
        while CanSort do
        begin
          CanSort := False;
          case RComponSortOrder.ItemIndex of
            0: begin
                 for i := 0 to ComponList.Count - 2 do
                 begin
                   if ComponList[i].ID > ComponList[i + 1].ID then
                   begin
                     CanSort := True;
                     ComponList.Exchange(i, i + 1);
                   end;
                 end;
               end;
            1: begin
                 for i := 0 to ComponList.Count - 2 do
                 begin
                   if ComponList[i].SortID > ComponList[i + 1].SortID then
                   begin
                     CanSort := True;
                     ComponList.Exchange(i, i + 1);
                   end;
                 end;
               end;
          end;
        end;
      end;
    end;
begin
  ComponList := TSCSComponents.Create(false);
  for i:= 0 to aList.Count - 1 do
  begin
    //currList := TSCSList(aList);
    currList := TSCSList(aList[i]);
    // Select Compons
    if RApplyFor.Enabled then
    begin
      if RApplyFor.ItemIndex = 0 then // by selection
      begin
        ComponList.Assign(Tree_Selection);
        if ComponList.Count > 1 then
        begin
          for j := ComponList.Count - 1 downto 0 do
          begin
            if ComponList[j].ListID <> CurrList.ListID then
              ComponList.Remove(ComponList[j]);
          end;
        end;
      end
      else // by ComponentType
      begin
        ComponList.Assign(CurrList.ComponentReferences);
        for j := ComponList.Count - 1 downto 0 do
        begin
          if ComponList[j].IsLine = biTrue then
            ComponList.Remove(ComponList[j])
          else
          if ComponList[i].ComponentType.NamePlural <> ComponType.NamePlural then
            ComponList.Remove(ComponList[j]);
        end;
        RemoveChildsFromList(ComponList);
      end;
    end
    else
    begin
      ComponList.Assign(Tree_Selection);
      if ComponList.Count > 1 then
      begin
        for j := ComponList.Count - 1 downto 0 do
        begin
          if ComponList[j].ListID <> CurrList.ListID then
            ComponList.Remove(ComponList[j]);
        end;
      end;
    end;

    SortComponByUserOrder;

    for j := 0 to ComponList.Count - 1 do
    begin
      CurrCompon := ComponList[i];
      if RComponIndexType.ItemIndex = 0 then
      begin
        ReindexPorts(currCompon, currComponPortIndex);
        if CanReindexComplects then
        begin
          for k := 0 to CurrCompon.ChildComplects.Count - 1 do
          begin
            if RComplectIndexType.ItemIndex = 0 then
            begin
              ReindexPorts(CurrCompon.ChildComplects[k], currComponPortIndex, True)
            end
            else
            begin
              if CheckBox2.Checked then
                StartChildIndex := Spinedit2.value
              else
                StartChildIndex := 1;

              ReindexPorts(CurrCompon.ChildComplects[k], StartChildIndex, True);
            end;
          end;
        end;
      end
      else
      begin
        for k := 0 to CurrCompon.ChildComplects.Count - 1 do
        begin
          if RComplectIndexType.ItemIndex = 0 then
          begin
            ReindexPorts(CurrCompon.ChildComplects[k], currComponPortIndex, True)
          end
          else
          begin
            if CheckBox2.Checked then
              StartChildIndex := Spinedit2.value
            else
              StartChildIndex := 1;

            ReindexPorts(CurrCompon.ChildComplects[k], StartChildIndex, True);
          end;
        end;
      end;
    end;
    //ReindexPortsByList
  end;
end;



Procedure TF_PortsReIndex.StartReindex;
var i: integer;
    SheetsList: TList; //
    SCSCompon: TSCSComponent;
begin
  CanReindexComplects := not CantReidexChildCompon.Checked; // можно ли индексить порты комплектющих
  ByCreationOrder := (RComplectIndexType.ItemIndex = 0); // порядок компонент для индексирования
  SheetsList := TList.Create; // список листов

  RemoveChildsFromList(Tree_Selection);

  LastClickedCompon := F_ProjMan.GetActualSelectedComponent;

  ComponType := LastClickedCompon.ComponentType;

  currComponPortIndex := 1;

  if CheckBox1.Checked then
    currComponPortIndex := Spinedit1.Value;

  if CanReindexComplects then
  begin
    currChildComponPortIndex := 1;
    if CheckBox2.Checked then
      currChildComponPortIndex := Spinedit1.Value;
  end;

  GetSheetsList(SheetsList);
  ReindexComponsPorts(SheetsList);
  //free memory
  SheetsList.Free;
end;

procedure TF_PortsReIndex.ToolButton1Click(Sender: TObject);
var i, currIndex: integer;
begin
  if SheetsOrderList.Count > 1 then
  begin
    currIndex := SheetsOrderList.ItemIndex;
    if currIndex < SheetsOrderList.Items.Count then
    begin
      SheetsOrderList.Items.Exchange(currIndex, currIndex + 1);
    end;
  end;
end;

procedure TF_PortsReIndex.ToolButton2Click(Sender: TObject);
var i, currIndex: integer;
begin
  if SheetsOrderList.Count > 1 then
  begin
    currIndex := SheetsOrderList.ItemIndex;
    if currIndex > 0 then
    begin
      SheetsOrderList.Items.Exchange(currIndex, currIndex - 1);
    end;
  end;
end;

procedure TF_PortsReIndex.ToolButton3Click(Sender: TObject);
begin
  LoadProjLists;
end;

Procedure TF_PortsReIndex.DisableSheetsOrder;
begin
  SheetsOrderList.Enabled := False;
  SheetOrderLabel.Enabled := False;
end;

Procedure TF_PortsReIndex.EnableSheetsOrder;
begin
  SheetsOrderList.Enabled := True;
  SheetOrderLabel.Enabled := True;
end;

procedure TF_PortsReIndex.Button1Click(Sender: TObject);
begin
  ModalResult := mrOK;
  StartReindex;
end;

procedure TF_PortsReIndex.Button2Click(Sender: TObject);
begin
  ModalResult := mrCancel;
end;

procedure TF_PortsReIndex.CantReidexChildComponClick(Sender: TObject);
begin
  if CantReidexChildCompon.checked then
  begin
    CheckBox2.Enabled := False;
    SpinEdit2.Enabled := False;
    RComplectIndexType.Enabled := False
  end
  else
  begin
    CheckBox2.Enabled := True;
    SpinEdit2.Enabled := True;
    RComplectIndexType.Enabled := True;
  end;
end;

Procedure TF_PortsReIndex.LoadProjLists;
var i: integer;
    prLists: TstringList;
begin
  prLists := TStringList.Create;
  for i := 0 to F_ProjMan.GSCSBase.CurrProject.ProjectLists.Count - 1 do
  begin
    if F_ProjMan.GSCSBase.CurrProject.ProjectLists[i].Setting.ListType = lt_Normal then
      prLists.AddObject(F_ProjMan.GSCSBase.CurrProject.ProjectLists[i].GetNameForVisible, F_ProjMan.GSCSBase.CurrProject.ProjectLists[i]);
  end;
  SheetsOrderList.Items.Clear;
  SheetsOrderList.Items.Assign(prLists);
  prLists.Free;
end;

procedure TF_PortsReIndex.FormCreate(Sender: TObject);
begin
 { RComponIndexType.Buttons[1].Checked := True;
  RComplectIndexType.Buttons[1].Checked := True;
  RApplyFor.Buttons[1].Checked := true;}
  RComponIndexType.ItemIndex := 0;
  RComplectIndexType.ItemIndex := 0;
  RApplyFor.ItemIndex := 0;
  RComponSortOrder.ItemIndex := 1;
  Tree_Selection := nil;
end;

procedure TF_PortsReIndex.FormShow(Sender: TObject);
var i: integer;
    prLists: TStringList;
begin
  ModalResult := mrNone;
  if Tree_Selection <> nil then
    FreeAndNil(Tree_Selection);

  Tree_Selection := GetComponListFromTreeSelection; // выбранные в ПМ (отсеяны чилды)
  //RemoveChildsFromList(Tree_Selection);
  if Tree_Selection.Count > 1 then
    RApplyFor.Enabled := False
  else
    RApplyFor.Enabled := True;
  LoadProjLists;
end;

procedure TF_PortsReIndex.RApplyForClick(Sender: TObject);
var i: integer;
begin
  if RApplyFor.ItemIndex = 2 then
  begin
    EnableSheetsOrder;
  end
  else
    DisableSheetsOrder;
end;

procedure TF_PortsReIndex.RComplectIndexTypeClick(Sender: TObject);
begin
  if RComplectIndexType.ItemIndex = 0 then
  begin
    CheckBox2.Enabled := False;
    SpinEdit2.Enabled := False;
  end
  else
  begin
    CheckBox2.Enabled := True;
    SpinEdit2.Enabled := True;
  end;
end;

Procedure TF_PortsReIndex.RComponIndexTypeClick(Sender: TObject);
begin
  if RComponIndexType.ItemIndex = 0 then
  begin
    CantReidexChildCompon.Enabled := True;
    if CantReidexChildCompon.checked then
    begin
      CheckBox2.Enabled := False;
      SpinEdit2.Enabled := False;
      RComplectIndexType.Enabled := False
    end
    else
    begin
      RComplectIndexType.Enabled := True;
      if RComplectIndexType.ItemIndex = 0 then
      begin
        CheckBox2.Enabled := False;
        SpinEdit2.Enabled := False;
      end
      else
      begin
        CheckBox2.Enabled := True;
        SpinEdit2.Enabled := True;
      end;
    end;
  end
  else
  begin
    CantReidexChildCompon.Enabled := False;
    CheckBox2.Enabled := True;
    SpinEdit2.Enabled := True;
    RComplectIndexType.Enabled := True;
  end;
end;

end.
