/***************************************************************************
 *   Copyright (C) 2021 by Stefan Kebekus                                  *
 *   stefan.kebekus@gmail.com                                              *
 *                                                                         *
 *   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 3 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-1307, USA.             *
 ***************************************************************************/

#pragma once

#include "units/Angle.h"
#include "units/Distance.h"

namespace Traffic {

class TrafficDataSource_Abstract;

/*! \brief Traffic warning
 *
 *  Objects of this class represent traffic warnings, as detected by FLARM and
 *  similar devices.  The data fields correspond to the data fields sent out by
 *  FLARM devices with their PFLAU NMEA-sentences.  Instances of this class will
 *  be generated by the Navigation::TrafficDataSource_* classes. Consumers of
 *  this class will never have to set or construct instances of the class
 *  themselves
 */

class Warning {
    Q_GADGET

    friend TrafficDataSource_Abstract;

public:
    /*! \brief Default constructor */
    explicit Warning() = default;

    //
    // PROPERTIES
    //

    /*! \brief Alarm level, as reported by FLARM
     *
     * This is an integer in the range -1, …, 3 with the following
     * meaning.
     *
     *  - -1 = invalid data
     *  - 0 = no alarm (also used for no-alarm traffic information)
     *  - 1 = alarm, 13-18 seconds to impact
     *  - 2 = alarm, 9-12 seconds to impact
     *  - 3 = alarm, 0-8 seconds to impact
     *
     *  @returns alarm level
     *
     *  See the FLARM "Data Port Interface Control Document" for a further
     *  description.
     */
    [[nodiscard]] Q_INVOKABLE int alarmLevel() const
    {
        return m_alarmLevel;
    }

    /*! \brief Alarm type, as reported by FLARM
     *
     * This is an integer from the set {-1, 2, 3, 4} with the following meaning.
     *
     *  - -1 = invalid data
     *  - 2 = aircraft alarm
     *  - 3 = obstacle alarm
     *  - 4 = traffic advisory
     *
     *  Alert zone alarms are currently not supported.
     *
     *  @returns alarm type
     *
     *  See the FLARM "Data Port Interface Control Document" for a further
     *  description.
     */
    [[nodiscard]] Q_INVOKABLE int alarmType() const
    {
        return m_alarmType;
    }

    /*! \brief Translated, human-readable alarm message
     *
     *  @returns A string of the form "Traffic • 10 o'clock position • 
     *  Distance 0.4 nm • 700 ft below."
     */
    [[nodiscard]] Q_INVOKABLE QString description() const;

    /*! \brief Horizontal distance to obstacle or aircraft
     *
     *  @returns Horizontal distance, might be NaN
     */
    [[nodiscard]] Q_INVOKABLE Units::Distance hDist() const
    {
        return m_hDist;
    }

    /*! \brief Comparison
     *
     *  @param rhs Right hand side of the comparison
     *
     *  @returns True if equal
     */
    Q_INVOKABLE bool operator==(const Traffic::Warning &rhs);

    /*! \brief Direction to obstacle or aircraft
     *
     *  @returns Relative bearing, might be NaN
     */
    [[nodiscard]] Q_INVOKABLE Units::Angle relativeBearing() const
    {
        return m_relativeBearing;
    }

    /*! \brief Vertical distance to obstacle or aircraft
     *
     *  @returns Vertical distance, might be NaN
     */
    [[nodiscard]] Q_INVOKABLE Units::Distance vDist() const
    {
        return m_vDist;
    }

private:
    // Private constructor, only to be used by TrafficDataSource_Abstract
    explicit Warning(const QString& AlarmLevel,
                     const QString& RelativeBearing,
                     const QString& AlarmType,
                     const QString& RelativeVertical,
                     const QString& RelativeDistance);

    // Property values
    int m_alarmLevel {-1};
    int m_alarmType {-1};
    Units::Distance m_hDist;
    Units::Angle m_relativeBearing;
    Units::Distance m_vDist;
};

} // namespace Traffic

// Declare meta types
Q_DECLARE_METATYPE(Traffic::Warning)
