/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "MacroParamEditor.h"

#include <QDebug>
#include <QLabel>
#include <QScrollArea>
#include <QVBoxLayout>

#include "EditorFactory.h"
#include "IconObject.h"
#include "IconFactory.h"
#include "RequestPanel.h"
#include "IconClass.h"
#include "MacroParamObject.h"

#include "MvQIconHolder.h"
#include "MvQRequestPanelWidget.h"

MvQMacroParamDropWidget::MvQMacroParamDropWidget(MacroParamEditor* owner, const std::vector<std::string>& classes, QWidget* parent) :
    QWidget(parent),
    owner_(owner)
{
    auto* layout = new QVBoxLayout(this);
    layout->setSpacing(3);
    layout->setContentsMargins(1, 1, 1, 1);

    model_ = new MvQIconHolderModel(classes, this);
    view_ = new MvQIconHolderView(model_, nullptr, this);

    QString title(tr("Icons: "));
    for (auto it = classes.begin(); it != classes.end(); ++it) {
        if (it != classes.begin()) {
            title += ", ";
        }
        title += QString::fromStdString(IconClass::find(*it).defaultName());
    }

    auto* titleLabel = new QLabel(title, this);

    layout->addWidget(titleLabel);
    layout->addWidget(view_);

    connect(view_, SIGNAL(edited()),
            this, SLOT(slotHolderEdited()));
}


void MvQMacroParamDropWidget::reset(IconObjectH obj)
{
    std::vector<IconObjectH> lst;
    lst.push_back(obj);

    // This will clear the unwanted iconobjects!!
    model_->setIcons(lst);
}


void MvQMacroParamDropWidget::slotHolderEdited()
{
    std::vector<IconObjectH> vals;
    model_->iconObjects(vals);

    if (vals.size() > 0)
        owner_->editMacro(vals[0]);
    else
        owner_->editMacro(nullptr);
}

//==============================
//
// MacroParamEditor
//
//==============================

MacroParamEditor::MacroParamEditor(const IconClass& kind, const std::string& name) :
    MvQEditor(kind, name),
    paramPanelArea_(nullptr),
    paramPanel_(nullptr)
{
    // Macro drop panel
    std::vector<std::string> mc;
    mc.emplace_back("MACRO");
    macroDropWidget_ = new MvQMacroParamDropWidget(this, mc, this);
    centralLayout_->addWidget(macroDropWidget_);

    centralLayout_->addStretch(1);

    // Params panel
    classes_.push_back(kind.name());
}

MacroParamEditor::~MacroParamEditor()
{
    deleteParamPanel();
}

void MacroParamEditor::createParamPanel()
{
    deleteParamPanel();

    if (!macro_)
        return;

    centralLayout_->setStretch(1, 0);

    paramPanelArea_ = new QScrollArea(this);
    paramPanelArea_->setWidgetResizable(true);
    centralLayout_->addWidget(paramPanelArea_, 1);

    auto* w = new MvQRequestPanelWidget(classes_, this);
    paramPanelArea_->setWidget(w);

    paramPanel_ = new RequestPanel(state_->iconClass(), w, this, false);
    paramPanel_->reset(state_->iconObject());
}

void MacroParamEditor::deleteParamPanel()
{
    if (paramPanelArea_) {
        centralLayout_->removeWidget(paramPanelArea_);
        delete paramPanelArea_;
        paramPanelArea_ = nullptr;
        centralLayout_->setStretch(1, 1);
    }
}


MacroParamObject* MacroParamEditor::macroParamObject() const
{
    IconObject* cur = current_;
    return dynamic_cast<MacroParamObject*>(cur);
}

IconObject* MacroParamEditor::copy(const std::string& /*name*/)
{
    /*IconObject* o = IconFactory::create(name, class_);
    panel_->apply();
    o->request(panel_->request());
    return o;*/
    return nullptr;
}

void MacroParamEditor::apply()
{
    if (paramPanelArea_) {
        paramPanel_->apply();
        state_->request(paramPanel_->request());
        macroParamObject()->state(state_);
    }
    else {
        MvRequest r;
        state_->request(r);
        macroParamObject()->state(state_);
    }
}

void MacroParamEditor::reset()
{
    MacroParamObject* obj = macroParamObject();
    state_ = obj->state();
    editMacro(state_->macro());
}

void MacroParamEditor::close()
{
    if (macro_)
        macro_->removeObserver(this);
    macro_ = nullptr;
    deleteParamPanel();
    state_ = nullptr;
}

void MacroParamEditor::editMacro(IconObjectH macro)
{
    if (macro_)
        macro_->removeObserver(this);

    macro_ = macro;

    if (macro) {
        macroDropWidget_->reset(macro);
        // macroArea_.add(macro);
        macro_->addObserver(this);
    }

    state_->macro(macro);

    // Update param panel
    createParamPanel();
}


void MacroParamEditor::replace(IconObjectH /*obj*/)
{
    // panel_->replace(obj);
}

void MacroParamEditor::merge(IconObjectH /*obj*/)
{
    // panel_->merge(obj);
}

void MacroParamEditor::slotIconDropped(IconObject* obj)
{
    merge(obj);
}

void MacroParamEditor::iconEdited(IconObject* /*o*/)
{
    // macroArea_.openIcon(o);
}

void MacroParamEditor::iconChanged(IconObject* o)
{
    MvQEditor::iconChanged(o);
    // editMacro(o);
}

void MacroParamEditor::iconDestroyed(IconObject* /*o*/)
{
    // editMacro(0);
}

void MacroParamEditor::iconClosed(IconObject* /*o*/)
{
    // macroArea_.closeIcon(o);
}

static EditorMaker<MacroParamEditor> editorMaker("TwoLevelsEditor");
