/**********************************************************************************************
    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 "CDlgGps.h"
#include "CCanvas.h"
#include "IGps.h"
#include "GeoMath.h"
#include "IUnit.h"

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

#ifdef DISPLAY_SMALL
#define HEIGHT 100
#else                            //DISPLAY_SMALL
#define HEIGHT 200
#endif                           //DISPLAY_SMALL

CDlgGps::CDlgGps(QWidget * parent)
: QWidget(parent)
{
    setupUi(this);

    slotNewGps(&IGps::self());
    connect(&CCanvas::self(), SIGNAL(sigNewGps(IGps*)), this, SLOT(slotNewGps(IGps*)));
}


CDlgGps::~CDlgGps()
{
}


void CDlgGps::resizeEvent(QResizeEvent * e)
{
    QWidget::resizeEvent(e);

    QSize s = size();
    graph = QPixmap(s.width(),HEIGHT);
}


void CDlgGps::slotNewGps(IGps * gps)
{
    labelSatellites->setText(gps->getSysError());
    connect(gps, SIGNAL(sigNewData(IGps&)), this, SLOT(slotNewGpsData(IGps&)));
}


void CDlgGps::slotNewGpsData(IGps& gps)
{
    QString error = gps.getSysError();

    if(!error.isEmpty()) {
        labelSatellites->setText(error);
        return;
    }

    if(!isVisible()) return;

    const IGps::sat_t * satellites = 0;
    bool hasFix = gps.getFix() != IGps::eNoFix;
    gps.getSatellites(satellites);

    graph.fill(Qt::white);

    QPainter p;
    p.begin(&graph);

    QFontMetrics fi(p.font());
    const int y1 = graph.height() - fi.height();
    const int cw = graph.width() / N_OF_SATELLITES;

    QRect rectPNR(0,0,cw - 3,fi.height());
    rectPNR.moveTo(0, y1);

    p.translate(5,0);
    p.drawLine(0,y1, graph.width() - 10, y1);

    int n,i;
    for(n = 1; n <= SATELLITES_MAX_PRN; ++n) {
        // sort by PRN
        for(i = N_OF_SATELLITES - 1; i >= 0; --i) {
            if(satellites[i].prn == n) break;
        }
        if(i == -1) continue;

        // draw PRN
        p.setPen(Qt::black);
        int prn = satellites[i].prn;
        if(prn) {
            p.drawText(rectPNR,Qt::AlignCenter,QString::number(prn));
        }

        // draw SNR bar
        QRect bar(rectPNR);
        int snr = satellites[i].snr << 1;
        snr = snr < 60 ? snr : 60;

        bar.setHeight(-snr * (y1- 8) / 60 - 2);
        bar.translate(-1,-3);

        if(hasFix) {
            p.setBrush(Qt::darkBlue);
        }
        else {
            p.setPen(QPen(Qt::red,2));
            p.setBrush(Qt::NoBrush);
        }
        p.drawRect(bar);

        rectPNR.translate(cw,0);
    }
    p.end();
    labelSatellites->setPixmap(graph);

    if(hasFix) {
        qreal lon = 0, lat = 0, ele = 0;
        gps.getPosition(lon, lat);
        gps.getElevation(ele);

        QString val, unit;
        GPS_Math_Deg_To_Str(lon * RAD_TO_DEG, lat * RAD_TO_DEG, val);
        labelPosition->setText(val);
        IUnit::self().meter2elevation(ele, val, unit);
        labelElevation->setText(QString("%1 %2").arg(val).arg(unit));

        float hdop = -1, vdop = -1;
        gps.getError(hdop, vdop);
        labelError->setText(QString("H: %1 m V: %2 m").arg(hdop,0,'f',1).arg(vdop,0,'f',1));

        qreal speed = gps.getVelocity();
        if(speed > 1.0/3.6) {
            IUnit::self().meter2speed(speed, val, unit);
            labelSpeed->setText(QString("%1 %2").arg(val).arg(unit));
        }
        else {
            labelSpeed->setText("-");
        }

        qreal heading = gps.getHeading();
        if(heading && speed > 1.0/3.6) {
            labelHeading->setText(QString("%1\260 T").arg(heading));
        }
        else {
            labelSpeed->setText("-");
        }

    }
    else {
        labelPosition->setText("-");
        labelElevation->setText("-");
        labelError->setText("H: - V: -");
    }

}
