unit VisSeqcConnection;

interface
uses
  pFIBDatabase, pFIBDataSet, Classes, StdCtrls, dialogs, SysUtils, VisSeqcApi;

type
  TSeqcConnectionImpl = class(TSeqcConnection)
  private
    db: TpFIBDatabase;
    ds: TpFIBDataSet;
    tr1: TpFIBTransaction;
    tr2: TpFIBTransaction;
    tr3: TpFIBTransaction;
    tr4: TpFIBTransaction;


  public
    constructor create(dbNameParam: string); override;
    destructor destroy; override;

    procedure getRootList(filter: string; list: TStrings);
    procedure getRootListCombobox(cmb: TComboBox; filter: string; TagPath, TagRoot: string); override;

    function installRoot(code: integer; TagPath, TagRoot: string): boolean; override;
//    function installAndStartRoot(code: integer; TagPath, TagRoot: string): boolean; override;

    function getDataset: TpFIBDataSet; override;
    function isConnected: boolean; override;
  end;





implementation
uses
  IniFiles,
  VisSeqcRootData,
  TagStorage,
  Numbers,
  RpVisualParams, DB;



{ TSeqcConnection }

constructor TSeqcConnectionImpl.create(dbNameParam: string);
var
  dbname: string;
begin
  dbname := rpVisualParams_Read( dbNameParam, '', '');
  db := TpFIBDatabase.Create(nil);
  ds := TpFIBDataSet.Create(db);
  tr1 := TpFIBTransaction.Create(db);
  tr2 := TpFIBTransaction.Create(db);
  tr3 := TpFIBTransaction.Create(ds);
  tr4 := TpFIBTransaction.Create(ds);

  db.DefaultTransaction := tr1;
  db.DefaultUpdateTransaction := tr2;
  tr1.DefaultDatabase := db;
  tr2.DefaultDatabase := db;

  ds.Database := db;
  ds.Transaction := tr3;
  ds.UpdateTransaction := tr4;
  tr3.DefaultDatabase := db;
  tr4.DefaultDatabase := db;

  db.DBName := trim(dbname);
  db.DBParams.Add('user_name=SYSDBA');
  db.DBParams.Add('password=masterkey');
  db.DBParams.Add('lc_ctype=WIN1251');

  if dbname='' then
    MessageDlg('Не указан путь базы данных в параметре ' + dbNameParam, mtError, [mbOK], 0)
  else
    try
      db.Connected := true;
    except
      MessageDlg('Ошибка подключения к базе данных ' + dbNameParam + ' (' + dbname + ')', mtError, [mbOK], 0);
      db.Connected := false;
    end;
end;

destructor TSeqcConnectionImpl.destroy;
begin
  try
    if ds.Active then
      ds.Active := false;

    if db.Connected then
      db.Connected := false;
  except
  end;
  db.Free;
end;

function TSeqcConnectionImpl.getDataset: TpFIBDataSet;
begin
  Result := ds;
end;


procedure TSeqcConnectionImpl.getRootList(filter: string; list: TStrings);
begin
  list.Clear;
  if not isConnected then Exit;
  ds.SQLs.SelectSQL.Text := 'select code, name from roots order by name';
  try
    ds.Open;
    while not ds.Eof do begin
      if CheckFilter(ds.Fields[1].AsString, filter) then
        list.AddObject( ds.Fields[1].AsString,  Pointer(ds.Fields[0].AsInteger) );
      ds.Next;
    end;
    ds.Close;
  except
    ds.Active := False;
  end;
end;


procedure TSeqcConnectionImpl.getRootListCombobox(cmb: TComboBox; filter,
  TagPath, TagRoot: string);
var
  code: integer;
  i: Integer;
begin
  // get current code
  code := GetTagValueByName( TagPath + '.SEQC_' + TagRoot + '_Code' );

  // or get last code
  if (code=0) or (code=$FFFF) then
    with TIniFile.Create(CurDir + RpVisualIniFile) do try
      code := ReadInteger('Seqc', TagPath+'_'+TagRoot, 0);
    finally
      Free;
    end;

  getRootList(filter, cmb.items);

  // set current root by code
  if code>0 then begin
    for i:=0 to cmb.Items.Count-1 do
      if cmb.Items.Objects[i] = Pointer(code) then begin
        cmb.ItemIndex := i;
        Exit;
      end;
  end else
    if cmb.Items.Count>0 then
      cmb.ItemIndex := 0;
end;





function TSeqcConnectionImpl.installRoot(code: integer; TagPath, TagRoot: string): boolean;
var
  r: TSeqcRootData;
begin
  r := TSeqcRootDataImpl.create(Self, code, TagPath, TagRoot);
  r.installRootToPLC(10000);
  r.Free;
end;





//function TSeqcConnectionImpl.installAndStartRoot(code: integer;
//  TagPath, TagRoot: string): boolean;
//begin
//
//end;



function TSeqcConnectionImpl.isConnected: boolean;
begin
  result := db.Connected;
end;

end.
