// SPDX-License-Identifier: LGPL-2.1-or-later
//
// SPDX-FileCopyrightText: 2010 Wes Hardaker <marble@ws6z.com>
//

#include "AprsObject.h"

#include "GeoDataLineString.h"
#include "GeoPainter.h"
#include "MarbleColors.h"
#include "MarbleDebug.h"
#include "MarbleDirs.h"

using namespace Marble;

AprsObject::AprsObject(const GeoAprsCoordinates &at, const QString &name)
    : m_myName(name)
    , m_seenFrom(at.seenFrom())
    , m_havePixmap(false)
    , m_pixmapFilename()
{
    m_history.push_back(at);
}

AprsObject::~AprsObject()
{
    delete m_pixmap;
}

GeoAprsCoordinates AprsObject::location() const
{
    return m_history.last();
}

void AprsObject::setLocation(const GeoAprsCoordinates &location)
{
    // Not ideal but it's unlikely they'll jump to the *exact* same spot again
    if (!m_history.contains(location)) {
        m_history.push_back(location);
        mDebug() << "  moved: " << m_myName.toLocal8Bit().data();
    } else {
        int index = m_history.indexOf(location);
        m_history[index].resetTimestamp();
        m_history[index].addSeenFrom(location.seenFrom());
    }

    m_seenFrom = (m_seenFrom | location.seenFrom());
}

void AprsObject::setPixmapId(QString &pixmap)
{
    QString pixmapFilename = MarbleDirs::path(pixmap);
    if (QFile(pixmapFilename).exists()) {
        m_havePixmap = true;
        m_pixmapFilename = pixmapFilename;
        // We can't load the pixmap here since it's used in a different thread
    } else {
        m_havePixmap = false;
    }
}

QColor AprsObject::calculatePaintColor(int from, const QElapsedTimer &time, int fadeTime)
{
    QColor color;
    if (from & GeoAprsCoordinates::Directly) {
        color = Oxygen::emeraldGreen4; // oxygen green if direct
    } else if ((from & (GeoAprsCoordinates::FromTCPIP | GeoAprsCoordinates::FromTTY)) == (GeoAprsCoordinates::FromTCPIP | GeoAprsCoordinates::FromTTY)) {
        color = Oxygen::burgundyPurple4; // oxygen purple if both
    } else if (from & GeoAprsCoordinates::FromTCPIP) {
        color = Oxygen::brickRed4; // oxygen red if net
    } else if (from & GeoAprsCoordinates::FromTTY) {
        color = Oxygen::seaBlue4; // oxygen blue if TNC TTY relay
    } else if (from & (GeoAprsCoordinates::FromFile)) {
        color = Oxygen::sunYellow3; // oxygen yellow if file only
    } else {
        mDebug() << "**************************************** unknown from: " << from;
        color = Oxygen::aluminumGray5; // shouldn't happen but a user
                                       // could mess up I suppose we
                                       // should at least draw it in
                                       // something.
    }

    if (fadeTime > 0 && time.elapsed() > fadeTime) { // 5 min ( 600000 ms )
        color.setAlpha(160);
    }

    return color;
}

void AprsObject::render(GeoPainter *painter, ViewportParams *viewport, int fadeTime, int hideTime)
{
    Q_UNUSED(viewport);

    if (hideTime > 0 && m_history.last().timestamp().elapsed() > hideTime)
        return;

    QColor baseColor = calculatePaintColor(m_seenFrom, m_history.last().timestamp(), fadeTime);

    if (m_history.count() > 1) {
        QList<GeoAprsCoordinates>::iterator spot = m_history.begin();
        QList<GeoAprsCoordinates>::iterator endSpot = m_history.end();

        GeoDataLineString lineString;
        lineString.setTessellate(true);
        lineString << *spot; // *spot exists because m_history.count() > 1

        for (++spot; spot != endSpot; ++spot) {
            if (hideTime > 0 && (*spot).timestamp().elapsed() > hideTime)
                break;

            lineString << *spot;

            // draw the new circle in whatever is appropriate for that point
            const QColor penColor = calculatePaintColor(spot->seenFrom(), spot->timestamp(), fadeTime);
            painter->setPen(penColor);
            painter->drawRect(*spot, 5, 5);
        }

        // draw the line in the base color
        painter->setPen(baseColor);
        painter->drawPolyline(lineString);
    }

    // Always draw the symbol then the text last so it's on top
    if (m_havePixmap) {
        if (!m_pixmap)
            m_pixmap = new QPixmap(m_pixmapFilename);
        if (m_pixmap && !m_pixmap->isNull())
            painter->drawPixmap(m_history.last(), *m_pixmap);
        else
            painter->drawRect(m_history.last(), 6, 6);
    } else
        painter->drawRect(m_history.last(), 6, 6);

    painter->setPen(baseColor);
    painter->drawText(m_history.last(), m_myName);
}
