//
//
//
//			POSNET BASE EXAMPLES
//			EXAMPLE DIFFERENT REQUEST HANDLING
//
//

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

using namespace std;

	/*
		UWAGA: W tym przykładzie obsługę błędów zmiejszono do minimum
		dla czytelności pozostałej części kodu - proszę skorzystać z 
		programu demo_all dla zapoznania się z pełniejszą obsługą błędów.
	*/

/*

1. Paragon - Tryb SPOOL, z oczekiwaniem na zakończenie

*/

void SpoolSendReceipt(POSNET_HANDLE hGlobalDevice, POSNET_HANDLE hLocalDevice)
{
	int cancel=1;
	POSNET_HANDLE hRequest;
	do
	{
		hRequest = POS_CreateRequest(hLocalDevice,"trinit");
		if (!hRequest)
		{
				printf("POS_CreateRequest status: %d",POS_GetError(hLocalDevice));
				break;		
		}

		POS_PushRequestParam(hRequest,"bm","1");
		POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);

		if (POS_WaitForRequestCompleted(hRequest,5000)!=POSNET_STATUS_OK) break;

		if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) break;
		
		POS_DestroyRequest(hRequest);
		
		hRequest = POS_CreateRequestEx(hLocalDevice,"trline","na,Bułka Standardowa\nvt,0\npr,35");
			
		if (!hRequest)
		{
				printf("POS_CreateRequestEx status: %d",POS_GetError(hLocalDevice));
				break;		
		}
		POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);
		if (POS_WaitForRequestCompleted(hRequest,5000)!=POSNET_STATUS_OK) break;
		if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) break;

		POS_DestroyRequest(hRequest);

		hRequest = POS_CreateRequestEx(hLocalDevice,"trpayment","ty,0\nre,0\nwa,35");
		if (!hRequest)
		{
				printf("POS_CreateRequestEx status: %d",POS_GetError(hLocalDevice));
				break;		
		}

		POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);
		if (POS_WaitForRequestCompleted(hRequest,5000)!=POSNET_STATUS_OK) break;
		if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) break;

		POS_DestroyRequest(hRequest);

		hRequest = POS_CreateRequestEx(hLocalDevice,"trend","to,35\nfp,35");

		POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);
		if (POS_WaitForRequestCompleted(hRequest,5000)!=POSNET_STATUS_OK) break;
		if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) break;

		POS_DestroyRequest(hRequest);
		hRequest=NULL;
		cancel=0;
	}
	while (0);
	if (cancel)
	{
		if (hRequest) POS_DestroyRequest(hRequest);
		hRequest = POS_CreateRequest(hLocalDevice,"prncancel");
		POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);
		POS_WaitForRequestCompleted(hRequest,5000);
		POS_DestroyRequest(hRequest);
	}
}

/*

2. Tryb SPOOL, z oczekiwaniem na zakończenie, rtcget, obsluzymy wyniki

*/

void SpoolSendRtcGet(POSNET_HANDLE hGlobalDevice, POSNET_HANDLE hLocalDevice)
{
	int cancel=1;
	POSNET_HANDLE hRequest;
	do
	{
		hRequest = POS_CreateRequest(hLocalDevice,"rtcget");
		if (!hRequest)
		{
				printf("POS_CreateRequest status: %d",POS_GetError(hLocalDevice));
				break;		
		}

		POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);

		if (POS_WaitForRequestCompleted(hRequest,5000)!=POSNET_STATUS_OK) break;

		if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) break;
		
		// Sprawdzmy pola wynikowe
		char value[250];
		if (POS_GetResponseValue(hRequest,"da",value,250)==POSNET_STATUS_OK)
		{
			printf("Pobrano datę z urządzenia: %s\n",value);
		}
		else
		{
			printf("Brak pola daty w wyniku rozkazu\n");
		}

		POS_DestroyRequest(hRequest);
		
		hRequest=NULL;
		cancel=0;
	}
	while (0);
	if (cancel)
	{
		if (hRequest) POS_DestroyRequest(hRequest);
	}
}

/*

3. Tryb SPOOL, z oczekiwaniem na zakończenie, vatget, wyniki w pętli POP

*/

void SpoolSendRtcGetPOP(POSNET_HANDLE hGlobalDevice, POSNET_HANDLE hLocalDevice)
{
	int cancel=1;
	POSNET_HANDLE hRequest;
	do
	{
		hRequest = POS_CreateRequest(hLocalDevice,"vatget");
		if (!hRequest)
		{
				printf("POS_CreateRequest status: %d",POS_GetError(hLocalDevice));
				break;		
		}

		POS_PostRequest(hRequest,POSNET_REQMODE_SPOOL);

		if (POS_WaitForRequestCompleted(hRequest,5000)!=POSNET_STATUS_OK) break;

		if (POS_GetRequestStatus(hRequest) != POSNET_STATUS_OK) break;
		
		// Sprawdzmy pola wynikowe
		char value[250];
		char valueName[16];
		if (POS_GetResponseValueCount(hRequest))
		{
			printf("Odebrano wyniki, %d pól\n",POS_GetResponseValueCount(hRequest));
			while (POS_PopResponseValue(hRequest,valueName,value,250)==POSNET_STATUS_OK)
			{
				printf("Pobrano pole: '%s', o wartości '%s'\n",valueName,value);
			}
		}

		POS_DestroyRequest(hRequest);
		
		hRequest=NULL;
		cancel=0;
	}
	while (0);
	if (cancel)
	{
		if (hRequest) POS_DestroyRequest(hRequest);
	}
}

/*

3. Tryb SPOOLSPECIAL, z oczekiwaniem na zakończenie, rtcget

*/

void SpoolSendPaperSpecial(POSNET_HANDLE hGlobalDevice, POSNET_HANDLE hLocalDevice)
{
	int cancel=1;
	POSNET_HANDLE hRequest;
	do
	{
		printf("Wysylamy 50 wysuniec papieru ( w tym 1 błędne )....\n");
		for (int i=0; i<50;i++)
		{
			hRequest = POS_CreateRequest(hLocalDevice,"papfeed");
			if (!hRequest)
			{
					printf("POS_CreateRequest status: %d",POS_GetError(hLocalDevice));
					break;		
			}
			if (i==25)
				POS_PushRequestParam(hRequest,"ln","100");
				else
				POS_PushRequestParam(hRequest,"ln","1");

			POS_PostRequest(hRequest,POSNET_REQMODE_SPOOLSPECIAL);
			Sleep(100);
		}
		printf("Czekamy na wykonanie\n");
		Sleep(10000);
		if (POS_GetResponseCount(hLocalDevice)>0)
		{
			printf("Wykonano: %d\n",POS_GetResponseCount(hLocalDevice));
			int i=0;
			while (hRequest=POS_GetNextResponse(hLocalDevice))
			{
				POSNET_STATUS ps=POS_GetRequestStatus(hRequest);
				i++;
				if (ps!=POSNET_STATUS_OK && ps!=POSNET_STATUS_PENDING)
				{
					const char *txt=POS_GetErrorString(ps,"pl");
					char bufor[128];
					printf("Niewykonany %d - Status błędu: %d - %s\n",i,ps,txt?txt:"(brak opisu)");
					if (POS_GetResponseValue(hRequest,"cm",bufor,128)==POSNET_STATUS_OK)
						printf("Polecenie: '%s' \n",bufor);

					POS_DestroyRequest(hRequest);
				}
			}
		}
		
		hRequest=NULL;
		cancel=0;
	}
	while (0);
	if (cancel)
	{
		if (hRequest) POS_DestroyRequest(hRequest);
	}
}


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
 
#include "../setup.inc"

	unsigned long pi=5;
	POS_SetDeviceParam(hDevice,POSNET_DEV_PARAM_STATUSPOLLINGINTERVAL,&pi);
	
	long globalStatus,printerStatus;
	POS_GetPrnDeviceStatus(hLocalDevice,1,&globalStatus,&printerStatus);
	printf("Printer status D:%ld, P%ld\n",globalStatus,printerStatus);

	// Przygotowanie polecenia
	if (globalStatus==0) 
	{
		printf("*****************************************\n");
		printf("SPOOLSPECIAL - wyslij-zapomnij z obsluga bledow\n");
		printf("*****************************************\n");
		SpoolSendPaperSpecial(hDevice, hLocalDevice);
		printf("*****************************************\n");
		printf("Pobranie daty, metoda GET wyników\n");
		printf("*****************************************\n");
		SpoolSendRtcGet(hDevice, hLocalDevice);
		printf("*****************************************\n");
		printf("Pobranie daty, metoda POP wyników\n");
		printf("*****************************************\n");
		SpoolSendRtcGetPOP(hDevice, hLocalDevice);
		printf("*****************************************\n");
		printf("Drukowanie paragonu\n");
		printf("*****************************************\n");
		SpoolSendReceipt(hDevice, hLocalDevice);
	}
	
	POS_CloseDevice(hLocalDevice);
	POS_DestroyDeviceHandle(hDevice);
	return 0;
}
