unit IzmUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, PictureList, ExtCtrls, AdvPanel, AdvPicture, AdvGlowButton,
  AdvProgressBar, ActnList, DeviceRD, ComCtrls, DateUtils, DB, LayeredForm,
  IzmGraphUnit, user_types, class_measure, class_point, class_param, class_model;

type TIzmResult = array of array of user_types.params_record;
// type TIzmResult = array [1..24,1..5] of DeviceRD.params_record;
type
  TIzmForm = class(TForm)
    Izm_main_panel: TAdvPanel;
    Izm_top_panel: TPanel;
    Izm_middle_panel: TPanel;
    Izm_prev_point_btn: TAdvGlowButton;
    Izm_next_point_btn: TAdvGlowButton;
    Izm_condition_label: TLabel;
    Izm_stop_btn: TAdvGlowButton;
    Panel2: TPanel;
    Panel3: TPanel;
    Panel4: TPanel;
    Izm_info_panel: TPanel;
    Panel1: TPanel;
    Izm_progress_bar: TAdvProgressBar;
    Izm_point_picture: TAdvPicture;
    ActionList: TActionList;
    izm_next_point: TAction;
    izm_prev_point: TAction;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    Izm_patient_name: TLabel;
    Izm_date: TLabel;
    Izm_pat_num: TLabel;
    Izm_gen_num: TLabel;
    Izm_pat_id: TLabel;
    Label7: TLabel;
    izm_mes_tek_count: TLabel;
    Label9: TLabel;
    izm_mes_count: TLabel;
    izm_device_result_LB: TListView;
    izm_device_program_LB: TListView;
    Label8: TLabel;
    Label10: TLabel;
    izm_U_mis: TLabel;
    izm_I_mis: TLabel;
    Panel5: TPanel;
    Izm_DS: TDataSource;
    Label12: TLabel;
    izm_point_opis: TLabel;
    izm_point_num: TLabel;
    Label1: TLabel;
    Label13: TLabel;
    izm_point_name: TLabel;
    IzmPB: TAdvProgressBar;
    IzmTimer: TTimer;
    Label11: TLabel;
    izm_opisanie_edit: TEdit;
    IzmGraphFrame1: TIzmGraphFrame;
    procedure FormCreate(Sender: TObject);
    procedure izm_next_pointExecute(Sender: TObject);
    procedure izm_prev_pointExecute(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure izm_manual_switchClick(Sender: TObject);
    procedure Izm_stop_btnClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormKeyPress(Sender: TObject; var Key: Char);
    procedure IzmTimerTimer(Sender: TObject);
    function measure_default_initialization(in_measure: TRDMeasure):boolean;
  private
    { Private declarations }
  public
    measure: TRDMeasure;

    points_name_array: array [1..24] of string;
    points_array: array [1..24] of string;

    procedure incoming_message(message_:params_record; point,povtor:integer);
    procedure load_data_to_database(izm_result:TIzmResult);
    function get_string(data:TIzm_array):string;
    procedure load_picture(num:integer);
  end;

var
  IzmForm: TIzmForm;
  pict_num,
  povrot_num:integer;


implementation

uses ConstUnit, MainUnit, DataUnit, device_thread, D2XXUnit;

{$R *.dfm}
procedure TIzmForm.load_picture(num: Integer);
var stream:TMemoryStream;
i:integer;
begin
SQL_DM.mysql_DSQ3.DataSet.Open;
SQL_DM.mysql_DSQ3.DataSet.First;

//Перемотка датасета 
if num>1 then for i:=2 to num do SQL_DM.mysql_DSQ3.DataSet.Next;

try
  Izm_point_picture.Picture:=nil;

  stream := TMemoryStream.Create;

  (SQL_DM.mysql_DSQ3.DataSet.fieldbyname('image') as TBlobField).SaveToStream(stream);
  {чтобы что-нибудь записать, необходимо установить позицию потока в ноль!}
  Stream.Position:= 0;
  Izm_point_picture.Picture.LoadFromStream(stream);
  stream.Free;
except
end;
if Izm_point_picture.Picture<>nil then Izm_point_picture.Show;
SQL_DM.mysql_DSQ3.DataSet.close;
end;

function TIzmForm.measure_default_initialization (in_measure: TRDMeasure): boolean;
var inserted_num: integer;
    Params: TRDParamList;
    models: TRDModelList;
begin
  with in_measure do
  begin
    //грузим модели, пока просто вручную
    models := TRDModelList.Create;
    models.Add( TRDModel.Create( 'Нелинейная 3-х компонентная', '') );

    //грузим параметры для каждой из точек
    mysql_query(SQL_DM.mysql_query3, 'SELECT name, opisanie FROM ' + table_param_name + ';', 1);
    SQL_DM.mysql_query3.Open;
    SQL_DM.mysql_query3.First;
    params := TRDParamList.Create;
    while ( not SQL_DM.mysql_query3.Eof ) do
    begin
      //создаем параметры
      params.Add (
                   TRDParam.Create( SQL_DM.mysql_query3.FieldByName( 'name' ).AsString,
                                    SQL_DM.mysql_query3.FieldByName( 'opisanie' ).AsString
                                  )
                 );
      //присваиваем модели параметрам
      params.Get_current_param.models := models;
      SQL_DM.mysql_query3.Next;
    end;

    // получаем из базы все точки и создаем массив точек
    mysql_query( SQL_DM.mysql_query3, 'SELECT num, name, opisanie, image FROM ' + table_points_name + ';', 1 );
    SQL_DM.mysql_query3.Open;
    SQL_DM.mysql_query3.First;
    while ( not SQL_DM.mysql_query3.Eof ) do
    begin
      //создаем точку, изображение грузится в автомате
      point_values.Add(
                        TRDPoint.Create( SQL_DM.mysql_query3.FieldByName( 'name' ).AsString,
                                         SQL_DM.mysql_query3.FieldByName( 'opisanie' ).AsString
                                       )
                      );
      // присваиваем полученные параметры точке
      point_values.Get_current_point.Params := params;
      SQL_DM.mysql_query3.Next;
    end;
  end;
end;

///для создания строки из значений тока и напряжения
///в настоящий момент не используется
function TIzmForm.get_string(data: TIzm_array):string;
var i:integer;
    tmp:string;
begin
result:='';
for i:=0 to 2400 do
begin
tmp:=floattostr(data[i]);
if strlen(PChar(tmp))<>3 then
  if strlen(PChar(tmp))=1 then tmp:='00'+tmp else
  if strlen(PChar(tmp))=2 then tmp:='0'+tmp;
result:=result+tmp;
end;
end;

procedure TIzmForm.incoming_message(message_:params_record; point,povtor:integer);
begin
// Показываем результаты расчета
//добавить результаты с программы
izm_device_result_LB.Items[0].SubItems.Clear;
izm_device_result_LB.Items[0].SubItems.Add(floattostrf(message_.R, ffExponent, 4, 2));
izm_device_result_LB.Items[1].SubItems.Clear;
izm_device_result_LB.Items[1].SubItems.Add(floattostrf(message_.g0, ffExponent, 4, 2));
izm_device_result_LB.Items[2].SubItems.Clear;
izm_device_result_LB.Items[2].SubItems.Add(floattostrf(message_.g1, ffExponent, 4, 2));
izm_device_result_LB.Items[3].SubItems.Clear;
izm_device_result_LB.Items[3].SubItems.Add(floattostrf(message_.g2, ffExponent, 4, 2));
izm_device_result_LB.Items[4].SubItems.Clear;
izm_device_result_LB.Items[4].SubItems.Add(floattostrf(message_.g3, ffExponent, 4, 2));
izm_device_result_LB.Items[5].SubItems.Clear;
izm_device_result_LB.Items[5].SubItems.Add(floattostrf(message_.C, ffExponent, 4, 2));
izm_device_result_LB.Items[6].SubItems.Clear;
izm_device_result_LB.Items[6].SubItems.Add(floattostrf(message_.Usm, ffExponent, 4, 2));

//добавить результаты с прибора
izm_device_program_LB.Items[0].SubItems.Clear;
izm_device_program_LB.Items[0].SubItems.Add(floattostrf(message_.R_e, ffExponent, 4, 2));
izm_device_program_LB.Items[1].SubItems.Clear;
izm_device_program_LB.Items[1].SubItems.Add(floattostrf(message_.g0_e, ffExponent, 4, 2));
izm_device_program_LB.Items[2].SubItems.Clear;
izm_device_program_LB.Items[2].SubItems.Add(floattostrf(message_.g1_e, ffExponent, 4, 2));
izm_device_program_LB.Items[3].SubItems.Clear;
izm_device_program_LB.Items[3].SubItems.Add(floattostrf(message_.g2_e, ffExponent, 4, 2));
izm_device_program_LB.Items[4].SubItems.Clear;
izm_device_program_LB.Items[4].SubItems.Add(floattostrf(message_.g3_e, ffExponent, 4, 2));
izm_device_program_LB.Items[5].SubItems.Clear;
izm_device_program_LB.Items[5].SubItems.Add(floattostrf(message_.C_e, ffExponent, 4, 2));
izm_device_program_LB.Items[6].SubItems.Clear;
izm_device_program_LB.Items[6].SubItems.Add(floattostrf(message_.Usm_e, ffExponent, 4, 2));
//Показываем результаты ошибок
if message_.U_mis
then begin
  izm_U_mis.Visible:=TRUE;
  //если была ошибка, то обнуляем результаты
  if MainForm.Izm_null_result_CB.Checked then
    begin
      message_.R:=0;
      message_.C:=0;
      message_.g0:=0;
      message_.g1:=0;
      message_.g2:=0;
      message_.g3:=0;
      message_.R_e:=0;
      message_.C_e:=0;
      message_.g0_e:=0;
      message_.g1_e:=0;
      message_.g2_e:=0;
      message_.g3_e:=0;
      message_.Usm_e:=0;
      message_.Ism_e:=0;
      message_.Usm:=0;
      message_.Ism:=0;
    end;
end
  else izm_U_mis.Visible:=FALSE;
if message_.I_mis then
begin
  izm_I_mis.Visible:=TRUE;
  //если была ошибка, то обнуляем результаты
  if MainForm.Izm_null_result_CB.Checked then
    begin
      message_.R:=0;
      message_.C:=0;
      message_.g0:=0;
      message_.g1:=0;
      message_.g2:=0;
      message_.g3:=0;
      message_.R_e:=0;
      message_.C_e:=0;
      message_.g0_e:=0;
      message_.g1_e:=0;
      message_.g2_e:=0;
      message_.g3_e:=0;
      message_.Usm_e:=0;
      message_.Ism_e:=0;
      message_.Usm:=0;
      message_.Ism:=0;
    end;
end
else izm_I_mis.Visible:=FALSE;
end;

procedure TIzmForm.IzmTimerTimer(Sender: TObject);
begin
IzmPB.Position:=IzmPB.Position+3;
end;

procedure TIzmForm.load_data_to_database(izm_result: TIzmResult);
begin
//
end;



procedure TIzmForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
// уничтожили поток
    MainForm.device.Close_thread;
// уничтожаем объект измерения
    self.measure.Free;

//закрыли устройство
    //MainForm.device.Close_usb;

end;

procedure TIzmForm.izm_manual_switchClick(Sender: TObject);
begin
if MainForm.izm_manual_switch.Checked then begin
  if ( pict_num <> 1 ) then
       Izm_prev_point_btn.Enabled := TRUE;
  if ( pict_num <> 24 ) then
       Izm_next_point_btn.Enabled := TRUE;
end
else
begin
       Izm_prev_point_btn.Enabled := FALSE;
       Izm_next_point_btn.Enabled := FALSE;
end;

end;

procedure TIzmForm.FormCreate(Sender: TObject);
var i:integer;
begin


//загрузка точек
  mysql_query(SQL_DM.mysql_query3, 'SELECT name, opisanie, image FROM '+table_points_name+';', 1);

  SQL_DM.mysql_query3.Open;
  SQL_DM.mysql_query3.First;
  i := 0;
  while ( not Izm_DS.DataSet.Eof ) do
  begin
   points_name_array[ i ] := SQL_DM.mysql_query3.FieldByName( 'name' ).AsString;
   points_array[ i ] := SQL_DM.mysql_query3.FieldByName( 'opisanie' ).AsString;
   inc( i );
   SQL_DM.mysql_query3.next;
  end;

with izm_device_result_LB do
  begin
  Items.Add();
  Items[ 0 ].Caption := params_default_name3;

  Items.Add();
  Items[ 1 ].Caption := params_default_name4;

  Items.Add();
  Items[ 2 ].Caption := params_default_name5;

  Items.Add();
  Items[ 3 ].Caption := params_default_name6;

  Items.Add();
  Items[ 4 ].Caption := params_default_name7;

  Items.Add();
  Items[ 5 ].Caption := params_default_name8;

  Items.Add();
  Items[ 6 ].Caption := params_default_name9;
  end;
with izm_device_program_LB do
  begin
  Items.Add();
  Items[0].Caption:=params_default_name3;

  Items.Add();
  Items[1].Caption:=params_default_name4;

  Items.Add();
  Items[2].Caption:=params_default_name5;

  Items.Add();
  Items[3].Caption:=params_default_name6;

  Items.Add();
  Items[4].Caption:=params_default_name7;

  Items.Add();
  Items[5].Caption:=params_default_name8;

  Items.Add();
  Items[6].Caption:=params_default_name9;
end;
Izm_DS.DataSet.Close;
end;

procedure TIzmForm.FormKeyPress(Sender: TObject; var Key: Char);
begin
if ( key = #13 ) then IzmForm.izm_next_point.Execute;
end;

procedure TIzmForm.FormShow(Sender: TObject);
begin
// Создаем измерение
  self.measure := TRDMeasure.Create;
  measure_default_initialization(measure);


//device_thread.TTH.Resume;
//Панель информации
  // Фамилия Имя Отчество
  Izm_patient_name.Caption:=MainForm.patient.Get_current_patient_sirname + ' ' +
                            MainForm.patient.Get_current_patient_first_name + ' ' +
                            MainForm.patient.Get_current_patient_middle_name;

  measure.Set_measure_patient_info(MainForm.patient.Get_current_patient_ID,
                                   MainForm.patient.Get_current_patient_sirname,
                                   MainForm.patient.Get_current_patient_first_name,
                                   MainForm.patient.Get_current_patient_middle_name );

  // дата и время измерения
  Izm_date.Caption := datetostr( date () );

  Izm_pat_num.Caption:=inttostr( strtoint( MainForm.patient.Get_current_patient_measure_count ) + 1 );

  // глобальный номер текущего измерения
  mysql_query(SQL_DM.mysql_query1, 'SELECT MAX(id) FROM `'+table_izm_name+'`;',1);
  Izm_gen_num.Caption:=inttostr( SQL_DM.mysql_DSQ1.DataSet.FieldByName('MAX(id)').AsInteger + 1 );

  //ID пациента
  Izm_pat_id.Caption := MainForm.patient.Get_current_patient_ID;


  measure.Set_measure_info( inttostr( SQL_DM.mysql_DSQ1.DataSet.FieldByName('MAX(id)').AsInteger + 1 ),
                            datetostr( date () ),
                            IZM_UNIT_MEASURMENT_LABEL + datetostr( today () ) + ' ' + timetostr( time() )
                          );


  measure.point_values.First_point;

// обнуление параметров формы

  izm_mes_count.Caption:=inttostr( device_thread.num );
  izm_mes_tek_count.Caption := '0';
  izm_mes_count.Caption := '0';

  device_thread.povtor := 0;
  device_thread.point := 1;
  device_thread.num := 0;

  pict_num := 1;
  izm_point_num.Caption := inttostr( pict_num );
  load_picture( 1 );

Izm_progress_bar.Position:=round(100/25*(pict_num-1));

Izm_stop_btn.Caption := izm_stop_measurement;
  //Время измерения
  izm_opisanie_edit.Text := IZM_UNIT_MEASURMENT_LABEL
                            +datetostr(today())+' '+timetostr(time());
Izm_next_point_btn.Enabled:=TRUE;
Izm_prev_point_btn.Enabled:=FALSE;

izm_point_opis.Caption:=points_array[1];
izm_point_name.Caption:=points_name_array[1];

IzmPB.Position:=0;
IzmTimer.Enabled:=FALSE;
//Состояние прибора
Purge_USB_Device_In;
Purge_USB_Device_Out;
Reset_USB_Device;

 /// заносим нулевые значения в базу, потом только обновление

end;

procedure TIzmForm.izm_next_pointExecute(Sender: TObject);
begin
if pict_num+1<25 then
  begin
    load_picture(pict_num+1);
    Izm_progress_bar.Position:=round(100/24*(pict_num+1));
    Izm_prev_point_btn.Enabled:=TRUE;
    izm_point_num.Caption:=inttostr(pict_num+1);

    izm_point_opis.Caption:=points_array[pict_num+1];
    izm_point_name.Caption:=points_name_array[pict_num+1];
    
    inc(pict_num);
  end;
if pict_num+1=25 then begin
      Izm_progress_bar.Position:=100;
      Izm_next_point_btn.Enabled:=FALSE;
     end;

izm_mes_tek_count.Caption:='0';

device_thread.povtor:=0;
device_thread.point:=pict_num;
end;

procedure TIzmForm.izm_prev_pointExecute(Sender: TObject);
begin
if ( ( pict_num - 1 ) > 0 ) then
  begin
    load_picture( pict_num - 1 );
    Izm_progress_bar.Position := round( 100 / 24 * ( pict_num - 1 ) );
    Izm_next_point_btn.Enabled := TRUE;
    izm_point_num.Caption := inttostr( pict_num - 1 );

    izm_point_opis.Caption := points_array[ pict_num - 1 ];
    izm_point_name.Caption := points_name_array[ pict_num - 1 ];

    dec( pict_num );
  end;
if pict_num-1=0 then begin
      Izm_progress_bar.Position:=round(100/24*(pict_num));
      Izm_prev_point_btn.Enabled:=FALSE;
     end;
izm_mes_tek_count.Caption:='0';

device_thread.povtor:=0;
device_thread.point:=pict_num;
end;

procedure TIzmForm.Izm_stop_btnClick(Sender: TObject);
begin
if MessageBox(0,
              PChar(izm_data_lost),
              PChar(izm_caption_message),
              MB_ICONQUESTION or MB_OKCANCEL
              )=id_OK then
begin
self.Close;
end;
end;

end.
