unit VisSeqcRootData;

interface
uses
  pFIBDatabase, pFIBDataSet, Classes, StdCtrls, dialogs, SysUtils, VisSeqcConnection,
  Windows, Graphics, VisSeqcApi;

type

  TSeqcRootDataRec = record
    name: string;
    tagAddr: integer;
    tagDelays: integer;
    tagModeflags: integer;
    valAddr: integer;
    valDelays: integer;
    valModeflags: integer;
  end;


  TSeqcRootDataImpl = class(TSeqcRootData)
  private
    conn: TSeqcConnection;
    ds: TpFIBDataSet;
    code: Integer;
    TagPath: string;
    TagRoot: string;
    tagCode: Integer;
    devices: array of TSeqcRootDataRec;
    deviceCount: Integer;

    function getDeviceCountFromDB: Integer;
    procedure getDevicesFromDB;
    procedure getTagIndexes;
  public
    constructor create(conn: TSeqcConnection; code: Integer; TagPath, TagRoot: string); override;
    function toString: string; override;
    function getDeviceCount: Integer; override;
    function installRootToPLC(timeout: Integer): boolean; override;
  end;


implementation
uses
  Status,
  TagStorage,
  Numbers,
  RpVisualParams, DB;



{ TSeqcRootData }

constructor TSeqcRootDataImpl.create(conn: TSeqcConnection; code: Integer;
  TagPath, TagRoot: string);
begin
  Self.conn := conn;
  Self.code := code;
  Self.TagPath := TagPath;
  Self.TagRoot := TagRoot;
  ds := conn.getDataset;


  deviceCount := getDeviceCountFromDB+1;
  SetLength( devices, deviceCount );

  getTagIndexes;

  getDevicesFromDB;
  
end;


function TSeqcRootDataImpl.getDeviceCount: Integer;
begin
  Result := deviceCount;
end;

function TSeqcRootDataImpl.getDeviceCountFromDB: Integer;
begin
  result := 0;
  ds.SQLs.SelectSQL.Text := 'select count(*) from rootdevices rd, roots r '+
        'where rd.root_id=r.id and r.code=' + IntToStr(code);
  try
    ds.Open;
    if not ds.Eof then
      result := ds.Fields[0].AsInteger;
    ds.Close;
  except
    ds.Active := False;
  end;
end;


procedure TSeqcRootDataImpl.getDevicesFromDB;
var
  i: integer;
begin
  ds.SQLs.SelectSQL.Text :=
    'select d.name, d.addr, (rd.TIMESTART*256+rd.TIMESTOP) as delays, ' +
    '(rd.FL_ARMO + rd.FL_TRANSPARENT*2 + rd.FL_CTRLPROD*8 + rd.FL_PROD*16 '+
    '+ rd.FL_CTRLONLY*32 + rd.FL_SOLEOWNER*64 + rd.DLY_PRODSTOP*256) as modeflags '+
    'from rootdevices rd, devices d, roots r '+
    'where rd.root_id=r.id and rd.device_id=d.id and r.code=' + IntToStr(code) +
    ' order by rd.ORDERNUM';

  try
    i:=0;
    ds.Open;
    while (not ds.Eof) and (i<deviceCount) do begin
      devices[i].name := ds.Fields[0].AsString;
      devices[i].valAddr := ds.Fields[1].AsInteger;
      devices[i].valDelays := ds.Fields[2].AsInteger;
      devices[i].valModeflags := ds.Fields[3].AsInteger;

      ds.Next;
      inc(i);
    end;
    ds.Close;
  except
    ds.Active := False;
  end;
end;


procedure TSeqcRootDataImpl.getTagIndexes;
var
  i: integer;
  _address, _delays, _modeflags: string;
begin
  _address   := TagPath + '.SEQC_' + TagRoot + '_Address';
  _delays    := TagPath + '.SEQC_' + TagRoot + '_Delays';
  _modeflags := TagPath + '.SEQC_' + TagRoot + '_ModeFlags';
  for i:=0 to deviceCount-1 do begin
    devices[i].tagAddr      := GetTagIndex( _address   + IntToStr(i) );
    devices[i].tagDelays    := GetTagIndex( _delays    + IntToStr(i) );
    devices[i].tagModeflags := GetTagIndex( _modeflags + IntToStr(i) );
    devices[i].valAddr      := $FFFF;
    devices[i].valDelays    := 0;
    devices[i].valModeflags := 0;
  end;
  tagCode := GetTagIndex( TagPath + '.SEQC_' + TagRoot + '_Code' );

end;


function TSeqcRootDataImpl.toString: string;
var
  s: string;
  i: integer;
begin
  s := '';
  for i:=0 to deviceCount-1 do
    s := s +
      'add=' + IntToStr(devices[i].valAddr) + '/' + IntToStr(devices[i].tagAddr) + ' ' +
      'dly=' + IntToStr(devices[i].valDelays) + '/' + IntToStr(devices[i].tagDelays) + ' ' +
      'flg=' + IntToStr(devices[i].valModeflags) + '/' + IntToStr(devices[i].tagModeflags) + ' '+
      devices[i].name + #13#10;

  result := s;
end;




function TSeqcRootDataImpl.installRootToPLC(timeout: Integer): boolean;

  procedure settag(idx, value: integer; var flagOk: boolean);
  begin
    if GetTagValue(idx) <> value then begin
      SetTagValue(idx, value);
      flagOk := False;
    end;
  end;

var
  i: Integer;
  timebeg: cardinal;
  flagOk: Boolean;
begin
  ShowStatusMessageA('Установка данных','подождите...', clLime);

  timebeg := GetTickCount;

  repeat
    flagOk := true;
    settag(tagCode, code, flagOk);
    for i:=0 to deviceCount-1 do begin
      settag(devices[i].tagAddr, devices[i].valAddr, flagOk);
      settag(devices[i].tagDelays, devices[i].valDelays, flagOk);
      settag(devices[i].tagModeflags, devices[i].valModeflags, flagOk);
    end;

  until (GetTickCount-timebeg > timeout) or (flagOk);

  CloseStatusMessage;

  if not flagOk then
    MessageDlg('Установка данных не выполнена!', mtError, [mbOK], 0);

  Result := flagOk;
end;


end.
