#include "gps.h"
#include "stdio.h"
#include "string.h"
#include "math.h"

uint32_t UTC;
char SetTimeZone[25] = {0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xf1, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c};

u8 NMEA_Comma_Pos(u8 *buf, u8 cx)
{
    u8 *p = buf;
    while (cx)
    {
        if (*buf == '*' || *buf < ' ' || *buf > 'z')
            return 0XFF; // 遇到'*'或者非法字符,则不存在第cx个逗号
        if (*buf == ',')
            cx--;
        buf++;
    }
    return buf - p;
}

u32 NMEA_Pow(u8 m, u8 n)
{
    u32 result = 1;
    while (n--)
        result *= m;
    return result;
}

int NMEA_Str2num(u8 *buf, u8 *dx)
{
    u8 *p = buf;
    u32 ires = 0, fres = 0;
    u8 ilen = 0, flen = 0, i;
    u8 mask = 0;
    int res;
    while (1) // 得到整数和小数的长度
    {
        if (*p == '-')
        {
            mask |= 0X02;
            p++;
        } // 是负数
        if (*p == ',' || (*p == '*'))
            break; // 遇到结束了
        if (*p == '.')
        {
            mask |= 0X01;
            p++;
        } // 遇到小数点了
        else if (*p > '9' || (*p < '0')) // 有非法字符
        {
            ilen = 0;
            flen = 0;
            break;
        }
        if (mask & 0X01)
            flen++;
        else
            ilen++;
        p++;
    }
    if (mask & 0X02)
        buf++; // 去掉负号
    for (i = 0; i < ilen; i++) // 得到整数部分数据
    {
        ires += NMEA_Pow(10, ilen - 1 - i) * (buf[i] - '0');
    }
    if (flen > 5)
        flen = 5;      // 最多取5位小数
    *dx = flen;        // 小数点位数
    for (i = 0; i < flen; i++) // 得到小数部分数据
    {
        fres += NMEA_Pow(10, flen - 1 - i) * (buf[ilen + 1 + i] - '0');
    }
    res = ires * NMEA_Pow(10, flen) + fres;
    if (mask & 0X02)
        res = -res;
    return res;
}

// 分析GPRMC信息
// gpsx: nmea信息结构体
// buf: 接收到的GPS数据缓冲区首地址
void NMEA_GPRMC_Analysis(nmea_msg *gpsx, u8 *buf)
{
    u8 *p1, dx;
    u8 posx;
    u32 temp;
    p1 = (u8 *)strstr((const char *)buf, "RMC"); // "$GPRMC", 经常有&和GPRMC分开的情况, 故只判断GPRMC.
    posx = NMEA_Comma_Pos(p1, 1); // 得到UTC时间
    if (posx != 0XFF)
    {
        UTC = NMEA_Str2num(p1 + posx, &dx) / NMEA_Pow(10, dx);
        temp = (NMEA_Str2num(p1 + posx, &dx) / NMEA_Pow(10, dx)); // 得到UTC时间, 去掉ms

        gpsx->utc.hour = temp / 10000 + 8; // UTC时间加上时区差
        gpsx->utc.min = (temp / 100) % 100;
        gpsx->utc.sec = temp % 100;
    }

    posx = NMEA_Comma_Pos(p1, 9); // 得到UTC日期
    if (posx != 0XFF)
    {
        temp = NMEA_Str2num(p1 + posx, &dx); // 得到UTC日期
        gpsx->utc.date = temp / 10000;
        gpsx->utc.month = (temp / 100) % 100;
        gpsx->utc.year = 2000 + temp % 100;
    }
}

// 提取NMEA-0183信息
// gpsx: nmea信息结构体
// buf: 接收到的GPS数据缓冲区首地址
void GPS_Analysis(nmea_msg *gpsx, u8 *buf)
{
    NMEA_GPRMC_Analysis(gpsx, buf); // GPRMC解析
}
