program LCICTest;

uses
  Messages,
  Windows,
  SysUtils,
  Loadcell in 'Loadcell.pas';

{$R lcic.res}
{$I lcictest.Inc}

const
  IconName: PChar = 'MAINICON';
  AppName: PChar = 'LCICTEST';

var
  TestLoops: Integer = 1000;
  hDriver: THandle = INVALID_HANDLE_VALUE;
  hWindow: HWND;

type
  PInputBoxParams = ^TInputBoxParams;
  TInputBoxParams =
  record
    Caption, Prompt, Value: String;
  end;

function InputProc(
    hDlg: HWND;
    uMsg: UINT;
    wParam: WPARAM;
    lParam: LPARAM): BOOL; stdcall;
var
  Params: PInputBoxParams absolute lParam;
  Buf: array[0..255] of Char;
begin
  case uMsg of
    WM_INITDIALOG:
    begin
      SetWindowLong(hDlg, GWL_USERDATA, lParam);
      SetWindowText(hDlg, PChar(Params^.Caption));
      SetWindowText(GetDlgItem(hDlg, id_InputPrompt), PChar(Params^.Prompt));
      SetWindowText(GetDlgItem(hDlg, id_InputText), PChar(Params^.Value));
      Result:= true;
    end;
    WM_COMMAND:
    case Lo(wParam) of
      IDOK:
      begin
        lParam:= GetWindowLong(hDlg, GWL_USERDATA);
        GetWindowText(GetDlgItem(hDlg, id_InputText), Buf, SizeOf(Buf) - 1);
        Params.Value:= Buf;
        EndDialog(hDlg, 1);
        Result:= true
      end;
      IDCANCEL:
      begin
        EndDialog(hDlg, 0);
        Result:= true
      end
    else
      Result:= false
    end;
  else
    Result:= false
  end
end;


function InputQuery(const ACaption, APrompt: string;
  var Value: string): Boolean;
var
  P: TInputBoxParams;
begin
  P.Caption:= aCaption;
  P.Prompt:= aPrompt;
  P.Value:= Value;
  Result:= Boolean(DialogBoxParam(System.MainInstance,
    'INPUTBOX', hWindow, @InputProc, Integer(@P)));
  if Result then
    Value:= P.Value
end;

procedure IDOpenDriver;
var
  hButton: HWND;
begin
  hButton:= GetDlgItem(hWindow, id_OpenDriver);
  if hDriver = INVALID_HANDLE_VALUE then
  begin
    SetWindowText(hButton, 'Opening...');
    UpdateWindow(hButton);
    hDriver:= LCICOpen('LCIC1');
    if hDriver <> INVALID_HANDLE_VALUE then
    begin
      SetWindowText(GetDlgItem(hWindow, id_OpenDriver), '&Close Driver');
      if LCICInit(hDriver) then
        MessageBox(hWindow, 'Initialised OK', 'Information', MB_OK or MB_ICONINFORMATION)
      else
        MessageBox(hWindow, 'Could not intialise card', 'Error', MB_OK or MB_ICONEXCLAMATION)
    end else
    begin
      SetWindowText(GetDlgItem(hWindow, id_OpenDriver), '&Open Driver');
      MessageBox(hWindow, 'Could not open driver', 'Error', MB_OK or MB_ICONEXCLAMATION)
    end
  end else
  begin
    LCICDone(hDriver);
    LCICClose(hDriver);
    SetWindowText(GetDlgItem(hWindow, id_OpenDriver), '&Open Driver');
    hDriver:= INVALID_HANDLE_VALUE;
  end
end;

procedure IDReadDriver;
var
  Val: Single;
  Msg: String;
  tc: DWORD;
begin
  tc:= GetTickCount;
  if LCICRead(hDriver, Val) then
    Msg:= FloatToStrF(Val, ffFixed, 6, 0)
  else
    Msg:= 'read error';
  Msg:= Msg + ' tc ' + IntToStr(GetTickCount - tc);
  SetWindowText(GetDlgItem(hWindow, id_FloatLabel), PChar(Msg))
end;

procedure IDTestDriver;
var
  Inp: String;
  Val: Single;
  i: Integer;
  gtc: DWORD;
  hTestLabel: HWND;
begin
  Inp:= IntToStr(TestLoops);
  if InputQuery('Speed Test', 'Please enter number of read loops', Inp) then
  begin
    hTestLabel:= GetDlgItem(hWindow, id_TestLabel);
    try
      TestLoops:= StrToInt(Inp);
      SetWindowText(hTestLabel, 'Testing. Please wait');
      UpdateWindow(hTestLabel);
      gtc:= GetTickCount;
      for i:= 0 to TestLoops - 1 do
      if not LCICRead(hDriver, Val) then
        RaiseLastWin32Error;
      Val:= (GetTickCount - gtc)/TestLoops;
      SetWindowText(hTestLabel,
         PChar(Format('%d reads at %.3f ms per read', [TestLoops, Val])));
    except
      on EConvertError do
        MessageBox(hWindow, PChar(Format('%s is not a valid integer', [Inp])),
                 'Error', MB_OK or MB_ICONERROR)
    end
  end
end;

procedure IDSetup;
begin
  LCICSetup(hWindow, 'LCIC1')
end;

function WindowProc( hWindow: HWND;
                        iMsg: UINT;
                   WordParam: WPARAM;
                   LongParam: LPARAM): LRESULT; stdcall;
begin
  Result:= 0;
  case iMsg of
    WM_COMMAND:
    begin
      case Lo(WordParam) of
        id_OpenDriver: IDOpenDriver;
        id_ReadDriver: IDReadDriver;
        id_TestDriver: IDTestDriver;
        id_Setup: IDSetup;
        IDCANCEL: SendMessage(hWindow, WM_CLOSE, 0, 0);
      end;
    end;
    WM_CLOSE:
    begin
      LCICClose(hDriver);
      Result:= DefWindowProc(hWindow, iMsg, WordParam, LongParam)
    end;
    WM_DESTROY: PostQuitMessage(0);
  else
    Result:= DefWindowProc(hWindow, iMsg, WordParam, LongParam);
  end
end;

procedure InitApp;
var
  WndClass: TWndClassEx;
begin
  with WndClass do
  begin
    cbSize:= SizeOf(WndClass);
    Style:= CS_HREDRAW or CS_VREDRAW;
    lpfnWndProc:= @WindowProc;
    cbClsExtra:= 0;
    cbWndExtra:= DLGWINDOWEXTRA;
    hInstance:= System.MainInstance;
    hIcon:= LoadIcon(System.MainInstance, IconName);
    hCursor:= LoadCursor(0, IDC_ARROW);
    hbrBackground:= HBRUSH(COLOR_WINDOW);
    lpszMenuName:= nil;
    lpszClassName:= AppName;
    hIconSm:= LoadIcon(System.MainInstance, IconName);
  end;
  RegisterClassEx(WndClass)
end;

var
  Msg: TMsg;
begin
  InitApp;
  hWindow:= CreateDialog( System.MainInstance, AppName, 0, nil);
  ShowWindow(hWindow, System.CmdShow);
  while GetMessage(Msg, 0, 0, 0) do
  if not IsDialogMessage(hWindow, Msg) then
  begin
    TranslateMessage(Msg);
    DispatchMessage(Msg)
  end
end.


