#include "riadenie.h"
#include "printf-stdarg.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "kom_modul.h"
#include "LCD.h"
#include "string.h"
#include "console_reader.h"
#include "klavesnica.h"

void LCDwrite2(char *data) {
	LCD_Clear_Line(0);
	LCD_PutString(0, data);

}
void NormalnyStav(char opak) {
	LCD_Clear();
	LCD_PutCenterString(0, "Prilozte Kartu!");
}

void buzzerOK(char opak) {
	Bit1_NegVal();
	if (opak == 0)
		Bit1_ClrVal();
}

void buzzerChyba(char opak) {
	Bit1_ClrVal();
}
void dvere(char opak) {
	Bit2_ClrVal();
}

void OpenDvere(char *data) {
	CASOVAC test1, test2, test3;

	LCD_Clear_Line(0);
	LCD_PutCenterString(0, "Dvere otvorene!");
	if (data != NULL) {
		test1.ms100 = atoi(data);
	} else
		test1.ms100 = 20;
	test1.ms100orig = test1.ms100;
	test1.opakovanie = 1;
	test1.funkcia = NormalnyStav;
	xQueueSend(casovacQueue,&test1,portMAX_DELAY);

	test2.ms100 = 1;
	test2.ms100orig = test2.ms100;
	test2.opakovanie = 25;
	test2.funkcia = buzzerOK;
	xQueueSend(casovacQueue,&test2,portMAX_DELAY);

	Bit2_SetVal();
	test3.ms100 = 50;
	test3.ms100orig = test2.ms100;
	test3.opakovanie = 1;
	test3.funkcia = dvere;
	xQueueSend(casovacQueue,&test3,portMAX_DELAY);
}

void Chyba(char *data) {
	CASOVAC test1, test2;
	char *pch;
	pch = strtok(data, ",.");
	LCD_Clear_Line(0);
	LCD_PutCenterString(0, "CHYBA!!!");
	LCD_PutCenterString(1, pch);
	pch = strtok(NULL, ",.");
	test1.ms100 = atoi(pch);
	test1.ms100orig = test1.ms100;
	test1.opakovanie = 1;
	test1.funkcia = NormalnyStav;
	xprintf("\n\rMS: %d",test1.ms100);
	xQueueSend(casovacQueue,&test1,portMAX_DELAY);

	Bit1_SetVal();
	test2.ms100 = 10;
	test2.ms100orig = test2.ms100;
	test2.opakovanie = 1;
	test2.funkcia = buzzerChyba;
	xQueueSend(casovacQueue,&test2,portMAX_DELAY);
}

void PIN(char *data) {
	char *pin;
	char *casCh;
	char zadanyPin[4];
	char i = 0, znak;
	CASOVAC test1;
	int cas;
	xprintf("\n\r  %s",data);
	LCD_Clear_Line(0x10);
	LCD_PutString(0x10, "PIN:");
	LCD_SetCursorOn(0x14);
	pin = strtok(data, ",.");
	casCh = strtok(NULL, ",.");
	cas = atoi(casCh);
	xprintf("\n\r PIN: %s  cas: %d",pin,cas);
	xSemaphoreTake(klavesnicaGetKeyMutex,1);
	while (1) {
		if (xSemaphoreTake(klavesnicaGetKeyMutex,cas) == pdTRUE) {
			vTaskDelay(50);
			znak = KlavesnicaValue_GetVal();

			if (znak == '*') {
				LCD_Clear_Line(0x10);
				LCD_PutString(0x10, "PIN:");
				LCD_SetCursorOn(0x14);
				i = 0;
			} else if (i == 4) {
				if (znak == '#') {
					if (strncmp(zadanyPin, pin, 4) == 0) {
						LCD_Clear_Line(0x10);
						LCD_PutString(0x10, "PIN OK");
						test1.ms100 = 5;
						test1.ms100orig = test1.ms100;
						test1.opakovanie = 1;
						test1.funkcia = OpenDvere;
						xQueueSend(casovacQueue,&test1,portMAX_DELAY);
						return;
					} else {
						LCD_Clear_Line(0x10);
						LCD_PutString(0x10, "Zly PIN");
						test1.ms100 = 20;
						test1.ms100orig = test1.ms100;
						test1.opakovanie = 1;
						test1.funkcia = NormalnyStav;
						xQueueSend(casovacQueue,&test1,portMAX_DELAY);
						return;
					}
				}
			} else {
				LCD_Write_Data(znak);
				zadanyPin[i] = znak;
				i++;
			}

		} else {
			LCD_Clear_Line(0x10);
			LCD_PutString(0x10, "VYPRSAL CAS");
			test1.ms100 = 20;
			test1.ms100orig = test1.ms100;
			test1.opakovanie = 1;
			test1.funkcia = NormalnyStav;
			xQueueSend(casovacQueue,&test1,portMAX_DELAY);
			return;
		}

	}
}

struct init_PRIKAZ const commandSSS[] = { { "LCD", LCDwrite2 }, { "OPEN",
		OpenDvere }, { "CHYBA", Chyba }, { "PIN", PIN }, { 0, NULL } };

/*
 **==========================================================================================
 ** Function: vTaskTimer
 ** Arguments: void*
 ** Return:  void
 ** Comment: Proces Timer
 **===========================================================================================
 */
void vTaskTimer(void *pvParameters) {
	portTickType prevTime;
	CASOVAC buffer;
	unsigned char i, pocetSprav;
	prevTime = xTaskGetTickCount();
	for (;;) {
		vTaskDelayUntil(&prevTime, 100); //Zobudenie kazdych 100ms
		pocetSprav = uxQueueMessagesWaiting(casovacQueue);
		for (i = 0; i < pocetSprav; i++) {
			(void) xQueueReceive(casovacQueue,&buffer,portMAX_DELAY);
			buffer.ms100--;
			//xprintf("\n\rTimer: %d  MS:%d Opak: %d",i,buffer.ms100,buffer.opakovanie);

			if (buffer.ms100 == 0) {
				if (buffer.opakovanie > 0) {
					buffer.ms100 = buffer.ms100orig;
					buffer.opakovanie--;
					buffer.funkcia(buffer.opakovanie);
					xQueueSend(casovacQueue,&buffer,portMAX_DELAY);
				} else if (buffer.opakovanie == 0) {
					buffer.ms100 = buffer.ms100orig;
					//buffer.funkcia(0);

				} else {
					buffer.ms100 = buffer.ms100orig;
					xQueueSend(casovacQueue,&buffer,portMAX_DELAY);
					buffer.funkcia(-1);
				}

			} else {
				xQueueSend(casovacQueue,&buffer,portMAX_DELAY);
			}

		}

	}
}
/*--END OF FUNCTION: vTaskTimer-----------------------------------------------------*/

/*
 **==========================================================================================
 ** Function: vStartControlTask
 ** Arguments: unsigned char
 ** Return:  void
 ** Comment: Startovanie taskov potrebnych na kontrol
 **===========================================================================================
 */
void vStartControlTask(unsigned char priority) {

	xTaskCreate(vTaskControl,"Control",150,NULL,priority,NULL);
	xTaskCreate(vTaskTimer,"Timer",250,NULL,priority,NULL);

}
/*--END OF FUNCTION: vStartControlTask-----------------------------------------------------*/

/*
 **==========================================================================================
 ** Function: command_parser
 ** Arguments: char* - buffer prikaz napr. LCD napisTOTO
 ** Return:  void ** Comment: Analyzuje vstupny buffer a ak je najdeny prikaz tak sa vykona
 **===========================================================================================
 */
void command_parser(char *buffer) {
	uint8 najdenyPrikaz, temp, temp2;

	for (temp = 0; commandSSS[temp].meno != 0; temp++) {

		for (temp2 = 0; (buffer[temp2] != '\0' && buffer[temp2] != ' '); temp2++)
			;
		if (buffer[temp2] == ' ') {
			buffer[temp2] = '\0';
			najdenyPrikaz = 127;
		} else
			najdenyPrikaz = 128;

		if (strcmp(buffer, commandSSS[temp].meno) == 0) {

			if (najdenyPrikaz == 127) {
				commandSSS[temp].funkcia(buffer + temp2 + 1);
			} else
				commandSSS[temp].funkcia(NULL);

			return;
		}
		if (najdenyPrikaz == 127)
			buffer[temp2] = ' ';
	}
	xprintf("\n\rUnknow commandSSS")
	;

}
/*--END OF FUNCTION: command_parser-----------------------------------------------------*/

/*
 **==========================================================================================
 ** Function: vTaskControl
 ** Arguments: void*
 ** Return:  void
 ** Comment: Kontrolny proces
 **===========================================================================================
 */
void vTaskControl(void *pvParameters) {
	char buffer[sizeQueue];
	uint8 i = 0;
	LCD_Clear();
	LCD_PutCenterString(0, "Prilozte Kartu!");
	for (;;) {
		(void) xQueueReceive(komInSocketQueue,buffer,portMAX_DELAY);

		buffer[strlen(buffer)] = '\0';

		xprintf("\n\r");
		for (i = 0; i < strlen(buffer) + 1; i++) {
			xprintf("%x ",buffer[i])
			;
		}
		xprintf("%s",buffer);
		command_parser(buffer);

	}

}
/*--END OF FUNCTION: vTaskControl-----------------------------------------------------*/

