// SPDX-FileCopyrightText: 2014 Torsten Dreyer
// SPDX-License-Identifier: GPL-2.0-or-later

#include "CurrentWeatherATISInformationProvider.hxx"
#include <Main/fg_props.hxx>

using std::string;

CurrentWeatherATISInformationProvider::CurrentWeatherATISInformationProvider(const std::string& airportId) : _airportId(airportId),
                                                                                                             _environment(fgGetNode("/environment"))
{
}

static inline int roundToInt(double d)
{
    return (static_cast<int>(10.0 * (d + .5))) / 10;
}

static inline int roundToInt(SGPropertyNode_ptr n)
{
    return roundToInt(n->getDoubleValue());
}

static inline int roundToInt(SGPropertyNode_ptr n, const char* child)
{
    return roundToInt(n->getNode(child, true));
}


CurrentWeatherATISInformationProvider::~CurrentWeatherATISInformationProvider()
{
}

bool CurrentWeatherATISInformationProvider::isValid() const
{
    return true;
}

string CurrentWeatherATISInformationProvider::airportId() const
{
    return _airportId;
}

long CurrentWeatherATISInformationProvider::getTime() const
{
    int h = fgGetInt("/sim/time/utc/hour", 12);
    int m = 20 + fgGetInt("/sim/time/utc/minute", 0) / 30; // fake twice per hour
    return makeAtisTime(0, h, m);
}

int CurrentWeatherATISInformationProvider::getWindDeg() const
{
    // round to 10 degs
    int i = 5 + roundToInt(_environment->getNode("config/boundary/entry[0]/wind-from-heading-deg", true));
    i /= 10;
    return i * 10;
}

int CurrentWeatherATISInformationProvider::getWindSpeedKt() const
{
    return roundToInt(_environment, "config/boundary/entry[0]/wind-speed-kt");
}

int CurrentWeatherATISInformationProvider::getGustsKt() const
{
    return 0;
}

int CurrentWeatherATISInformationProvider::getQnh() const
{
    // TODO: Calculate QNH correctly from environment
    return roundToInt(_environment->getNode("pressure-sea-level-inhg", true)->getDoubleValue() * SG_INHG_TO_PA / 100);
}

double CurrentWeatherATISInformationProvider::getQnhInHg() const
{
    // TODO: Calculate QNH correctly from environment
    return _environment->getNode("pressure-sea-level-inhg", true)->getDoubleValue();
}

bool CurrentWeatherATISInformationProvider::isCavok() const
{
    return false;
}

int CurrentWeatherATISInformationProvider::getVisibilityMeters() const
{
    return roundToInt(_environment, "ground-visibility-m");
}

string CurrentWeatherATISInformationProvider::getPhenomena() const
{
    return "";
}

ATISInformationProvider::CloudEntries CurrentWeatherATISInformationProvider::getClouds()
{
    using simgear::PropertyList;

    ATISInformationProvider::CloudEntries cloudEntries;
    PropertyList layers = _environment->getNode("clouds", true)->getChildren("layer");
    for (PropertyList::iterator it = layers.begin(); it != layers.end(); ++it) {
        string coverage = (*it)->getStringValue("coverage", "clear");
        int alt = roundToInt((*it)->getDoubleValue("elevation-ft", -9999)) / 100;
        alt *= 100;

        if (coverage != "clear" && alt > 0)
            cloudEntries[alt] = coverage;
    }
    return cloudEntries;
}

int CurrentWeatherATISInformationProvider::getTemperatureDeg() const
{
    return roundToInt(_environment, "temperature-sea-level-degc");
}

int CurrentWeatherATISInformationProvider::getDewpointDeg() const
{
    return roundToInt(_environment, "dewpoint-sea-level-degc");
}

string CurrentWeatherATISInformationProvider::getTrend() const
{
    return "nosig";
}
