// Copyright  1999 Production Robots Eng Ltd
//
// PROGRAM: Lcictest.c Test and demonstrate LCIC card under windows NT

#define APPNAME "Lcictest"

#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

#include "resource.h"

// prototypes for LCIC functions
// you must call LoadLoaccellLibrary() and check the result
// before you can call any of the function pointers declared
// in lciclink.h. Loadcell.dll must be on your dll search path at
// runtime. Proper location for loadcell.dll is C:\Winnt\System32

#include "lciclink.h"

// Global Variables:

HINSTANCE hInst;      // current instance
char szAppName[] = APPNAME; // Name of the app

LONG  TestLoops = 1000;
HANDLE  DriverHandle = INVALID_HANDLE_VALUE;
HWND  hWindow;

#define DriverOpen (DriverHandle != INVALID_HANDLE_VALUE)

typedef struct _INPUTBOX_PARAMS {
	PCHAR Caption;
	PCHAR Prompt;
	PCHAR Buf;
	DWORD MaxBuf;
} INPUTBOX_PARAMS, *PINPUTBOX_PARAMS;


static BOOL WINAPI InputProc(
				HWND hDlg,
				UINT uMsg,
				WPARAM wParam,
				LPARAM lParam) {
	PINPUTBOX_PARAMS Params;
  	switch (uMsg) {
	case WM_INITDIALOG:
		SetWindowLong(hDlg, GWL_USERDATA, lParam);
		Params = (PINPUTBOX_PARAMS)lParam;
		SetWindowText(hDlg, Params->Caption);
		SetWindowText(GetDlgItem(hDlg, id_InputPrompt), Params->Prompt);
		SetWindowText(GetDlgItem(hDlg, id_InputText), Params->Buf);
		return TRUE;
	case WM_COMMAND:
		switch LOWORD(wParam) {
		case IDOK:
			Params = (PINPUTBOX_PARAMS)GetWindowLong(hDlg, GWL_USERDATA);
			GetWindowText(GetDlgItem(hDlg, id_InputText), Params->Buf, Params->MaxBuf);
			EndDialog(hDlg, 1);
		return TRUE;
		case IDCANCEL:
			EndDialog(hDlg, 0);
			return TRUE;
		}
	}
	return FALSE;
}

static BOOL InputQuery(PCHAR Caption, PCHAR Prompt, PCHAR Buf, DWORD MaxBuf) {
	INPUTBOX_PARAMS P;
	P.Caption = Caption;
	P.Prompt = Prompt;
	P.Buf = Buf;
	P.MaxBuf = MaxBuf;
	return (BOOL)DialogBoxParam(hInst, "INPUTBOX", hWindow, InputProc, (LONG)(&P));
}


static BOOL check_driver(void) {
	if (!DriverOpen) {
		MessageBox(hWindow, "Driver must be opened to carry out this operation", 
			"Error", MB_OK | MB_ICONEXCLAMATION);
		return FALSE;
	} else {
		return TRUE;
	}
}


static void IDOpenDriver(void) {
	HWND hButton = GetDlgItem(hWindow, id_OpenDriver);
	if (!DriverOpen) {
		SetWindowText(hButton, "Opening...");
		UpdateWindow(hButton);
		DriverHandle = LCICOpen("LCIC1");
		if (DriverOpen) {
			SetWindowText(hButton, "&Close Driver");
			if (LCICInit(DriverHandle)) 
				MessageBox(hWindow, "Initialised OK", "Information", MB_OK | MB_ICONINFORMATION);
			else
				MessageBox(hWindow, "Could not initialise card", 
					"Error", MB_OK | MB_ICONEXCLAMATION);
		} else {
			SetWindowText(hButton, "&Open Driver");
			MessageBox(hWindow, "Could not open driver. Loadcell.sys must be installed and started", 
				"Error", MB_OK | MB_ICONEXCLAMATION);
		}
	} else {
		LCICDone(DriverHandle);
		LCICClose(DriverHandle);
		SetWindowText(hButton, "&Open Driver");
		DriverHandle = INVALID_HANDLE_VALUE;
	}
}

void IDReadDriver(void) {
	FLOAT Val;
	char MsgBuf[0x100];
	DWORD tc;
	if (!check_driver()) return;
	tc = GetTickCount();
	if (LCICRead(DriverHandle, &Val)) {
		sprintf(MsgBuf, "%.3f took %d ms", Val, GetTickCount() - tc);
	} else {
		strcpy(MsgBuf, "read error");
	}
	SetWindowText(GetDlgItem(hWindow, id_FloatLabel), MsgBuf);
}

void IDTestDriver(void) {
	char Buf[0x100];
	FLOAT Val;
	int i;
	DWORD gtc;
	HWND hTestLabel = GetDlgItem(hWindow, id_TestLabel);
	if (!check_driver) return;
	
	_itoa(TestLoops, Buf, 10);

	if (InputQuery("Speed Test", "Please enter number of read loops", Buf, 0xFF)) {
		TestLoops = atol(Buf);
		if (!TestLoops) {
			sprintf(Buf, "%s is not a valid input", Buf);
			MessageBox(hWindow, Buf, "Error", MB_OK | MB_ICONERROR);
			return;
		}
		SetWindowText(hTestLabel, "Testing. Please wait");
		UpdateWindow(hTestLabel);
		gtc = GetTickCount();
		for (i = 0; i < TestLoops; i++) {
			if (!LCICRead(DriverHandle, &Val)) break;
		}
		if (i) {
			Val = ((FLOAT)(GetTickCount() - gtc)) / i;
			sprintf(Buf, "%d reads at %.2f ms per read", i, Val);
			SetWindowText(hTestLabel, Buf);
		}
	}
}

void IDSetupDriver(void) {
	LCICSetup(hWindow, "LCIC1");
}


LRESULT CALLBACK WindowProc( HWND hWindow,
                        UINT iMsg,
						WPARAM wParam,
						LPARAM lParam) {
	switch (iMsg) {
    case WM_COMMAND:
		switch LOWORD(wParam) {
        case id_OpenDriver: 
			IDOpenDriver();
			return 0;
        case id_ReadDriver: 
			IDReadDriver();
			return 0;
        case id_TestDriver: 
			IDTestDriver();
			return 0;
		case id_SetupDriver:
			IDSetupDriver();
			return 0;
        case IDCANCEL: 
			SendMessage(hWindow, WM_CLOSE, 0, 0);
			return 0;
		}
	case WM_CLOSE: 
		LCICClose(DriverHandle);
		break;

    case WM_DESTROY: 
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWindow, iMsg, wParam, lParam);
}

int WINAPI WinMain (
	HINSTANCE hInstance, 
	HINSTANCE hPrevInstance,
	PSTR szCommandLine,
	int iCmdShow) {
	HINSTANCE LoadcellLib; //handle to library instance
	MSG msg;
	WNDCLASSEX wc;
	LoadcellLib = LoadLoadcellLibrary();
	if (!LoadcellLib) {
   		MessageBox(NULL, "Cannot open loadcell library",
      	              "Error", MB_OK | MB_ICONEXCLAMATION);
		return 1;
	}
    wc.cbSize = sizeof(wc);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = DLGWINDOWEXTRA;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, ICONNAME);
    wc.hCursor = LoadCursor(0, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = szAppName;
    wc.hIconSm = LoadIcon(hInstance, ICONNAME);
	RegisterClassEx(&wc);
	hInst = hInstance;
	hWindow = CreateDialog( hInstance, szAppName, 0, NULL);
	ShowWindow(hWindow, iCmdShow);
	while (GetMessage(&msg, 0, 0, 0)) {
		IsDialogMessage(hWindow, &msg);
		//TranslateMessage(&msg);
		//DispatchMessage(&msg);
	}
	return msg.wParam;
}

