unit ChannelList;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Grids, BaseGrid, AdvGrid, StdCtrls, ExtCtrls, tmsAdvGridExcel;

type
  TChannelListForm = class(TForm)
    g: TAdvStringGrid;
    btXLS: TButton;
    Button2: TButton;
    xls: TAdvGridExcelIO;
    op: TOpenDialog;
    lbWait: TLabel;
    procedure FormActivate(Sender: TObject);
    procedure btXLSClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    list_done: boolean;
    cache: TStringList;
    procedure AddEmptyChannels;
    procedure MarkDups;
    { Private declarations }
  public
    { Public declarations }
  end;


  procedure _Show_ChannelList;

var
  ChannelListForm: TChannelListForm;

implementation
uses
  users,
  numbers,
  TagStorage,
  RpVisualGlobal;

{$R *.dfm}

procedure _Show_ChannelList;
begin
  if not rvgLogIn then exit;

  if ChannelListForm=nil then
    ChannelListForm := TChannelListForm.Create(nil);


  ChannelListForm.Show;




end;

procedure TChannelListForm.FormActivate(Sender: TObject);

  function _get_nomer(s,s1,s2: string): string;
  var
   k,n: integer;
  begin
    result := s;
    n := length(s1);
    k := pos(s1,s);
    if k=0 then exit;
    delete(s, 1, k+n-1);

    n := length(s);
    k := pos(s2,s);
    if k=0 then exit;
    delete(s, k, n-k+1);

    result := s;

  end;


  function _make_name(var name: string; var descr: string; src, addname, adddescr: string): boolean;
  var
    k: integer;
  begin
    result := false;
    k:=pos(src, name);
    if k=0 then exit;
    delete(name, k, length(src));
    insert(addname, name, k);
    descr := descr + adddescr;
    result := true;
  end;

var
  s: string;
  i,k,v: integer;
  plata,adr,name,descr,path: string;
  flag: boolean;
begin
  if list_done then exit;
  
  btXLS.Visible :=  CheckAccess(PREVILEG_CHANNELS, false);

  update;


  g.Cells[0,0] := '';
  g.Cells[1,0] := '№пл';
  g.Cells[2,0] := 'Адрес';
  g.Cells[3,0] := 'Номер';
  g.Cells[4,0] := 'Описание';
  g.Cells[5,0] := 'Имя тега';

  g.BeginUpdate;

  cache.Clear;
  i := 0;
  k := 1;
  repeat
    s := GetTagName(i);
    flag := true;

    if not(s='') then begin

      adr:='';
      name:='';
      descr:='';
      plata:='';




      if CheckFilter(s, '*.MCHA_*_Channel') then begin
        name := _get_nomer(s, 'MCHA_', '_Channel');
      end else

      if CheckFilter(s, '*.MCHB_*_Channel1') then begin
        name := _get_nomer(s, 'MCHB_', '_Channel1');
      end else

      if CheckFilter(s, '*.MCHB_*_Channel2') then begin
        name := _get_nomer(s, 'MCHB_', '_Channel2');
        descr := 'контроль';
      end else

      if CheckFilter(s, '*.ZDVA_*_Chnl1In') then begin
        name := _get_nomer(s, 'ZDVA_', '_Chnl1In');
        descr := 'конечник Откр / Напр2';
      end else

      if CheckFilter(s, '*.ZDVA_*_Chnl2In') then begin
        name := _get_nomer(s, 'ZDVA_', '_Chnl2In');
        descr := 'конечник Закр / Напр1';
      end else

      if CheckFilter(s, '*.ZDVA_*_Chnl1Out') then begin
        name := _get_nomer(s, 'ZDVA_', '_Chnl1Out');
        descr := 'Откр / Напр2';
      end else

      if CheckFilter(s, '*.ZDVA_*_Chnl2Out') then begin
        name := _get_nomer(s, 'ZDVA_', '_Chnl2Out');
        descr := 'Закр / Напр1';
      end else



      if CheckFilter(s, '*.ZDVB_*_Chnl1In') then begin
        name := _get_nomer(s, 'ZDVB_', '_Chnl1In');
        descr := 'конечник Откр / Напр2';
      end else

      if CheckFilter(s, '*.ZDVB_*_Chnl2In') then begin
        name := _get_nomer(s, 'ZDVB_', '_Chnl2In');
        descr := 'конечник Закр / Напр1';
      end else

      if CheckFilter(s, '*.ZDVB_*_Chnl1Out') then begin
        name := _get_nomer(s, 'ZDVB_', '_Chnl1Out');
        descr := 'Откр / Напр2';
      end else

      if CheckFilter(s, '*.ZDVB_*_Chnl2Out') then begin
        name := _get_nomer(s, 'ZDVB_', '_Chnl2Out');
        descr := 'Закр / Напр1';
      end else



      if CheckFilter(s, '*.MDTA_*_Channel') then begin
        name := _get_nomer(s, 'MDTA_', '_Channel');
        if not _make_name(name, descr, '_DVU',  ' ', 'ДВУ') then
        if not _make_name(name, descr, '_DNU',  ' ', 'ДНУ') then
        if not _make_name(name, descr, '_DSU',  ' ', 'ДСУ') then
        if not _make_name(name, descr, '_Avr',  ' ', 'Уровень') then
        if not _make_name(name, descr, '_Work', ' ', 'Питание') then
        if not _make_name(name, descr, '_RKS1', ' ', 'РКС 1') then
        if not _make_name(name, descr, '_RKS2', ' ', 'РКС 2') then
        if not _make_name(name, descr, '_RKS3', ' ', 'РКС 3') then
        if not _make_name(name, descr, '_RKS',  ' ', 'РКС') then
        if not _make_name(name, descr, '_Pdp1', ' ', 'Подпор 1') then
        if not _make_name(name, descr, '_Pdp2', ' ', 'Подпор 2') then
        if not _make_name(name, descr, '_Pdp3', ' ', 'Подпор 3') then
        if not _make_name(name, descr, '_Pdp',  ' ', 'Подпор') then
        if not _make_name(name, descr, '_Pdp',  ' ', 'РКС') then
        if not _make_name(name, descr, '_LntH', ' ', 'Лента верх') then
        if not _make_name(name, descr, '_LntL', ' ', 'Лента низ') then
        if not _make_name(name, descr, '_Tok1', ' ', 'Ток 1') then
        if not _make_name(name, descr, '_Tok2', ' ', 'Ток 2') then
        if not _make_name(name, descr, '_Tok3', ' ', 'Ток 3') then
        if not _make_name(name, descr, '_Tok',  ' ', 'Ток') then
        if not _make_name(name, descr, '_Tros', ' ', 'Трос') then
        if not _make_name(name, descr, '_DNP1',  ' ', 'ДНП 1') then
        if not _make_name(name, descr, '_DNP2',  ' ', 'ДНП 2') then
        if not _make_name(name, descr, '_DNP3',  ' ', 'ДНП 3') then
        if not _make_name(name, descr, '_DNP',  ' ', 'ДНП') then

        ;
      end else
        flag := false;



      if flag then begin

        v := GetTagValue( i );
        if ((v mod 256) > $7F) then begin
          v := v - $80;
          adr := ' a';
        end;
        plata := format('%.2d', [v div 256]);
        path := copy(s, 1, pos('.',s));
        adr := inttostr(v div 256) + '-' + format('%.2d', [v mod 256]) + adr;

        
        if g.RowCount<=k then g.RowCount:=k+1;

        g.Cells[1,k] := path + plata;
        g.Cells[2,k] := '  ' + adr;
        g.Cells[3,k] := name;
        g.Cells[4,k] := descr;
        g.Cells[5,k] := s;

        g.CellProperties[3,k].Alignment := taCenter;


        cache.Add(path + adr);

        lbWait.Caption := lbWait.Hint + ' ' + IntToStr(cache.Count);
        lbWait.Update;

        inc(k);
      end;
    end;
    inc(i);
  until s='';

  cache.Sort;
  
  AddEmptyChannels;

  g.EndUpdate;

  g.SortIndexes.Clear;
  g.SortIndexes.AddIndex(1,true);
  g.SortIndexes.AddIndex(2,true);
  g.SortIndexes.AddIndex(3,true);
  g.SortIndexes.AddIndex(4,true);
  g.SortIndexes.AddIndex(5,true);
  g.QSortIndexed;
  g.GroupColumn := 1;
//  g.Group(0);
  g.Grouping.MergeHeader := true;
  g.QSortGroup;

  MarkDups;

  g.Visible := true;
  list_done := true;
end;



procedure TChannelListForm.AddEmptyChannels;
var
  s: string;
  i,j,k,v,found: integer;
  plata,adr,name,descr,path: string;
  flag: boolean;
  tp: TPoint;
begin
  i := 0;
  k := 1;
  repeat
    s := GetTagName(i);
    flag := true;

    if not(s='') then begin

      if CheckFilter(s, '*.PL*NetAddress') then begin
        v := GetTagValue( i );
        if v > 255 then
          v := v and 255;

        path := copy(s, 1, pos('.',s));
        plata := path + format('%.2d', [v]);

        for j:=0 to 63 do begin
          s := inttostr(v) + '-' + format('%.2d', [j]);
          adr := s;

          s := '  ' + s;

          g.FindCol := 2;

          if( cache.Find(path + adr, found) ) then begin
            found := 0; // workaround for optimizer's bug
            Continue;
          end;

          s := s + ' a';
          if( cache.Find(path + adr + ' a', found) ) then begin
            found := 0; // workaround for optimizer's bug
            Continue;
          end;

          cache.Add(path + adr);

//          tp := Point(-1,-1);
//          tp := g.Find(tp, s, [fnMatchFull, fnFindInPresetCol]);
//          if not((tp.X=-1) or (tp.Y=-1)) then continue;
//
//          s := s + ' a';
//          tp := Point(-1,-1);
//          tp := g.Find(tp, s, [fnMatchFull, fnFindInPresetCol]);
//          if not((tp.X=-1) or (tp.Y=-1)) then continue;

          k := g.RowCount;
          g.RowCount := g.RowCount + 1;

          g.Cells[1,k] := plata;
          g.Cells[2,k] := '  ' + adr;
          g.Cells[3,k] := '';
          g.Cells[4,k] := '';
          g.Cells[5,k] := '';
        end;

      end;

    end;
    inc(i);
  until s='';
end;


procedure TChannelListForm.MarkDups;
var
  i,k1,k2: integer;
  s1,s2: string;
begin
  for i:=0 to g.RowCount-2 do begin
    s1 := g.Cells[1,i];
    if length(s1)<=2 then continue;
    s2 := g.Cells[1,i+1];
    if (pos(s1,s2)>0) or (pos(s1,s2)>0) then begin
      g.CellProperties[1,i].BrushColor := $003869FA;
      g.CellProperties[1,i].BrushColorTo := $005FB0FA;
      g.CellProperties[1,i+1].BrushColor := $005FB0FA;
      g.CellProperties[1,i+1].BrushColorTo := $003869FA;
    end;
  end;

end;


procedure TChannelListForm.btXLSClick(Sender: TObject);
var
  i,k: integer;
  s: string;
begin


  if not op.Execute then exit;

  for i:=0 to g.RowCount-1 do begin
    s := g.Cells[1,i];
    k := pos('-',s);

    if (k>0) then begin
//      insert(' ', s, k+1);
//      insert(' ', s, k);
//      g.Cells[1,i] := '"' + s + '  "';
//      g.Cells[1,i] := s + '.';
      g.Cells[1,i] := '.' + s ;
    end;
  end;
  xls.XLSExport(op.FileName);
  Close;
end;

procedure TChannelListForm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  ChannelListForm := nil;
  Release;
end;

procedure TChannelListForm.Button2Click(Sender: TObject);
begin
  close;
end;

procedure TChannelListForm.FormCreate(Sender: TObject);
begin
  cache := TStringList.Create;
  cache.Sorted := true;
end;

procedure TChannelListForm.FormDestroy(Sender: TObject);
begin
  cache.Free(); 
end;

end.
