/* ============================================================
 *
 * This file is a part of digiKam project
 * https://www.digikam.org
 *
 * Date        : 2023-05-15
 * Description : geolocation engine based on Marble.
 *               (c) 2007-2022 Marble Team
 *               https://invent.kde.org/education/marble/-/raw/master/data/credits_authors.html
 *
 * SPDX-FileCopyrightText: 2023-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
 *
 * SPDX-License-Identifier: LGPL-2.1-or-later
 *
 * ============================================================ */

#include "GeoDataLabelStyle.h"

// Qt includes

#include <QFont>
#include <QColor>
#include <QDataStream>

// Local includes

#include "GeoDataTypes.h"

namespace Marble
{
#ifdef Q_OS_MACOS
static const int defaultSize = 10;
#else
static const int defaultSize = 8;
#endif

class Q_DECL_HIDDEN GeoDataLabelStylePrivate
{
public:

    GeoDataLabelStylePrivate()
        : m_scale(1.0),
          m_alignment(GeoDataLabelStyle::Corner),
          m_font(QFont(QStringLiteral("Sans Serif")).family(), defaultSize, 50, false),
          m_glow(true)
    {
    }

    explicit GeoDataLabelStylePrivate(const QFont& font)
        : m_scale(1.0),
          m_alignment(GeoDataLabelStyle::Corner),
          m_font(font),
          m_glow(true)
    {
    }

    /// The current scale of the label
    float                        m_scale;
    /// The current alignment of the label
    GeoDataLabelStyle::Alignment m_alignment;
    /// The current font of the label
    QFont                        m_font;   // Not a KML property
    /// Whether or not the text should glow
    bool                         m_glow; // Not a KML property
};

GeoDataLabelStyle::GeoDataLabelStyle()
    : d(new GeoDataLabelStylePrivate)
{
    setColor(QColor(Qt::black));
}

GeoDataLabelStyle::GeoDataLabelStyle(const GeoDataLabelStyle& other)
    : GeoDataColorStyle(other), d(new GeoDataLabelStylePrivate(*other.d))
{
}

GeoDataLabelStyle::GeoDataLabelStyle(const QFont& font, const QColor& color)
    : d(new GeoDataLabelStylePrivate(font))
{
    setColor(color);
}

GeoDataLabelStyle::~GeoDataLabelStyle()
{
    delete d;
}

GeoDataLabelStyle& GeoDataLabelStyle::operator=(const GeoDataLabelStyle& other)
{
    GeoDataColorStyle::operator=(other);
    *d = *other.d;
    return *this;
}

bool GeoDataLabelStyle::operator==(const GeoDataLabelStyle& other) const
{
    if (GeoDataColorStyle::operator!=(other))
    {
        return false;
    }

    return d->m_scale == other.d->m_scale &&
           d->m_alignment == other.d->m_alignment &&
           d->m_font == other.d->m_font &&
           d->m_glow == other.d->m_glow;
}

bool GeoDataLabelStyle::operator!=(const GeoDataLabelStyle& other) const
{
    return !this->operator==(other);
}

const char* GeoDataLabelStyle::nodeType() const
{
    return GeoDataTypes::GeoDataLabelStyleType;
}

void GeoDataLabelStyle::setAlignment(GeoDataLabelStyle::Alignment alignment)
{
    d->m_alignment = alignment;
}

GeoDataLabelStyle::Alignment GeoDataLabelStyle::alignment() const
{
    return d->m_alignment;
}

void GeoDataLabelStyle::setScale(float scale)
{
    d->m_scale = scale;
}

float GeoDataLabelStyle::scale() const
{
    return d->m_scale;
}

void GeoDataLabelStyle::setFont(const QFont& font)
{
    d->m_font = font;
}

QFont GeoDataLabelStyle::font() const
{
    return d->m_font;
}

QFont GeoDataLabelStyle::scaledFont() const
{
    // Font shouldn't be smaller (or equal to) than 0, but if it is, regular font is returned
    // setPointSize() takes an integer as parameter, so rounded value should be checked
    if (qRound(font().pointSize() * scale()) <= 0)
    {
        return font();
    }

    QFont scaledFont = font();
    scaledFont.setPointSize(qRound(scaledFont.pointSize() * scale()));
    return scaledFont;
}

bool GeoDataLabelStyle::glow() const
{
    return d->m_glow;
}

void GeoDataLabelStyle::setGlow(bool on)
{
    d->m_glow = on;
}

void GeoDataLabelStyle::pack(QDataStream& stream) const
{
    GeoDataColorStyle::pack(stream);

    stream << d->m_scale;
    stream << d->m_alignment;
    stream << d->m_font;
}

void GeoDataLabelStyle::unpack(QDataStream& stream)
{
    int a;
    GeoDataColorStyle::unpack(stream);

    stream >> d->m_scale;
    stream >> a;
    stream >> d->m_font;

    d->m_alignment = static_cast<GeoDataLabelStyle::Alignment>(a);
}

} // namespace Marble
