/**********************************************************************************************
    Copyright (C) 2009 Oliver Eichler oliver.eichler@gmx.de

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

**********************************************************************************************/

#include "CNMEA_Mtk.h"

#include <QtGui>
#include <proj_api.h>

CNMEA_Mtk::CNMEA_Mtk(const QString& device, int rate, QObject * parent)
: CNMEA(device, rate, parent)
{
    sysError = tr("Start NMEA/Mtk device.");
}


CNMEA_Mtk::~CNMEA_Mtk()
{

}


void CNMEA_Mtk::portChanged()
{
    if(port.isOpen()) {
        encode("PMTK000");
        sysError = tr("Detecting MTK chip set...");
        emit sigNewData(*this);
    }
}


void CNMEA_Mtk::decode(const QString& line)
{
    QString tok;
    QStringList tokens = line.split(QRegExp("[,*]"));
    //     qDebug() << tokens.count() << tokens;
    if((tokens[0] == "$PMTK001")) {
        //         "$PMTK001,0,3*30"
        if(tokens[1] == "0" && tokens[2] == "3") {
            encode("PMTK314,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1");
            sysError.clear();
        }
    }
    else if((tokens[0] == "$GPGGA")) {
        //             0      1                  2       3         4        5    6     7     8       9     10    11     12   13    14
        //     15 ("$GPGGA", "130108.000", "4901.7451", "N", "01205.8656", "E", "1", "06", "1.8", "331.6", "M", "47.3", "M", "", "0000*5F")
        //         qDebug() << tokens.count() << tokens;
        ele         = tokens[9].toDouble();
        //         height      = tokens[11].toDouble();
        //         altitude    = ele - height;
    }
    else if((tokens[0] == "$GPGSA")) {
        //             0      1    2     3    4      5     6     7    8   9  10  11  12  13  14    15    16     17
        //     18 ("$GPGSA", "A", "3", "11", "23", "13", "04", "17", "", "", "", "", "", "", "", "3.5", "2.2", "2.6*31")
        //         qDebug() << tokens.count() << tokens;
        int tok = tokens[2].toInt();
        fix  = tok == 3 ? e3DFix : tok == 2 ? e2DFix : eNoFix;
        hdop = tokens[16].toDouble();
        vdop = tokens[17].toDouble();
        //         qDebug() << (hdop * 3);
    }
    else if((tokens[0] == "$GPGSV")) {
        //             0      1    2     3    4      5     6      7     8     9     10    11    12    13     14    15    16    17     18    19
        //     20 ("$GPGSV", "3", "1", "11", "23", "82", "080", "16", "20", "55", "094", "13", "13", "53", "227", "34", "04", "44", "298", "21*72")
        //     20 ("$GPGSV", "3", "2", "11", "25", "25", "170", "23", "17", "17", "239", "22", "11", "16", "165", "13", "31", "14", "036", "*72")
        //     16 ("$GPGSV", "3", "3", "11", "02", "12", "316", "", "07", "09", "177", "", "27", "05", "184", "*4E")
        if(tokens[2] == "1") {
            memset(satellites,0,sizeof(satellites));
            idxSat = 0;
        }

        int i = 4;
        while(i + 4 < tokens.count() && idxSat < N_OF_SATELLITES) {
            satellites[idxSat].prn = tokens[i++].toInt();
            satellites[idxSat].ele = tokens[i++].toInt();
            satellites[idxSat].azi = tokens[i++].toInt();
            satellites[idxSat].snr = tokens[i++].toInt();
            ++idxSat;
        }
        if(tokens[1] == tokens[2]) {
            //             printf("\t1\t2\t3\t4\t5\t6\t7\t8\t9\t10\t11\t12\t13\t14\t15\t16\t17\t18\t19\t20\n");
            //             for(int n = 0; n < N_OF_SATELLITES; ++n){
            //                 printf("\t%i",satellites[n].prn);
            //             }
            //             printf("\n");
            //             for(int n = 0; n < N_OF_SATELLITES; ++n){
            //                 printf("\t%i",satellites[n].snr);
            //             }
            //
            //             printf("\n");
        }

    }
    else if((tokens[0] == "$GPRMC")) {
        //                 0          1         2       3         4       5          6      7       8
        //         13 ("$GPRMC", "122450.539", "V", "4901.6288", "N", "01205.5946", "E", "", "", "030408", "", "", "N*76")
        //            ("$GPRMC", "183956.648", "A", "4341.0506", "N", "00407.7897", "E", "3.81", "186.84", "060408", "", "", "A", "64")
        //         qDebug() << tokens.count() << tokens[1] << tokens[9];
        datetime = QDateTime::fromString(tokens[1] + tokens[9],"hhmmss.zzzddMMyy").addYears(100);
        datetime.setTimeSpec(Qt::UTC);
        timestamp = datetime.toTime_t();

        tok = tokens[3];
        lat = tok.left(2).toInt() + tok.mid(2).toDouble() / 60.0;
        tok = tokens[5];
        lon = tok.left(3).toInt() + tok.mid(3).toDouble() / 60.0;

        lon = (tokens[6] == "E" ? lon : -lon) * DEG_TO_RAD;
        lat = (tokens[4] == "N" ? lat : -lat) * DEG_TO_RAD;

        //         fix = tokens[2] == "A";
        //         lat = 49.01 * DEG_TO_RAD;
        //         lon = 12.05 * DEG_TO_RAD;

        //         calcSecondaryData();
        //         velocity_0  = tokens[7].toFloat() * 0.514444;
        //         heading     = heading1_0 = heading2_0 = tokens[8].toFloat();

    }
    else if((tokens[0] == "$GPVTG")) {
        //                  0        1       2    3   4      5     6      7     8    9
        //          11 ("$GPVTG", "357.22", "T", "", "M", "0.09", "N", "0.16", "K", "A", "32")

        velocity    = tokens[5].toFloat() * 0.514444;
        heading     = tokens[1].toFloat();

        emit sigNewData(*this);
        //         qDebug();
    }
}
