/*  Copyright (C) 2013 VATSIM Community / contributors
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BLACKSIM_XBUS_SERVICE_H
#define BLACKSIM_XBUS_SERVICE_H

//! \file

#include "datarefs.h"
#include <QObject>

//! \cond PRIVATE
#define XBUS_SERVICE_INTERFACENAME "net.vatsim.xbus.service"
#define XBUS_SERVICE_OBJECTPATH "/xbus"
//! \endcond

namespace XBus
{

    /*!
     * XBus service object which is accessible through DBus
     */
    class CService : public QObject
    {
        Q_OBJECT
        Q_CLASSINFO("D-Bus Interface", XBUS_SERVICE_INTERFACENAME)

    public:
        //! Constructor
        CService(QObject *parent);

        //! DBus interface name
        static const QString &InterfaceName()
        {
            static QString s(XBUS_SERVICE_INTERFACENAME);
            return s;
        }

        //! DBus object path
        static const QString &ObjectPath()
        {
            static QString s(XBUS_SERVICE_OBJECTPATH);
            return s;
        }

        //! Called by XPluginReceiveMessage when the model changes.
        void onAircraftModelChanged();

    signals:
        //! Emitted when the model or livery changes.
        void aircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao);

    public slots:
        //! Get full path to current aircraft model
        QString getAircraftModelPath() const;

        //! Get base filename of current aircraft model
        QString getAircraftModelFilename() const;

        //! Get path to current aircraft livery
        QString getAircraftLivery() const { return m_liveryPath.get().c_str(); }

        //! Get the ICAO code of the current aircraft model
        QString getAircraftIcaoCode() const { return m_icao.get().c_str(); }

        //! Get major version number
        int getXPlaneVersionMajor() const;

        //! Get minor version number
        int getXPlaneVersionMinor() const;

        //! Get root of X-Plane install path
        QString getXPlaneInstallationPath() const;

        //! Get full path to X-Plane preferences file
        QString getXPlanePreferencesPath() const;

        //! Get aircraft latitude in degrees
        double getLatitude() const { return m_latitude.get(); }

        //! Get aircraft longitude in degrees
        double getLongitude() const { return m_longitude.get(); }

        //! Get aircraft altitude in meters
        double getAltitudeMSL() const { return m_elevation.get(); }

        //! Get aircraft height in meters
        double getHeightAGL() const { return m_agl.get(); }

        //! Get aircraft groundspeed in meters per second
        double getGroundSpeed() const { return m_groundSpeed.get(); }

        //! Get aircraft IAS in knots
        double getIndicatedAirspeed() const { return m_indicatedAirspeed.get(); }

        //! Get aircraft TAS in meters per second
        double getTrueAirspeed() const { return m_trueAirspeed.get(); }

        //! Get aircraft pitch in degrees above horizon
        double getPitch() const { return m_pitch.get(); }

        //! Get aircraft roll in degrees
        double getRoll() const { return m_roll.get(); }

        //! Get aircraft true heading in degrees
        double getTrueHeading() const { return m_heading.get(); }

        //! Get whether any wheel is on the ground
        bool getAnyWheelOnGround() const { return m_onGroundAny.get(); }

        //! Get whether all wheels are on the ground
        bool getAllWheelsOnGround() const { return m_onGroundAll.get(); }

        //! Get the current COM1 active frequency in kHz
        int getCom1Active() const { return m_com1Active.get() * 10; }

        //! Get the current COM1 standby frequency in kHz
        int getCom1Standby() const { return m_com1Standby.get() * 10; }

        //! Get the current COM2 active frequency in kHz
        int getCom2Active() const { return m_com2Active.get() * 10; }

        //! Get the current COM2 standby frequency in kHz
        int getCom2Standby() const { return m_com2Standby.get() * 10; }

        //! Get the current transponder code in decimal
        int getTransponderCode() const { return m_xpdrCode.get(); }

        //! Get the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby, >1 active)
        int getTransponderMode() const { return m_xpdrMode.get(); }

        //! Get whether we are currently squawking ident
        bool getTransponderIdent() const { return m_xpdrIdent.get(); }

        //! Set the current COM1 active frequency in kHz
        void setCom1Active(int freq) { m_com1Active.set(freq / 10); }

        //! Set the current COM1 standby frequency in kHz
        void setCom1Standby(int freq) { m_com1Standby.set(freq / 10); }

        //! Set the current COM2 active frequency in kHz
        void setCom2Active(int freq) { m_com2Active.set(freq / 10); }

        //! Set the current COM2 standby frequency in kHz
        void setCom2Standby(int freq) { m_com2Standby.set(freq / 10); }

        //! Set the current transponder code in decimal
        void setTransponderCode(int code) { m_xpdrCode.set(code); }

        //! Set the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby, >1 active)
        void setTransponderMode(int mode) { m_xpdrMode.set(mode); }

    private:
        StringDataRef<xplane::data::sim::aircraft::view::acf_livery_path> m_liveryPath;
        StringDataRef<xplane::data::sim::aircraft::view::acf_ICAO> m_icao;
        DataRef<xplane::data::sim::flightmodel::position::latitude> m_latitude;
        DataRef<xplane::data::sim::flightmodel::position::longitude> m_longitude;
        DataRef<xplane::data::sim::flightmodel::position::elevation> m_elevation;
        DataRef<xplane::data::sim::flightmodel::position::y_agl> m_agl;
        DataRef<xplane::data::sim::flightmodel::position::groundspeed> m_groundSpeed;
        DataRef<xplane::data::sim::flightmodel::position::indicated_airspeed2> m_indicatedAirspeed;
        DataRef<xplane::data::sim::flightmodel::position::true_airspeed> m_trueAirspeed;
        DataRef<xplane::data::sim::flightmodel::position::theta> m_pitch;
        DataRef<xplane::data::sim::flightmodel::position::phi> m_roll;
        DataRef<xplane::data::sim::flightmodel::position::psi> m_heading;
        DataRef<xplane::data::sim::flightmodel::failures::onground_any> m_onGroundAny;
        DataRef<xplane::data::sim::flightmodel::failures::onground_all> m_onGroundAll;
        DataRef<xplane::data::sim::cockpit::radios::com1_freq_hz> m_com1Active;
        DataRef<xplane::data::sim::cockpit::radios::com1_stdby_freq_hz> m_com1Standby;
        DataRef<xplane::data::sim::cockpit::radios::com2_freq_hz> m_com2Active;
        DataRef<xplane::data::sim::cockpit::radios::com2_stdby_freq_hz> m_com2Standby;
        DataRef<xplane::data::sim::cockpit::radios::transponder_code> m_xpdrCode;
        DataRef<xplane::data::sim::cockpit::radios::transponder_mode> m_xpdrMode;
        DataRef<xplane::data::sim::cockpit::radios::transponder_id> m_xpdrIdent;
    };

}

#endif // guard

