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

 Copyright 2019 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 <QMenu>

#include "MvQEditorListMenu.h"
#include "Editor.h"
#include "IconClass.h"
#include "MvQIconProvider.h"

QList<Editor*> MvQEditorListMenu::editors_;
QList<MvQEditorListMenu*> MvQEditorListMenu::items_;
#ifdef __APPLE__
MvQEditorListMenu* MvQEditorListMenu::dockMenu_ = nullptr;
#endif

MvQEditorListMenu::MvQEditorListMenu(QMenu* menu) :
    QObject(menu),
    menu_(menu)
{
    // Populate
    updateMenu();

    connect(menu_, SIGNAL(triggered(QAction*)),
            this, SLOT(slotMenu(QAction*)));

    items_ << this;
}

MvQEditorListMenu::~MvQEditorListMenu()
{
    items_.removeOne(this);
}

void MvQEditorListMenu::initDockMenu()
{
#ifdef __APPLE__
    if (!dockMenu_) {
        dockMenu_ = new MvQEditorListMenu(new QMenu());
        dockMenu_->menu_->setAsDockMenu();
    }
#endif
}

void MvQEditorListMenu::add(Editor* e)
{
    Q_ASSERT(e);

    // the editor can be already in the list, e.g. when it is open and we
    // double click on its icon to raise it
    if (editors_.contains(e)) {
        return;
    }
    editors_ << e;
    sortList();

    // reload the editor list in each window
    foreach (MvQEditorListMenu* item, items_) {
        item->updateMenu();
    }
}

void MvQEditorListMenu::remove(Editor* e)
{
    if (editors_.removeAll(e) > 0) {
        sortList();

        // reload the editor list in each window
        foreach (MvQEditorListMenu* item, items_) {
            item->updateMenu();
        }
    }
}

// sort editor list by iconclass
void MvQEditorListMenu::sortList()
{
    QMap<std::string, QList<Editor*> > editorMap;
    foreach (Editor* e, editors_) {
        editorMap[e->iconClass().name()] << e;
    }

    editors_.clear();

    QMapIterator<std::string, QList<Editor*> > it(editorMap);
    while (it.hasNext()) {
        it.next();
        foreach (Editor* e, it.value()) {
            editors_ << e;
        }
    }
}

void MvQEditorListMenu::updateMenu()
{
    menu_->clear();

    for (int i = 0; i < editors_.count(); i++) {
        Editor* e = editors_[i];
        auto* ac = new QAction(menu_);
        auto name = QString::fromStdString(e->current()->fullName());
        ac->setText(name);
        ac->setIcon(MvQIconProvider::pixmap(e->iconClass(), 16));
        ac->setData(i);
        menu_->addAction(ac);
    }
}

void MvQEditorListMenu::slotMenu(QAction* ac)
{
    if (ac) {
        int idx = ac->data().toInt();
        if (idx >= 0 && idx < editors_.count()) {
            editors_[idx]->raiseIt();
            return;
        }
    }
}
