//
//
//
//			POSNET BASE EXAMPLES
//			EXAMPLE FOR MODEM
//
//

#include <stdlib.h>
#include <string>
#include <iostream>
#include <istream>
#include <limits>
#ifdef WIN32
#include <windows.h>
#else
#include <signal.h>
#define INFINITE 0xFFFFFFFF
#define Sleep(a) {struct timespec tc,tc1;\
		  long k=a;\
		  if (k<1000)\
		  {\
		    tc.tv_sec=0; \
		    tc.tv_nsec=k*1000*1000; \
		    nanosleep(&tc,&tc1);	\
		  }\
		  else\
		  {\
		    tc.tv_sec=(k/1000);\
		    tc.tv_nsec=(k%1000)*1000*1000; \
		    nanosleep(&tc,&tc1);	\
		  }\
		 }	
#endif
#include "../../include/posnet.h"
#include "../../include/posnet_cmdid.h"
#include "../../include/posnet_hlapi.h"

using namespace std;



int main(int argc, char *argv[])
{

#ifdef WIN32
	WSADATA WSAData;
	if (WSAStartup (MAKEWORD(2,0), &WSAData) != 0) 
	{
		MessageBox (NULL, TEXT("WSAStartup failed!"), TEXT("Error"), MB_OK);
		return FALSE;
	}

 #endif
 
/*
		COMMON SETUP
*/

unsigned long type=POSNET_INTERFACE_RS232;
	void *hDevice=NULL;
	string ip="10.33.44.6";
	string usbser="";
	string atinit="AT&S0=0"; // test string
	string atdial="ATDT!"; // just flash dial
	int dial=0;
#ifdef WIN32
	string comparams="COM1,57600,8,N,1,H";
#else
	string comparams="/dev/ttyS0,57600,8,N,1,H";
#endif
	if (argc>1)
	{
		if (string(argv[1])==string("DIAL")) dial=1;
		if (argc>=3)
			comparams=argv[2];
		if (argc>=4)
			atdial=argv[3];
		if (argc>=5)
			atinit=argv[4];
	}
	else
	{
		cout << "Usage: demo_modem [[DIAL|RECEIVE] [com_settings [modem_dial_string [modem_init_string]]]] \n";
		cout << "Defaults to RECEIVE. Default params : com_settings = COM1,57600,8,N,1,H  modem_dial_string=ATDT! modem_init_string=AT&S0=0" << endl;
		return 1;
	}

#ifndef _WIN32
	signal (SIGIO, SIG_IGN);
	signal (SIGTTOU, SIG_IGN);
#endif

	hDevice=POS_CreateDeviceHandle(type);
	if (!hDevice)
	{
		cout << "Could not create a device." << endl;
		return 2;
	}
	POS_SetDebugLevel(hDevice,POSNET_DEBUG_ALL & 0xFFFFFFFE);

	POS_SetDeviceParam(hDevice,POSNET_DEV_PARAM_COMSETTINGS,(void*)comparams.c_str());
	POS_SetDeviceParam(hDevice,POSNET_DEV_PARAM_MODEMINIT,(void*)atinit.c_str());
	POS_SetDeviceParam(hDevice,POSNET_DEV_PARAM_MODEMDIAL,(void*)atdial.c_str());
	unsigned char c=1;
	POS_SetDeviceParam(hDevice,POSNET_DEV_PARAM_MODEMMODE,(void*)&c);
	
	void *hLocalDevice=POS_OpenDevice(hDevice);
	if (!hLocalDevice)
	{
		POSNET_STATUS code=POS_GetError(hDevice);
		char *c=(char*)POS_GetErrorString(code,"pl");
		cout << "Error Opening device: 0x" << hex << code << dec << " " ;
		if (c) cout << c;
		cout  <<endl;
		return 4;
	}
	if (dial)
	{
		// dial
		if (POS_ModemDial(hDevice,1)!=POSNET_STATUS_OK)
		{
			POSNET_STATUS code=POS_GetError(hDevice);
			char *c=(char*)POS_GetErrorString(code,"pl");
			cout << "Error Dialing device: 0x" << hex << code << dec << " " ;
			if (c) cout << c;
			cout  <<endl;
			POS_CloseDevice(hLocalDevice);
			POS_DestroyDeviceHandle(hDevice);
			return 4;
		}
	}
	else
	while (POS_ModemStatus(hDevice)!=POSNET_STATUS_MODEM_CONNECTED)
	{
		Sleep(1000);
	}


	POSNET_HANDLE hRequest;

	// Przygotowanie polecenia
	// Numer polecenia DSPPARAMGET = 101
	hRequest = POS_CreateRequest(hLocalDevice,POSNET_CMDID_DSPPARAMGET);

	// Przygotowanie parametrów polecenia
	// Pobierz dane dla wyświetlacza operatora
	// Wymagany 1 paramter typu 'B' o wartości 0
	POS_PushRequestParamByte(hRequest,0);

	// Wyślij rozkaz do kasy w trybie interaktywnym
	POS_PostRequest(hRequest,POSNET_REQMODE_IMMEDIATE);

	int time=0;
	while (POS_ModemStatus(hDevice)==POSNET_STATUS_MODEM_CONNECTED)
	{
		// Oczekuj na wykonanie
		POS_WaitForRequestCompleted(hRequest,5000);
		time++;
		if (time==5) // 25 seconds is our timeout 
			break;
	}
	// Sprawdź czy zakończyło się sukcesem
	if (POS_GetRequestStatus(hRequest) == POSNET_STATUS_OK)
	{
		// Pobranie wyników, polecenie zwraca 3 wartości typu byte
		unsigned char kontrast,podswietlenie,tryb;
		POS_PopResponseValueByte(hRequest,&kontrast);
		POS_PopResponseValueByte(hRequest,&podswietlenie);
		POS_PopResponseValueByte(hRequest,&tryb);
		cout << "Kontrast: " << (int)kontrast << " Podswietlenie: " << (int)podswietlenie << " Tryb: " << (int)tryb << endl;
	}

	// Usuń stworzone zapytanie
	POS_DestroyRequest(hRequest);

	if (POS_ModemDisconnect(hDevice,1)!=POSNET_STATUS_OK)
	{
		POSNET_STATUS code=POS_GetError(hDevice);
		char *c=(char*)POS_GetErrorString(code,"pl");
		cout << "Error Dialing device: 0x" << hex << code << dec << " " ;
		if (c) cout << c;
		cout  <<endl;
	}

	POS_CloseDevice(hLocalDevice);
	POS_DestroyDeviceHandle(hDevice);
	return 0;
}
