/* ============================================================
 *
 * 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 "GeoDataListStyle.h"

// Qt includes

#include <QDataStream>

// Local includes

#include "GeoDataTypes.h"
#include "GeoDataItemIcon.h"
#include "MarbleDirs.h"

namespace Marble
{

class Q_DECL_HIDDEN GeoDataListStylePrivate
{
public:

    GeoDataListStylePrivate();

    GeoDataListStyle::ListItemType  m_listItemType;
    QColor                          m_bgColor;

    QVector<GeoDataItemIcon*>       m_vector;
};

GeoDataListStylePrivate::GeoDataListStylePrivate()
    : m_listItemType(GeoDataListStyle::Check),
      m_bgColor(Qt::white)
{
}

GeoDataListStyle::GeoDataListStyle()
    : d(new GeoDataListStylePrivate)
{
}

GeoDataListStyle::GeoDataListStyle(const Marble::GeoDataListStyle& other)
    : GeoDataObject(other), d(new GeoDataListStylePrivate(*other.d))
{
}

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

bool GeoDataListStyle::operator==(const GeoDataListStyle& other) const
{
    if (!GeoDataObject::equals(other) ||
        d->m_bgColor != other.d->m_bgColor ||
        d->m_listItemType != other.d->m_listItemType ||
        d->m_vector.size() != other.d->m_vector.size())
    {
        return false;
    }

    QVector<GeoDataItemIcon*>::const_iterator begin = d->m_vector.constBegin();
    QVector<GeoDataItemIcon*>::const_iterator end = d->m_vector.constEnd();
    QVector<GeoDataItemIcon*>::const_iterator otherBegin = other.d->m_vector.constBegin();

    for (; begin != end; ++begin, ++otherBegin)
    {
        if (**begin != **otherBegin)
        {
            return false;
        }
    }

    return true;
}

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

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

const char* GeoDataListStyle::nodeType() const
{
    return GeoDataTypes::GeoDataListStyleType;
}

GeoDataListStyle::ListItemType GeoDataListStyle::listItemType() const
{
    return d->m_listItemType;
}

void GeoDataListStyle::setListItemType(ListItemType type)
{
    d->m_listItemType = type;
}

QColor GeoDataListStyle::backgroundColor() const
{
    return d->m_bgColor;
}

void GeoDataListStyle::setBackgroundColor(const QColor& color)
{
    d->m_bgColor = color;
}

QVector<GeoDataItemIcon*> GeoDataListStyle::itemIconList() const
{
    return d->m_vector;
}

GeoDataItemIcon* GeoDataListStyle::child(int i)
{
    return d->m_vector.at(i);
}

const GeoDataItemIcon* GeoDataListStyle::child(int i) const
{
    return d->m_vector.at(i);
}

int GeoDataListStyle::childPosition(const GeoDataItemIcon* object) const
{
    return d->m_vector.indexOf(const_cast<GeoDataItemIcon*>(object));
}

void GeoDataListStyle::append(GeoDataItemIcon* other)
{
    other->setParent(this);
    d->m_vector.append(other);
}


void GeoDataListStyle::remove(int index)
{
    d->m_vector.remove(index);
}

int GeoDataListStyle::size() const
{
    return d->m_vector.size();
}

GeoDataItemIcon& GeoDataListStyle::at(int pos)
{
    return *(d->m_vector[ pos ]);
}

const GeoDataItemIcon& GeoDataListStyle::at(int pos) const
{
    return *(d->m_vector.at(pos));
}

GeoDataItemIcon& GeoDataListStyle::last()
{
    return *(d->m_vector.last());
}

const GeoDataItemIcon& GeoDataListStyle::last() const
{
    return *(d->m_vector.last());
}

GeoDataItemIcon& GeoDataListStyle::first()
{
    return *(d->m_vector.first());
}

const GeoDataItemIcon& GeoDataListStyle::first() const
{
    return *(d->m_vector.first());
}

void GeoDataListStyle::clear()
{
    qDeleteAll(d->m_vector);
    d->m_vector.clear();
}

QVector<GeoDataItemIcon*>::Iterator GeoDataListStyle::begin()
{
    return d->m_vector.begin();
}

QVector<GeoDataItemIcon*>::Iterator GeoDataListStyle::end()
{
    return d->m_vector.end();
}

QVector<GeoDataItemIcon*>::ConstIterator GeoDataListStyle::constBegin() const
{
    return d->m_vector.constBegin();
}

QVector<GeoDataItemIcon*>::ConstIterator GeoDataListStyle::constEnd() const
{
    return d->m_vector.constEnd();
}

void GeoDataListStyle::pack(QDataStream& stream) const
{
    GeoDataObject::pack(stream);
    stream << d->m_vector.count();

    for (QVector <GeoDataItemIcon*>::const_iterator iterator = d->m_vector.constBegin();
         iterator != d->m_vector.constEnd();
         ++iterator)
    {
        const GeoDataItemIcon* itemIcon = *iterator;
        itemIcon->pack(stream);
    }
}

void GeoDataListStyle::unpack(QDataStream& stream)
{
    GeoDataObject::unpack(stream);

    int count;
    stream >> count;

    int featureId;
    stream >> featureId;

    GeoDataItemIcon* itemIcon = new GeoDataItemIcon;
    itemIcon->unpack(stream);
    d->m_vector.append(itemIcon);
}

} // namespace Marble
