#include "console_reader.h"
#include "printf-stdarg.h"
//#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "webcam.h"
#include "flashUtilities.h"
#include "klavesnica.h"
#include "riadenie.h"

extern int vykon, maxVykon;
int temp_velkost;
void funkcia(char* data) {
	char text[10];
	uint8 i;
	xprintf("\n\r");
	i = consoleRead(text, 10);
	xprintf("\n\rDlzka textu: %s je:%d",text,i);
	xprintf("\n\r %s", data)
	;

}
void testTlacit(char opakovanie) {
	xprintf("\n\r Timer: %d",opakovanie)
	;
}
void testFunkcia1(char *data) {
	CASOVAC test1;
	char *pch;
	pch = strtok(data, " ,.");

	test1.ms100 = atoi(pch);
	test1.ms100orig = test1.ms100;
	pch = strtok(NULL, " ,.");

	test1.opakovanie = atoi(pch);

	test1.funkcia = testTlacit;
	xprintf("\n\rMs: %d, Opak: %d",test1.ms100orig*100,test1.opakovanie);
	xQueueSend(casovacQueue,&test1,portMAX_DELAY);

}

/*
 **==========================================================================================
 ** Function: cpuVykon
 ** Arguments: char*
 ** Return:  void
 ** Comment: Zobrazy vyuzitie CPU za poslednych 5sec
 **===========================================================================================
 */

void cpuVykon(char* data) {
	int tVykon, tMaxVykon;
	tVykon = vykon;
	tMaxVykon = maxVykon;
	xprintf("\n\rVykon: %d \n\r Max Vykon: %d", tVykon,tMaxVykon)
	;
}
/*--END OF FUNCTION: cpuVykon-----------------------------------------------------*/

void heap(char *data) {
	xprintf("\n\rHeap size/free: %d/%d",configTOTAL_HEAP_SIZE,xPortGetFreeHeapSize())
	;

}

void camsync(char *data) {
	if (sync_camera() == 1) {
		xprintf("\n\rPripojene")
		;
	} else {
		xprintf("\n\r Chyba sync")
		;
	}
}
void caminit(char *data) {

	if (init_camera(COLOR_JPEG, PREVIEW_R160x120, JPEG_R160x128) == 1) {
		xprintf("\n\rKamera inicializovana")
		;
	} else {
		xprintf("\n\r Chyba inicializacie")
		;
	}
}
void camtakepic(char *data) {
	unsigned long velkost;
	if (set_snapshot(SNAPSHOT_COMPRESSED) == -1) {
		xprintf("\n\rChyba SNAMPSHOT")
		;
	} else {
		xprintf("\n\rSNAMPSHOT OK")
		;
	}
	velkost = take_picture(TYPE_SNAPSHOT);
	cam_data_Length = velkost;
	cam_packages_total(cam_data_Length);

	cam_reset_packages();
	xprintf("\n\r Velkost obrazka: %d \n\r Paketov: %d",velkost,akt_total_packages)
	;
	//get_jpeg_data(velkost);

}

void camgetpacket(char *data) {
	char buff[130];
	int i;
	i = atoi(data);
	temp_velkost = get_jpeg_data_packet(buff, i);
	xprintf("\n\r Pocet nacitanych dat= %d este treba: %d",temp_velkost,cam_data_Length-temp_velkost)
	;

}

void camnextpacket(char *data) {
	cam_data_Length -= temp_velkost;
	cam_next_packages()
	;
}

void camgetpacketnext(char *data) {
	uint8 x;
	for (x = 0; x < 16; x++) {

		xprintf("\n\n\r START PACKET: %d\n\r start length: %d",start_package_counter,next_length);

		/*if (x == 1)
		 camgetpacket("130");
		 else if (x == 3)
		 camgetpacket("122");
		 else if (x == 6)
		 camgetpacket("100");
		 else*/
		camgetpacket(data);

		/*if (x == 4 || x == 8)
		 camgetpacket(data);*/
		camnextpacket(NULL);
	}
}
void resetcam(char *data) {
	uint8 resType = RESET_STATES;
	if (data != NULL)
		resType = RESET_SYSTEM;
	xprintf("Reset TYPE: %s",(resType==0)?"SYSTEM":"STATES");
	if (reset_camera(resType) == -1) {
		xprintf("\n\rChyba RESET")
		;
	} else {
		xprintf("\n\rRESET OK")
		;
	}

}
void pinSet(char *data) {
	if (data[0] == '0')
		kameraBit_ClrVal();
	if (data[0] == '1')
		kameraBit_SetVal();
	xprintf("%d",kameraBit_GetVal())
	;
}
void bit1Set(char *data) {
	if (data[0] == '0')
		Bit1_ClrVal();
	if (data[0] == '1')
		Bit1_SetVal();
	xprintf("%s",data)
	;
}
void bit2Set(char *data) {
	if (data[0] == '0')
		Bit2_ClrVal();
	if (data[0] == '1')
		Bit2_SetVal();
	xprintf("%s",data)
	;
}


void psocket_koniec(char *data) {

}

void psocket_send(char *data) {

	(void) xQueueSend(komOutSocketQueue,data,portMAX_DELAY);

	taskYIELD()
	;

}

void flashWrite(char *data) {
	uint32 words[] = { 0xdeadbeef, 0xcafebabe, 0xbabadada, 0xdecafbad,
			0xfeedface, 0xdeadc0de, 0xabadbabe, 0xfeedbabe, 0x00000000,
			0xFFFFFFFF };
	int i;
	i = atoi(data);
	xprintf("Before write: %x\n\r",FLASH_READ_ADDR(TESTADDRESS));
	/*
	 * after erasing ROM, value is 0xFFFF_FFFF
	 * write in same location:
	 * no problem clearing a bit
	 * problem setting bit
	 * page erase (2KB) is executed first for this reason
	 * will return location value to 0xFFFF_FFFF
	 *
	 * will erase from 0x6000 to 0x67FFC longwords.
	 */
	portENTER_CRITICAL();
	CFMrom2ram(TEMPADDRESS, 0, PAGEERASE);
	/* write new word in selected address */
	CFMrom2ram(TEMPADDRESS, words[i], WRITELONGWORD);
	portEXIT_CRITICAL();

	xprintf("After write: %x\n\r",FLASH_READ_ADDR(TESTADDRESS))
	;
}

void flashRead(char *data) {
	xprintf("After write: %x\n\r",FLASH_READ_ADDR(TEMPADDRESS));
	xprintf("Adresa: %x",&Settings.ipAdresa.ip4)
	;
}

void pause(char *data) {
	int i;
	i = atoi(data);
	portENTER_CRITICAL();
	Cpu_Delay50US(i);

	portEXIT_CRITICAL();
	xprintf("\n\rUbehlo: %d ms",i/10)
	;
}
void LCDwrite(char *data) {
	LCD_Clear();
	LCD_Write(data);
}
void klavesnica(char *data) {
	while (1) {
		xSemaphoreTake(klavesnicaGetKeyMutex,portMAX_DELAY);
		xprintf("\n\r Key: %d",KlavesnicaValue_GetVal())
		;
	}
}
void testPIN(char *data){
	PIN("1234,5000,");
}
struct init_PRIKAZ const prikazy[] = { { "heap", heap },
		{ "camsync", camsync }, { "caminit", caminit }, { "camtakepic",
				camtakepic }, { "set", pinSet }, { "resetcam", resetcam }, {
				"take", camgetpacketnext }, { "cpu", cpuVykon }, { "socketEnd",
				psocket_koniec }, { "send", psocket_send }, { "fWrite",
				flashWrite }, { "fRead", flashRead }, { "pause", pause }, {
				"LCD_write", LCDwrite }, { "key", klavesnica }, { "Timer",
				testFunkcia1 },{ "PIN",testPIN },{ "BIT1",bit1Set },{ "BIT2",bit2Set }, { 0, NULL } };

/*
 **==========================================================================================
 ** Function: startConsole_reader
 ** Arguments: int
 ** Return:  void
 ** Comment: nastartovanie tasky console reader
 **===========================================================================================
 */
void vStartConsole_reader(const int priority, const int stack) {

	xTaskCreate(console_reader,"ConsRead",stack,NULL,priority,NULL);
	//xTaskCreate(console_reader_uart1,"Uart1",stack,NULL,priority,NULL);

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

/*
 **==========================================================================================
 ** Function: console_reader
 ** Arguments: void*
 ** Return:  void
 ** Comment: Tento proces vacsinu casu caka na priajate data z uart1 aked ich prijme tak vyhodnocuje a posiela dalej
 **===========================================================================================
 */
void console_reader(void *pvParameters) {
	uart1_TComData c;
	char buffer[size_of_console_command_buffer];
	unsigned char index = 0;

	unsigned char temp, najdenyPrikaz;

	uart1_SendChar('>');
	buffer[0] = '\0';

	for (;;) {

		xSemaphoreTake(uart1_Mutex.getCharMutex,portMAX_DELAY);
		(void) uart1_RecvChar(&c);

		switch (c) {
		case 9: //Tabulator
			najdenyPrikaz = 127;
			for (temp = 0; prikazy[temp].meno != 0; temp++) {

				if (strncmp(buffer, prikazy[temp].meno, index) == 0) {
					if (najdenyPrikaz == 127) {
						najdenyPrikaz = temp;
						najdenyPrikaz |= 0x80;
					} else {
						if (najdenyPrikaz & 0x80) {
							najdenyPrikaz &= 0x7f;
							xprintf("\n\r%s", prikazy[najdenyPrikaz].meno)
							;
						}
						xprintf("\n\r%s", prikazy[temp].meno)
						;
					}
				}
			}
			if (najdenyPrikaz & 0x80) {
				najdenyPrikaz &= 0x7f;
				strcpy(buffer, prikazy[najdenyPrikaz].meno);
				index = strlen(prikazy[najdenyPrikaz].meno);
				xprintf("\r>%s", buffer)
				;
			} else if (najdenyPrikaz != 127) {
				xprintf("\n\r>%s", buffer)
				;
			}
			break;
		case 8: //BackSpace
			if (index != 0) {
				index--;
				uart1_SendChar(c);
				uart1_SendChar(' ');
				uart1_SendChar(c);
				buffer[index] = '\0';
			}
			break;

		case '\r':
			if (index > 0) {
				buffer[index] = '\0';

				for (temp = 0; prikazy[temp].meno != 0; temp++) {
					char temp2;

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

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

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

						goto koniec;
					}
					if (najdenyPrikaz == 127)
						buffer[temp2] = ' ';
				}
				xprintf("\n\rUnknow command")
				;
			}
			koniec:

			uart1_SendChar('\r');
			uart1_SendChar('\n');
			uart1_SendChar('>');
			index = 0;
			buffer[0] = '\0';

			break;
		case 224:
			/*	if (getch() == 72)
			 {
			 if (history[0] != '\0')
			 {

			 strcpy(buffer, history);
			 temp = index;
			 index = strlen(buffer);

			 printf("\n\r>%s", buffer);

			 }
			 }*/
			break;

		default:
			if (index < size_of_console_command_buffer - 1) {
				buffer[index] = (char) c;
				index++;
				buffer[index] = '\0';
				uart1_SendChar(c);
			}
			break;
		}

	}

}
/*--END OF FUNCTION: enclosing_method-----------------------------------------------------*/
/*
 **==========================================================================================
 ** Function: consoleRead
 ** Arguments: char*, const uint8
 ** Return:  uint8
 ** Comment: Nacitanie retazca z konzoly, retazec je ukonceny enterom
 **===========================================================================================
 */
uint8 consoleRead(char *buffer, const uint8 max) {
	uart1_TComData c;
	unsigned char index = 0;
	buffer[0] = '\0';

	for (;;) {

		xSemaphoreTake(uart1_Mutex.getCharMutex,portMAX_DELAY);
		(void) uart1_RecvChar(&c);
		switch (c) {
		case 9: //Tabulator
			break;
		case 8: //BackSpace
			if (index != 0) {
				index--;
				uart1_SendChar(c);
				uart1_SendChar(' ');
				uart1_SendChar(c);
				buffer[index] = '\0';
			}
			break;

		case '\r':
			return index;
			break;

		default:
			if (index < max) {
				buffer[index] = (char) c;
				index++;
				buffer[index] = '\0';
				uart1_SendChar(c);
			}
			break;
		}

	}

}
/*--END OF FUNCTION: consoleRead-----------------------------------------------------*/
/*
 **==========================================================================================
 ** Function: console_reader
 ** Arguments: void*
 ** Return:  void
 ** Comment: Tento proces vacsinu casu caka na priajate data z Uart1 aked ich prijme tak vyhodnocuje a posiela dalej
 **===========================================================================================
 */
//void console_reader_uart1(void *pvParameters) {
//	uart1_TComData c, buffer[20];
//	word i;
//	for (;;) {
//		/*xSemaphoreTake(uart1_Mutex.getCharMutex,portMAX_DELAY);
//		 (void) uart1_RecvChar(&c);
//		 uart1_RecvBlock();
//		 (void) uart1_SendChar(c);*/
//		(void) uart1_RecvBlock(buffer, 10, &i, portMAX_DELAY);
//		buffer[10] = '\0';
//		xprintf("%s",buffer)
//		;
//	}
//}
/*--END OF FUNCTION: consoleRead-----------------------------------------------------*/
