unit Calib;

interface

uses
  Windows, SysUtils, msxml, ADCDevice;

const
  CALIB_DEFAULT  = 'Default';
  CALIB_FILENAME = 'ADCx148D.xml';

type

  PCalibItem = ^TCalibItem;
  TCalibItem = record
    K : array [0..CHANNEL_COUNT - 1, 0..GAIN_COUNT - 1] of double;
    S : array [0..CHANNEL_COUNT - 1, 0..GAIN_COUNT - 1] of double;
  end;

  TCalibration = class
  private
    FCalib     : PCalibItem;
    FCalibName : string;
    FPath      : string;
  protected

  public
    constructor Create;virtual;
    destructor Destroy; override;
    procedure Load(AName : string);
    procedure Save(AName : string);

    property Calib : PCalibItem read FCalib write FCalib;
    property CalibName : string read FCalibName write FCalibName;
    property Path : string read FPath write FPath;
  end;


var
  Calibration : TCalibration;

implementation


constructor TCalibration.Create;
begin
  inherited Create;
  FCalibName := CALIB_DEFAULT;
  New(FCalib);
end;

destructor TCalibration.Destroy;
begin
  Dispose(FCalib);
  inherited Destroy;
end;

procedure TCalibration.Load(AName : string);
var
  i, j         : integer;
  Doc          : DomDocument;
  RootEl,
  Calibration,
  Item         : IXMLDOMNode;
  ChannelList,
  GainList     : IXMLDOMNodeList;
begin

  for i := 0 to CHANNEL_COUNT - 1 do
      for j := 0 to GAIN_COUNT - 1 do
      begin
        FCalib.K[i, j] := 1;
        FCalib.S[i, j] := 0;
      end;

  Doc := CoDOMDocument.Create;
  Doc.load(FPath + CALIB_FILENAME);
  RootEl := Doc.Get_documentElement;
  if Assigned(RootEl) then
  begin
    Calibration := RootEl.selectSingleNode(format('CALIBRATION[@NAME="%s"]', [AName]));
    if not Assigned(Calibration) then
        Calibration := RootEl.selectSingleNode(format('CALIBRATION[@NAME="%s"]', [CALIB_DEFAULT]));

    if Assigned(Calibration) then
    begin
      ChannelList := Calibration.selectNodes('CHANNEL');
      for i := 0 to ChannelList.length - 1 do
      begin
        GainList := ChannelList[i].selectNodes('GAIN');
        for j := 0 to GainList.length - 1 do
        begin
          Item := GainList[j].selectSingleNode('ITEM');
          FCalib.K[i, j] := Item.attributes.getnameditem('K').nodeValue;
          FCalib.S[i, j] := Item.attributes.getnameditem('S').nodeValue;
        end;
      end;
    end;
  end;

end;

procedure TCalibration.Save(AName : string);
var
  i,j       : integer;
  Doc       : DomDocument;
  RootEl,
  Calibration,
  Channel,
  Gain,
  Item      : IXMLDOMElement;
  Coment    : IXMLDOMComment;
begin
  Doc:= CoDOMDocument.Create;
  Doc.Set_async(false);

  Doc.load(FPath + CALIB_FILENAME);     (*  вызов метода Load экземпляра объекта DOMDocument;  *)
  RootEl := Doc.Get_documentElement;
  if not Assigned(RootEl) then
  begin
    Doc.AppendChild(doc.CreateProcessingInstruction('xml', 'version="1.0" encoding="windows-1251"'));
    Doc.AppendChild(doc.CreateElement('CALIBRATIONS'));

    RootEl:= Doc.Get_documentElement;
    Coment  := Doc.createComment('XML файл калибровки для программы DataLogger');
    RootEl.appendChild(Coment);
  end;

  Calibration := RootEl.selectSingleNode(format('CALIBRATION[@NAME="%s"]', [AName])) as IXMLDOMElement;
  if assigned(Calibration) then
      RootEl.removeChild(Calibration);
  Calibration:= Doc.createElement('CALIBRATION');
  Calibration.setAttribute('NAME', AName);
  RootEl.appendChild(Calibration);

  for i := 0 to CHANNEL_COUNT - 1 do
  begin
    Channel:= Doc.createElement('CHANNEL');
    Calibration.appendChild(Channel);

    Coment  := Doc.createComment('Канал:' + IntToStr(i + 1));
    Channel.appendChild(Coment);

    for j := 0 to GAIN_COUNT - 1 do
    begin
      Gain:= Doc.createElement('GAIN');
      Channel.appendChild(Gain);

      Coment  := Doc.createComment('Усиление:' + IntToStr(Device.IndexToGain(j)));
      Gain.appendChild(Coment);

      Item:= Doc.createElement('ITEM');
      Item.setAttribute('K', FCalib.K[i, j]);
      Item.setAttribute('S', FCalib.S[i, j]);
      Gain.appendChild(Item);
    end;
  end;
  Doc.save(FPath + CALIB_FILENAME);
end;


initialization
  Calibration := TCalibration.Create;

finalization
  Calibration.Free;
end.


