#include <SoftwareSerial.h>
#include <LibPrintf.h>
#include <string.h>

#define GPS_RX_PIN 7
#define GPS_TX_PIN 6
#define GPS_BAUD_RATE 9600

char received_char, buffer[100];
char *ptr, *identifier, *time_utc, *latitude, *ns_indicator, *longitude, *ew_indicator, *fix_quality, *altitude, *altitude_units;
uint8_t buffer_length = 0;
SoftwareSerial GPS_Serial(GPS_RX_PIN, GPS_TX_PIN);

void setup() {
   Serial.begin(115200);
   GPS_Serial.begin(GPS_BAUD_RATE);
}

void loop() {
   while (1) {
      if (GPS_Serial.available() != 0) { // check for data
         received_char = GPS_Serial.read();
         buffer[buffer_length++] = received_char;
      }
      if (received_char == '\n') { // check for end of line
         buffer_length = 0;
         if (strncmp(buffer, "$GPGGA", 6) == 0) { // check for fix data
            identifier = strtok_r(buffer, ",", &ptr);
            time_utc = strtok_r(NULL, ",", &ptr);
            if (buffer[10 + (time_utc - buffer)] == ',') { // check for empty latitude
               printf("%s: no fix\n", time_utc);
               break;
            }
            latitude = strtok_r(NULL, ",", &ptr);
            ns_indicator = strtok_r(NULL, ",", &ptr);
            longitude = strtok_r(NULL, ",", &ptr);
            ew_indicator = strtok_r(NULL, ",", &ptr);
            fix_quality = strtok_r(NULL, ",", &ptr);
            altitude = strtok_r(NULL, ",", &ptr);
            altitude_units = strtok_r(NULL, ",", &ptr);
            printf("UTC time: %s, ", time_utc);
            printf("Latitude: %s ", latitude);
            printf("%s, ", ns_indicator);
            printf("Longitude: %s ", longitude);
            printf("Altitude: %s ", altitude);
            printf("%s\n", altitude_units);
            break;
         }
      }
   }
}