#pragma once

#include <string.h>
#include <stdlib.h>
using namespace std;

#include "GPS.hpp"
#include "UARTs.h"

class UBloxGPSuart : public GPS
{
public:
	UBloxGPSuart()
	{
		defineCommands();
	}
	
	uint8_t getPosition2(GPSFix currentFix)
	{
		//ioPort.writeReadPort(ubloxCmd[GPS::GPSCommands::getPosition]);  		
		return 1;
	}
	
	uint8_t getTime2(GPSFix* currentFix)
	{
		//if (ioPort.writeReadPort[ubloxCmd[GPS::GPSCommands::getTime] > 0)
		{
		}
		return 1;
	}
	
	uint8_t getTime2Fake(GPSFix& currentFix)
	{
		uint8_t returnValue = -1;
		FIFO::FIFORecord qRecord;
		
		clearFix(currentFix);
		
		string dateNow = __DATE__;
		string timeNow = __TIME__;
		string dateTimeNow = dateNow + "T" + timeNow;
		
		ubloxCmd[GPS::GPSCmdNums::getTimeFake].commandString = dateTimeNow;
		
		if (ioPort.writeReadPortFake(ubloxCmd[GPS::GPSCmdNums::getTimeFake], &qRecord) > 0)
		{
			if (checkForCorrectReply(ubloxCmd[GPS::GPSCmdNums::getTimeFake], qRecord))
			{
				for (int i = 0; i < sizeof(currentFix.msg); i++)
					currentFix.msg[i] = qRecord.message[i];
			
				parseTime2Fake(currentFix);
				
				logFix(currentFix);
				returnValue = 1;
			}
			else
			{
				logRecord();
				returnValue = 0;
			}
		}
		else
		{
			returnValue = 0;
		}
		
		return returnValue;
	}

	bool checkForCorrectReply(UARTs::CommandStruct cmd, FIFO::FIFORecord qRecord)
	{
		return true;
	}
	
	void logFix(GPS::GPSFix fix)
	{
	}
	
	void logRecord()
	{
	}
	
	uint8_t parseTime2Fake(GPS::GPSFix& currentFix)
	{
		char* token;
		char msg[sizeof(currentFix.msg) + 1];
	
		for (int i = 0; i < sizeof(currentFix.msg); i++)
		{
			msg[i] = currentFix.msg[i];
			if (currentFix.msg[i] == 0)
				break;
		}
		
		token = strtok(msg, " ");
		cout << token << endl;
		currentFix.TOF.monthMMM = token;

		if (strcmp(token, "Jan") == 0)
			currentFix.TOF.month = 1;
		else if (strcmp(token, "Feb") == 0)
			currentFix.TOF.month = 2;
		else if (strcmp(token, "Mar") == 0)
			currentFix.TOF.month = 3;
		else if (strcmp(token, "Apr") == 0)
			currentFix.TOF.month = 4;
		else if (strcmp(token, "May") == 0)
			currentFix.TOF.month = 5;
		else if (strcmp(token, "Jun") == 0)
			currentFix.TOF.month = 6;
		else if (strcmp(token, "Jul") == 0)
			currentFix.TOF.month = 7;
		else if (strcmp(token, "Aug") == 0)
			currentFix.TOF.month = 8;
		else if (strcmp(token, "Sep") == 0)
			currentFix.TOF.month = 9;
		else if (strcmp(token, "Oct") == 0)
			currentFix.TOF.month = 10;
		else if (strcmp(token, "Nov") == 0)
			currentFix.TOF.month = 11;
		else if (strcmp(token, "Dec") == 0)
			currentFix.TOF.month = 12;
				  		
		token = strtok(NULL, " ");
		cout << token << endl;
		currentFix.TOF.date = atoi(token);
		
		token = strtok(NULL, "T");
		cout << token << endl;
		currentFix.TOF.year = atoi(token);
		
		token = strtok(NULL, ":");
		cout << token << endl;
		currentFix.TOF.hour = atoi(token);
		
		token = strtok(NULL, ":");
		cout << token << endl;
		currentFix.TOF.minute = atoi(token);
		
		token = strtok(NULL, ":");
		cout << token << endl;
		currentFix.TOF.second = atoi(token);
		
		currentFix.TOF.milliSecond = 0;
		
		return 1;
	}

protected:
	UARTs ioPort = UARTs(UARTs::DeviceID::gpsSim, 16, 255, "GPS2");
	UARTs::CommandStruct ubloxCmd[GPS::GPSCmdNums::numCmds];
	

private:
	
	void defineCommands()
	{
		ubloxCmd[GPS::GPSCmdNums::getPositionCmdNum].commandString = "$PUBX,00*33\r\n";
		copy(ubloxCmd[GPS::GPSCmdNums::getPositionCmdNum].commandString.begin(),
			ubloxCmd[GPS::GPSCmdNums::getPositionCmdNum].commandString.begin(),
			ubloxCmd[GPS::GPSCmdNums::getPositionCmdNum].commandBytes);
		ubloxCmd[GPS::GPSCmdNums::getPositionCmdNum].correctReply = (uint8_t*)"$PUBX,00";
		ubloxCmd[GPS::GPSCmdNums::getPositionCmdNum].commandLength = sizeof(ubloxCmd[GPS::GPSCmdNums::getPositionCmdNum].commandString);
		
		ubloxCmd[GPS::GPSCmdNums::getTimeCmdNum].commandString = "$PUBX,04*37\r\n";
		copy(ubloxCmd[GPS::GPSCmdNums::getTimeCmdNum].commandString.begin(),
			ubloxCmd[GPS::GPSCmdNums::getTimeCmdNum].commandString.begin(),
			ubloxCmd[GPS::GPSCmdNums::getTimeCmdNum].commandBytes);
		ubloxCmd[GPS::GPSCmdNums::getTimeCmdNum].correctReply = (uint8_t*)"$PUBX,04";
		ubloxCmd[GPS::GPSCmdNums::getTimeCmdNum].commandLength = sizeof(ubloxCmd[GPS::GPSCmdNums::getTimeCmdNum].commandString);

		ubloxCmd[GPS::GPSCmdNums::getTimeFake].commandString = "$PUBX,fakeTime\r\n";
		copy(ubloxCmd[GPS::GPSCmdNums::getTimeFake].commandString.begin(),
			ubloxCmd[GPS::GPSCmdNums::getTimeFake].commandString.begin(),
			ubloxCmd[GPS::GPSCmdNums::getTimeFake].commandBytes);
		ubloxCmd[GPS::GPSCmdNums::getTimeFake].correctReply = (uint8_t*)"$PUBX,fakeTime";
		ubloxCmd[GPS::GPSCmdNums::getTimeFake].commandLength = sizeof(ubloxCmd[GPS::GPSCmdNums::getTimeFake].commandString);
	}
};