/**********************************************************************************************
    Copyright (C) 2008 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., 59 Temple Place - Suite 330, Boston, MA 02111 USA

**********************************************************************************************/
#ifndef CTRACK_H
#define CTRACK_H


#include <QFile>
#include <QVector>

#include "CWpt.h"

#define CHUNKSIZE   10000

/**
    In general the track size is only limited by the available SD memory. However for performance reasons
    only the last CHUNKSIZE track points are kept in RAM. Only trackpoints in RAM are displayed as overlay.

    A track is stored on SD RAM in several files. The header file is named "trackname.trk" and each trackpoint
    chunk is stored as "trackname_n.trkpt". With n = 0..N, 0 holding the oldest points and N the last ones.

    All data is stored as binary via the QDataStream object. The header format is:

    <pre>
    QString key             /// unique key to identify the track
    quint32 timestamp       /// creation timestamp
    QString name            /// track name to display in a list
    QString comment         /// some userdefined comment
    quint32 colorIdx        /// color of the track
    quint32 next            /// zero to terminate header file or an enumeration to define additional data
    </pre>

    Each chunk stores one trackpoint after the other. The current trackpoint definition is not appendable itself.
    If you want to store additional data you have to add a notifier into the header and write the additional data
    into it's own chunk file. A track point is stored as:

    <pre>
    float   lon [°]
    float   lat [°]
    float   ele [m]
    quit32  timestamp
    quint32 flags
    </pre>

    Extended data per track point (in own file)

    <pre>
    float   altitude [m]
    float   height [m]
    float   velocity [m/s]
    float   heading  [°]
    float   magnetic [°]
    float   vdop
    float   hdop
    float   pdop
    float   x;          ///< [m] cartesian gps coordinate
    float   y;          ///< [m] cartesian gps coordinate
    float   z;          ///< [m] cartesian gps coordinate
    float   vx;         ///< [m/s] velocity
    float   vy;         ///< [m/s] velocity
    float   vz;         ///< [m/s] velocity
    </pre>


*/

struct STrackPoint
{
    STrackPoint() : lon(WPT_NOFLOAT), lat(WPT_NOFLOAT), ele(WPT_NOFLOAT), timestamp(0), flags(0){}
    float   lon;        ///< [rad]
    float   lat;        ///< [rad]
    float   ele;        ///< [m]
    quint32 timestamp;
    quint32 flags;      ///< see CTrack::flags_e
};

struct STrackExt1
{
    STrackExt1() : altitude(WPT_NOFLOAT), height(WPT_NOFLOAT), velocity(WPT_NOFLOAT), heading(WPT_NOFLOAT), magnetic(WPT_NOFLOAT),
                   vdop(WPT_NOFLOAT), hdop(WPT_NOFLOAT), pdop(WPT_NOFLOAT), x(WPT_NOFLOAT), y(WPT_NOFLOAT), z(WPT_NOFLOAT),
                   vx(WPT_NOFLOAT), vy(WPT_NOFLOAT), vz(WPT_NOFLOAT){}
    float   altitude;   ///< [m] Altitude, Meters, above mean sea level
    float   height;     ///< [m] Height of geoid (mean sea level) above WGS84 ellipsoid
    float   velocity;   ///< [m/s] Ground speed, meters per hour
    float   heading;    ///< [°] Track angle in degrees True
    float   magnetic;   ///< [°] Magnetic Variation
    float   vdop;       ///< Vertical dilution of precision (VDOP)
    float   hdop;       ///< Horizontal dilution of precision (HDOP)
    float   pdop;       ///< PDOP (dilution of precision)
    float   x;          ///< [m] cartesian gps coordinate
    float   y;          ///< [m] cartesian gps coordinate
    float   z;          ///< [m] cartesian gps coordinate
    float   vx;         ///< [m/s] velocity
    float   vy;         ///< [m/s] velocity
    float   vz;         ///< [m/s] velocity
};

class CTrack
{
    public:
        CTrack();
        virtual ~CTrack();

        enum type_e {eEnd,eBase,eTrkPts,eTrkExt1};

        //track head data
        quint32 timestamp;
        QString name;
        QString comment;
        quint32 colorIdx;
        quint32 trackid;
        QString dbKey;
        QString distance;

        enum flags_e
        {
             e2DFix = 0x00010000
            ,e3DFix = 0x00020000
        };


        const QString& key();

        void operator <<(STrackPoint& trkpt);
        void operator <<(STrackExt1& trkpt);

        static const QColor lineColors[];

    private:
        friend QDataStream& operator >>(QDataStream& s, CTrack& track);
        friend QDataStream& operator <<(QDataStream& s, CTrack& track);
        friend class CTrackDB;

        void genKey();
        QString _key_;

        QVector<STrackPoint> trkpts;
        QVector<STrackExt1> trkext1;
};

extern STrackPoint trackbuffer[];
extern quint32     trackIdx;
extern STrackPoint trackbuffer1[];
extern quint32     trackIdx1;

extern QDataStream& operator >>(QDataStream& s, CTrack& track);
extern QDataStream& operator <<(QDataStream& s, CTrack& track);

extern void operator >>(QFile& s, CTrack& track);
extern void operator <<(QFile& s, CTrack& track);


#endif //CTRACK_H
