/*
 * Fooyin
 * Copyright © 2023, Luke Taylor <luket@pm.me>
 *
 * Fooyin is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fooyin is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Fooyin.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <gui/widgetcontainer.h>

#include "widgets/dummy.h"

#include <gui/widgetprovider.h>

#include <QJsonArray>
#include <QJsonObject>

#include <vector>

using namespace Qt::StringLiterals;

namespace Fooyin {
WidgetContainer::WidgetContainer(WidgetProvider* widgetProvider, SettingsManager* settings, QWidget* parent)
    : FyWidget{parent}
    , m_widgetProvider{widgetProvider}
    , m_settings{settings}
{ }

FyWidget* WidgetContainer::widgetAtPosition(const QPoint& /*pos*/) const
{
    return nullptr;
}

QRect WidgetContainer::widgetGeometry(FyWidget* widget) const
{
    if(!widget) {
        return {};
    }

    return {widget->mapTo(const_cast<WidgetContainer*>(this), QPoint{}), widget->size()}; // NOLINT
}

int WidgetContainer::fullWidgetCount() const
{
    return widgetCount();
}

Qt::Orientation WidgetContainer::orientation() const
{
    return Qt::Horizontal;
}

QByteArray WidgetContainer::saveState() const
{
    return {};
}

bool WidgetContainer::restoreState(const QByteArray& /*state*/)
{
    return true;
}

void WidgetContainer::saveCopyLayoutData(QJsonObject& layout, LayoutCopyContext& context, bool isRoot)
{
    FyWidget::saveCopyLayoutData(layout, context, isRoot);

    const auto childWidgets = widgets();
    if(childWidgets.empty()) {
        return;
    }

    QJsonArray children;
    for(FyWidget* widget : childWidgets) {
        if(widget) {
            widget->saveCopyLayout(children, context, false);
        }
    }

    layout["Widgets"_L1] = children;
}

void WidgetContainer::loadWidgets(const QJsonArray& widgets)
{
    std::vector<FyWidget*> addedWidgets;

    for(const auto& widget : widgets) {
        if(!widget.isObject()) {
            continue;
        }
        const QJsonObject widgetObject = widget.toObject();

        const auto widgetName = widgetObject.constBegin().key();
        const auto childValue = widgetObject.value(widgetName);

        bool currentIsMissing{false};
        FyWidget* childWidget{nullptr};
        if(!m_widgetProvider->widgetExists(widgetName)) {
            currentIsMissing = true;
            childWidget      = new Dummy(widgetName, m_settings, this);
        }
        else {
            childWidget = m_widgetProvider->createWidget(widgetName);
        }

        if(childWidget) {
            if(childValue.isObject()) {
                childWidget->loadLayout(childValue.toObject());
            }

            if(!currentIsMissing) {
                if(auto* dummy = qobject_cast<Dummy*>(childWidget)) {
                    const QString missingName = dummy->missingName();

                    if(!missingName.isEmpty() && m_widgetProvider->canCreateWidget(missingName)) {
                        const QJsonObject missingData = dummy->missingLayoutData();
                        childWidget->deleteLater();
                        childWidget = m_widgetProvider->createWidget(missingName);

                        if(childWidget && !missingData.empty()) {
                            childWidget->loadLayout(missingData);
                        }
                    }
                }
            }

            if(childWidget) {
                addWidget(childWidget);
                addedWidgets.emplace_back(childWidget);
            }
        }
    }

    for(const auto& childWidget : addedWidgets) {
        childWidget->finalise();
    }
}
} // namespace Fooyin

#include "gui/moc_widgetcontainer.cpp"
