#include "EC800M_GPS.h"

// 存放GPS数据
char GPSDATA[GPSDATA_LENGTH];
int GPSDATA_LEN;

// 重置GPS数据缓冲区
void gps_reset_data()
{
    memset(GPSDATA, 0, GPSDATA_LENGTH);
    GPSDATA_LEN = 0;
}

// 初始化 EC800M 串口
int EC800M_UART_INIT()
{
    uart_init(EC800M_GPS_UART, GPS_UART_BAUD_RATE);
    gpio_set_function(GPS_UART_TX, GPIO_FUNC_UART);
    gpio_set_function(GPS_UART_RX, GPIO_FUNC_UART);
    uart_set_hw_flow(EC800M_GPS_UART, false, false);
    uart_set_format(EC800M_GPS_UART, GPS_DATA_BITS, GPS_STOP_BITS, UART_PARITY_NONE);

    return 0;
}

void _gps_uart_send_string(const char *str)
{
    size_t len = strlen(str);
    uart_write_blocking(EC800M_GPS_UART, (const uint8_t *)str, len);

    return;
}

int _gps_uart_read_string()
{
    int _time = 0;
    int timeout = 3000;         // 设置超时时间为7秒，单位为毫秒

    while (1) {
        if (uart_is_readable(EC800M_GPS_UART)) {
            char c = uart_getc(EC800M_GPS_UART);

            if (GPSDATA_LEN < GPSDATA_LENGTH - 1) {
                GPSDATA[GPSDATA_LEN++] = c;
                GPSDATA[GPSDATA_LEN] = '\0';
            }
        } else {
            return 0;
        }

        // 检查是否超时
        if (_time >= timeout) {
            printf("EC800M _gps_uart_read_string() 读取超时\n");
            return -1;
        }

        sleep_ms(1);            // 稍微延迟一下，等待下一个循环
        _time++;
    }

    return 0;
}

int _gps_uart_read_string_until_response(const char *expected_response)
{
    gps_reset_data();

    int timeout = 3000;         // 设置超时时间为7秒，单位为毫秒

    int i = 0;
    int _time = 0;
    while (1) {
        while (uart_is_readable(EC800M_GPS_UART)) {
            char c = uart_getc(EC800M_GPS_UART);
            GPSDATA[i++] = c;
            GPSDATA[i] = '\0';  // 添加字符串结束符

            if (strstr(GPSDATA, expected_response) != NULL) {
                GPSDATA_LEN = i;
                return 0;       // 找到了预期的响应，退出循环
            }
        }
        _time++;
        sleep_ms(1);            // 等待一小段时间再继续读取

        if (_time >= timeout) {
            _time = 0;
            printf("EC800M _gps_uart_read_string_until_response() 读取超时\n");

            return -1;
        }
    }
}

// GPS 经纬度转10进制
long double convertToDecimal(long double coordinate)
{
    int degree = (int)(coordinate / 100);
    long double minutes = coordinate - degree * 100;
    return degree + minutes / 60;
}

// 解释GPS数据
int EC800M_GPS_DATA_PARSING(char *GPS_DATA, GPS_ * gps_)
{
    int i = 1;
    char *p;
    char *p1;
    char *token;

    p = strchr(GPS_DATA, ':');
    if (p == NULL) {
        return -1;
    }
    
    p1 = strstr(p + 2, "\r\n");
    if (p1 == NULL) {
        return -1;
    }

    char GPS_DATA_[p1 - p];
    memset(gps_->time, 0, 20);
    memset(gps_->N, 0, 20);
    memset(gps_->E, 0, 20);
    memset(GPS_DATA_, 0, p1 - p);
    memcpy(GPS_DATA_, p + 2, p1 - p - 2 + 1);
    GPS_DATA_[p1 - p - 2 + 1] = '\0';
    printf("%s\n", GPS_DATA_);

    token = strtok(GPS_DATA_, ",");
    while (token != NULL) {
        if (i == 1) {
            strcpy(gps_->time, token);
        }
        if (i == 2) {
            strcpy(gps_->N, token);
        }
        if (i == 3) {
            strcpy(gps_->E, token);
        }

        token = strtok(NULL, ",");
        i++;
    }

    gps_->N[strlen(gps_->N) - 1] = '\0';
    gps_->E[strlen(gps_->E) - 1] = '\0';

    // 095921.00
    char hours[3] = { 0 };
    char minutes[3] = { 0 };
    char seconds[9] = { 0 };
    char *p2 = gps_->time;
    memcpy(hours, p2, 2);
    memcpy(minutes, p2 + 2, 2);
    memcpy(seconds, p2 + 4, 2);
    //printf("GPS 修正时间: %d:%s:%s\n", atoi(hours) + 8, minutes, seconds);

    sprintf(gps_->time, "%d:%s:%s", atoi(hours) + 8, minutes, seconds);
    sprintf(gps_->N, "%.6lf", convertToDecimal(atof(gps_->N)));
    sprintf(gps_->E, "%.6lf", convertToDecimal(atof(gps_->E)));


    return 0;
}

// 初始化 EC800M GPS
int EC800M_GPS_INIT()
{
    _gps_uart_send_string("AT+QGPSCFG=\"outport\",\"uartdebug\"\r\n");
    sleep_ms(100);
    if (-1 == _gps_uart_read_string()) {
        return -1;
    }

    _gps_uart_send_string("AT+QGPSCFG=\"nmeasrc\",1\r\n");
    sleep_ms(100);
    if (-1 == _gps_uart_read_string()) {
        return -1;
    }

    _gps_uart_send_string("AT+QGPSCFG=\"gpsnmeatype\",63\r\n");
    sleep_ms(100);
    if (-1 == _gps_uart_read_string()) {
        return -1;
    }

    _gps_uart_send_string("AT+QGPSCFG=\"gnssconfig\",1\r\n");
    sleep_ms(100);
    if (-1 == _gps_uart_read_string()) {
        return -1;
    }

    _gps_uart_send_string("AT+QGPSCFG=\"autogps\",0\r\n");
    sleep_ms(100);
    if (-1 == _gps_uart_read_string()) {
        return -1;
    }

    _gps_uart_send_string("AT+QGPSCFG=\"apflash\",0\r\n");
    sleep_ms(100);
    if (-1 == _gps_uart_read_string()) {
        return -1;
    }

    _gps_uart_send_string("AT+QGPS=1\r\n");
    sleep_ms(100);
    if (-1 == _gps_uart_read_string()) {
        return -1;
    }
    // 打印第一次初始化输出
    //printf("%s %d\n", GPSDATA, strlen(GPSDATA));

    return 0;
}

void EC800M_GPS(void *p)
{
    (void)p;

    
    //while (1) {
        printf("EC800M Module GPS\n");

        GPS_ gps_;
        memset(gps_.time, 0, 20);
        memset(gps_.N, 0, 20);
        memset(gps_.E, 0, 20);

        if (-1 == EC800M_GPS_INIT()) {
            printf("EC800M_INIT() 第一次初始化失败\n");
        }

        _gps_uart_send_string("AT+QGPSLOC=0\r\n");
        if (-1 == _gps_uart_read_string_until_response("OK")) {
            printf("重启EC800M模块 GPS\n");
            EC800M_GPS_INIT();
        }
        sleep_ms(300);
        //printf("%s %d %d\n", GPSDATA, strlen(GPSDATA), GPSDATA_LEN);

        if (NULL == strstr(GPSDATA, "ERROR") && GPSDATA_LEN > 0) {
            EC800M_GPS_DATA_PARSING(GPSDATA, &gps_);
            printf(" T: %s\n N: %s\n E: %s\n", gps_.time, gps_.N, gps_.E);
            printf(" NE: %s, %s\n", gps_.N, gps_.E);
        }
        
        printf("\n");
        vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
    //}
    
    return;
}
