/***************************** 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 <QApplication>
#include <QComboBox>
#include <QDebug>
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QGroupBox>
#include <QInputDialog>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QMessageBox>
#include <QPushButton>
#include <QSettings>
#include <QSplitter>
#include <QStackedWidget>
#include <QToolButton>
#include <QTreeView>
#include <QVBoxLayout>

#include "MvQKeyDialog.h"
#include "MvQKeyModel.h"
#include "MvQKeyManager.h"
#include "MvQMethods.h"
#include "MvQTreeView.h"
#include "MvQTheme.h"

#include "MvKeyProfile.h"

//===================================
//
// MvQKeyProfileDialog
//
//===================================


MvQKeyProfileDialog::MvQKeyProfileDialog(QString /*title*/, MvQKeyManager* manager, int currentRow, QWidget* parent) :
    QWidget(parent),
    manager_(manager)
{
    auto* layout = new QVBoxLayout;
    setLayout(layout);

    auto* hb = new QHBoxLayout;
    layout->addLayout(hb);

    profList_ = new QListWidget(this);
    //profList_->setAlternatingRowColors(true);
    hb->addWidget(profList_);

    auto* vb = new QVBoxLayout;
    hb->addLayout(vb);

    auto* addPb = new QPushButton(tr("&New"), this);
    addPb->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/profile_add.svg"))));
    addPb->setToolTip(tr("Add new profile"));

    auto* saveAsPb = new QPushButton(tr("Du&plicate"), this);
    saveAsPb->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/profile_duplicate.svg"))));
    saveAsPb->setToolTip(tr("Duplicate profile"));

    renamePb_ = new QPushButton(tr("&Rename ..."), this);
    renamePb_->setToolTip(tr("Rename profile"));

    deletePb_ = new QPushButton(tr("&Delete"), this);
    deletePb_->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/profile_delete.svg"))));
    deletePb_->setToolTip(tr("Delete profile"));

    vb->addWidget(addPb);
    vb->addWidget(saveAsPb);
    vb->addWidget(renamePb_);
    vb->addWidget(deletePb_);
    vb->addStretch(1);

    connect(profList_, SIGNAL(currentRowChanged(int)),
            this, SLOT(slotSelectProfile(int)));

    connect(addPb, SIGNAL(clicked()),
            this, SLOT(slotAddProfile()));

    connect(saveAsPb, SIGNAL(clicked()),
            this, SLOT(slotDuplicateProfile()));

    connect(deletePb_, SIGNAL(clicked()),
            this, SLOT(slotDeleteProfile()));

    connect(renamePb_, SIGNAL(clicked()),
            this, SLOT(slotRenameProfile()));


    init(currentRow);
}

void MvQKeyProfileDialog::init(int row)
{
    for (auto it : manager_->data()) {
        MvKeyProfile* prof = it;
        auto* item         = new QListWidgetItem(QString(prof->name().c_str()));

        if (it->systemProfile()) {
            item->setIcon(MvQTheme::logo());
        }

        profList_->addItem(item);
    }

    if (profList_->count() > 0)
        profList_->setCurrentRow(row);
}

void MvQKeyProfileDialog::slotUpdate()
{
    disconnect(profList_, SIGNAL(currentRowChanged(int)), this, 0);
    int row = profList_->currentRow();
    profList_->clear();
    init(row);
    connect(profList_, SIGNAL(currentRowChanged(int)),
            this, SLOT(slotSelectProfile(int)));
    emit dataChanged();
}

void MvQKeyProfileDialog::slotSelectProfile(int row)
{
    if (row < 0 || row >= static_cast<int>(manager_->data().size()))
        return;

    if (manager_->data().at(row)->systemProfile()) {
        deletePb_->setEnabled(false);
        renamePb_->setEnabled(false);
    }
    else {
        deletePb_->setEnabled(true);
        renamePb_->setEnabled(true);
    }

    emit currentProfileChanged(row);
}

void MvQKeyProfileDialog::slotAddProfile()
{
    bool ok;
    QString text = QInputDialog::getText(this, tr("Add profile"),
                                         tr("New profile name:"), QLineEdit::Normal,
                                         "", &ok);
    if (ok && !text.isEmpty()) {
        manager_->addProfile(text.toStdString());
        profList_->addItem(text);
        emit dataChanged();
        profList_->setCurrentRow(profList_->count() - 1);
    }
}

void MvQKeyProfileDialog::slotDeleteProfile()
{
    int index = profList_->currentRow();
    if (index < 0 || index >= static_cast<int>(manager_->data().size()))
        return;

    if (manager_->data().at(index)->systemProfile())
        return;

    QMessageBox msgBox;
    msgBox.setWindowTitle(tr("Delete profile"));

    QString str = tr("Are you sure that you want to delete profile: <b>");
    str += QString::fromStdString(manager_->data().at(index)->name());
    str += "</b>?";

    msgBox.setText(str);
    msgBox.setIcon(QMessageBox::Warning);
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Cancel);
    int ret = msgBox.exec();

    switch (ret) {
        case QMessageBox::Yes: {  //keyModel_->profileIsAboutToChange();
            //keyModel_->setKeyProfile(0);

            manager_->deleteProfile(index);

            QListWidgetItem* item = profList_->takeItem(index);
            delete item;

            emit dataChanged();

            if (index < profList_->count())
                profList_->setCurrentRow(index);
            else
                profList_->setCurrentRow(profList_->count() - 1);
            //slotSelectProfile(0);
        } break;
        case QMessageBox::Cancel:
            // Cancel was clicked
            break;
        default:
            // should never be reached
            break;
    }
}

void MvQKeyProfileDialog::slotDuplicateProfile()
{
    int index = profList_->currentRow();
    if (index < 0 || index >= static_cast<int>(manager_->data().size()) || manager_->data().size() == 0)
        return;

    bool ok;
    QString text = QInputDialog::getText(this, tr("Duplicate profile"),
                                         tr("New profile name:"), QLineEdit::Normal,
                                         "", &ok);
    if (ok && !text.isEmpty()) {
        MvKeyProfile* newProf = manager_->addProfile(text.toStdString(), manager_->data().at(index));
        newProf->setSystemProfile(false);

        profList_->addItem(text);
        emit dataChanged();
        profList_->setCurrentRow(profList_->count() - 1);
    }
}

void MvQKeyProfileDialog::slotRenameProfile()
{
    int index = profList_->currentRow();
    if (index < 0 || index >= static_cast<int>(manager_->data().size()) || manager_->data().size() == 0)
        return;

    if (manager_->data().at(index)->systemProfile())
        return;

    bool ok;
    QString text = QInputDialog::getText(this, tr("Rename profile"),
                                         tr("Profile name:"), QLineEdit::Normal,
                                         "", &ok);
    if (ok && !text.isEmpty()) {
        MvKeyProfile* prof = manager_->data().at(index);
        prof->setName(text.toStdString());
        profList_->item(index)->setData(Qt::DisplayRole, text);
        emit dataChanged();
    }
}


//=================================================
//
// MvQKeyListPag
//
//=================================================

MvQKeyListPage::MvQKeyListPage(QString /*title*/, MvQKeyManager* manager, QList<MvKeyProfile*> allKeys,
                               QWidget* parent) :
    QWidget(parent),
    manager_(manager),
    allKey_(allKeys)
{
    //setWindowTitle(title);

    auto* layout = new QVBoxLayout;
    setLayout(layout);

    //Profiles

    auto* profHb = new QHBoxLayout;
    layout->addLayout(profHb);

    auto* label = new QLabel(tr("Profile:"), this);
    profCombo_  = new QComboBox(this);
    label->setBuddy(profCombo_);
    profHb->addWidget(label);
    profHb->addWidget(profCombo_);
    profHb->addStretch(1);

    layout->addSpacing(6);

    //-----------------------------
    // Keys control
    //-----------------------------

    auto* hbPb = new QHBoxLayout;
    hbPb->setSpacing(2);
    layout->addLayout(hbPb);

    addKeyTb_ = new QToolButton(this);
    addKeyTb_->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/add.svg"))));
    addKeyTb_->setToolTip(tr("Add new key"));
    if (manager_->predefinedKeysOnly()) {
        addKeyTb_->setEnabled(false);
    }
    addKeyTb_->setAutoRaise(true);

    deleteKeyTb_ = new QToolButton(this);
    deleteKeyTb_->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/remove.svg"))));
    deleteKeyTb_->setToolTip(tr("Delete key"));
    deleteKeyTb_->setAutoRaise(true);

    moveUpKeyTb_ = new QToolButton(this);
    moveUpKeyTb_->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/arrow_up.svg"))));
    moveUpKeyTb_->setToolTip(tr("Move up key"));
    moveUpKeyTb_->setAutoRaise(true);

    moveDownKeyTb_ = new QToolButton(this);
    moveDownKeyTb_->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/arrow_down.svg"))));
    moveDownKeyTb_->setToolTip(tr("Move down key"));
    moveDownKeyTb_->setAutoRaise(true);

    editKeyTb_ = new QToolButton(this);
    editKeyTb_->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/edit.svg"))));
    editKeyTb_->setToolTip(tr("Edit key"));
    editKeyTb_->setAutoRaise(true);

    hbPb->addWidget(editKeyTb_);
    hbPb->addWidget(addKeyTb_);
    hbPb->addWidget(deleteKeyTb_);
    hbPb->addWidget(moveUpKeyTb_);
    hbPb->addWidget(moveDownKeyTb_);
    hbPb->addStretch(1);

    //-----------------------------
    // Keys in a given profile
    //-----------------------------

    splitter_ = new QSplitter(this);
    layout->addWidget(splitter_);

    auto* w = new QWidget(this);
    splitter_->addWidget(w);

    auto* vbKey = new QVBoxLayout(w);
    vbKey->setContentsMargins(0, 0, 0, 0);
    vbKey->setSpacing(4);

    keyTree_ = new QTreeView(this);
    keyTree_->setRootIsDecorated(false);
    keyTree_->setObjectName("keyTree");
    //keyTree_->setAlternatingRowColors(true);
    keyTree_->setAllColumnsShowFocus(true);
    keyTree_->setDragEnabled(true);
    keyTree_->setAcceptDrops(true);
    keyTree_->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
    vbKey->addWidget(keyTree_);

    keyModel_ = new MvQKeyModel(MvQKeyModel::ProfileContentsMode, this);
    keyTree_->setModel(keyModel_);

    //-----------------------------
    // Helper containing all the keys
    //-----------------------------

    w = new QWidget(this);
    splitter_->addWidget(w);

    auto* vbAllKey = new QVBoxLayout(w);
    vbAllKey->setContentsMargins(0, 0, 0, 0);
    vbAllKey->setSpacing(4);

    auto* comboLayout = new QHBoxLayout;

    auto* comboLabel = new QLabel(tr(" Available keys in category: "), this);
    allKeyCombo_     = new QComboBox(this);
    comboLabel->setBuddy(allKeyCombo_);

    comboLayout->addWidget(comboLabel);
    comboLayout->addWidget(allKeyCombo_, 1);
    vbAllKey->addLayout(comboLayout);

    allKeyTree_ = new QTreeView(this);
    allKeyTree_->setRootIsDecorated(false);
    allKeyTree_->setObjectName("allKeyTree");
    allKeyTree_->setAllColumnsShowFocus(true);
    allKeyTree_->setDragDropMode(QAbstractItemView::DragOnly);
    allKeyTree_->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
    vbAllKey->addWidget(allKeyTree_);

    allKeyModel_ = new MvQKeyModel(MvQKeyModel::AllKeysMode, this);
    allKeyTree_->setModel(allKeyModel_);

    //button to add key to profile

    addKeyToProfTb_ = new QPushButton(this);
    addKeyToProfTb_->setText(tr("   Add selected key to profile"));
    addKeyToProfTb_->setToolTip(tr("Add selected key to profile on the left"));
    addKeyToProfTb_->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/arrow_left.svg"))));

    QSizePolicy sPol = addKeyToProfTb_->sizePolicy();
    sPol.setHorizontalPolicy(QSizePolicy::Preferred);
    addKeyToProfTb_->setSizePolicy(sPol);

    QPalette pal = addKeyToProfTb_->palette();
    QColor col(10, 150, 10);
    pal.setColor(QPalette::Active, QPalette::Button, col);
    pal.setColor(QPalette::Active, QPalette::ButtonText, QColor(Qt::white));
    //addKeyToProfTb_->setPalette(pal);

    vbAllKey->addWidget(addKeyToProfTb_);

    //-----------------------------
    // Signals and slots
    //-----------------------------

    connect(keyTree_, SIGNAL(doubleClicked(const QModelIndex&)),
            this, SLOT(slotEditTree(const QModelIndex&)));

    connect(addKeyTb_, SIGNAL(clicked()),
            this, SLOT(slotAddKey()));

    connect(deleteKeyTb_, SIGNAL(clicked()),
            this, SLOT(slotDeleteKey()));

    connect(moveUpKeyTb_, SIGNAL(clicked()),
            this, SLOT(slotMoveUpKey()));

    connect(moveDownKeyTb_, SIGNAL(clicked()),
            this, SLOT(slotMoveDownKey()));

    connect(editKeyTb_, SIGNAL(clicked()),
            this, SLOT(slotEditKey()));

    connect(addKeyToProfTb_, SIGNAL(clicked()),
            this, SLOT(slotAddKeyToProf()));

    init();
    setAllKeyList(allKey_);

    QFont font;
    QFontMetrics fm(font);

    keyTree_->setColumnWidth(0, MvQ::textWidth(fm, "Index  "));
    keyTree_->setColumnWidth(1, MvQ::textWidth(fm, "masterTableVersionNumber  "));

    allKeyTree_->setColumnWidth(0, MvQ::textWidth(fm, "masterTableVersionNumber  "));
}

void MvQKeyListPage::init()
{
    int i = 0;
    for (auto prof : manager_->data()) {
        profCombo_->addItem(QString(prof->name().c_str()));
        if (prof->systemProfile()) {
            profCombo_->setItemIcon(i, MvQTheme::logo());
        }
        i++;
    }


    profCombo_->setCurrentIndex(-1);

    connect(profCombo_, SIGNAL(currentIndexChanged(int)),
            this, SLOT(slotSelectProfile(int)));

    if (profCombo_->count() > 0)
        profCombo_->setCurrentIndex(0);
}

void MvQKeyListPage::slotProfilesChanged()
{
    QString currentProfName = profCombo_->currentText();

    disconnect(profCombo_, SIGNAL(currentIndexChanged(int)), 0, 0);

    //Clear the profile list
    profCombo_->clear();

    int i     = 0;
    int index = -1;
    for (auto it : manager_->data()) {
        profCombo_->addItem(QString(it->name().c_str()));
        if (it->name() == currentProfName.toStdString()) {
            index = i;
        }
        if (it->systemProfile()) {
            profCombo_->setItemIcon(i, MvQTheme::logo());
        }
        i++;
    }

    profCombo_->setCurrentIndex(-1);

    connect(profCombo_, SIGNAL(currentIndexChanged(int)),
            this, SLOT(slotSelectProfile(int)));

    if (index != -1) {
        profCombo_->setCurrentIndex(index);
    }
    else {
        profCombo_->setCurrentIndex(0);
    }
}

void MvQKeyListPage::slotChangeCurrentProfile(int row)
{
    profCombo_->setCurrentIndex(row);
}

void MvQKeyListPage::slotSelectProfile(int row)
{
    if (row < 0 || row >= static_cast<int>(manager_->data().size()))
        return;

    MvKeyProfile* prof = manager_->data().at(row);

    keyModel_->profileIsAboutToChange();
    keyModel_->setKeyProfile(prof);

    if (prof->systemProfile()) {
        keyTree_->setEnabled(false);
        //keyTree_->setDragEnabled(false);
        //keyTree_->setAcceptDrops(false);
        addKeyTb_->setEnabled(false);
        deleteKeyTb_->setEnabled(false);
        moveUpKeyTb_->setEnabled(false);
        moveDownKeyTb_->setEnabled(false);
        editKeyTb_->setEnabled(false);
        addKeyToProfTb_->setEnabled(false);
    }
    else {
        keyTree_->setEnabled(true);
        //keyTree_->setDragEnabled(true);
        //keyTree_->setAcceptDrops(true);
        if (!manager_->predefinedKeysOnly()) {
            addKeyTb_->setEnabled(true);
        }
        deleteKeyTb_->setEnabled(true);
        moveUpKeyTb_->setEnabled(true);
        moveDownKeyTb_->setEnabled(true);
        editKeyTb_->setEnabled(true);
        addKeyToProfTb_->setEnabled(true);
    }
}

void MvQKeyListPage::slotAddKey()
{
    MvKeyProfile* prof = keyModel_->profile();

    if (prof == 0)  //|| !index.isValid())
        return;

    auto* key = new MvKey;
    MvQKeyEditDialog keyDialog(key);

    if (keyDialog.exec() == QDialog::Accepted && !key->name().empty()) {
        keyModel_->profileIsAboutToChange();
        prof->addKey(key);
        keyModel_->setKeyProfile(prof);
    }
    else {
        delete key;
    }
}

void MvQKeyListPage::slotDeleteKey()
{
    MvKeyProfile* prof = keyModel_->profile();
    QModelIndex index  = keyTree_->currentIndex();

    if (prof == 0 || !index.isValid())
        return;

    QString str = tr("Are you sure that you want to delete key: <b>");
    str += QString::fromStdString(prof->at(index.row())->name());
    str += "</b>?";

    QMessageBox msgBox;
    msgBox.setWindowTitle(tr("Delete key"));
    msgBox.setText(str);
    msgBox.setIcon(QMessageBox::Warning);
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Cancel);
    int ret = msgBox.exec();

    switch (ret) {
        case QMessageBox::Yes: {
            keyModel_->profileIsAboutToChange();
            prof->deleteKey(index.row());
            keyModel_->setKeyProfile(prof);
        } break;
        case QMessageBox::Cancel:
            // Cancel was clicked
            break;
        default:
            // should never be reached
            break;
    }
}

void MvQKeyListPage::slotMoveUpKey()
{
    MvKeyProfile* prof = keyModel_->profile();
    QModelIndex index  = keyTree_->currentIndex();

    if (prof == 0 || !index.isValid())
        return;

    if (index.row() > 0) {
        keyModel_->profileIsAboutToChange();
        prof->reposition(index.row(), index.row() - 1);
        keyModel_->setKeyProfile(prof);
        keyTree_->setCurrentIndex(keyModel_->index(index.row() - 1, 0));
    }
}

void MvQKeyListPage::slotMoveDownKey()
{
    MvKeyProfile* prof = keyModel_->profile();
    QModelIndex index  = keyTree_->currentIndex();

    if (prof == 0 || !index.isValid())
        return;

    if (index.row() < static_cast<int>(prof->size()) - 1) {
        keyModel_->profileIsAboutToChange();
        prof->reposition(index.row(), index.row() + 1);
        keyModel_->setKeyProfile(prof);
        keyTree_->setCurrentIndex(keyModel_->index(index.row() + 1, 0));
    }
}

void MvQKeyListPage::slotEditKey()
{
    MvKeyProfile* prof = keyModel_->profile();
    QModelIndex index  = keyTree_->currentIndex();

    if (prof == 0 || !index.isValid())
        return;

    if (index.row() <= static_cast<int>(prof->size()) - 1) {
        MvQKeyEditDialog edit(prof->at(index.row()));
        if (edit.exec() == QDialog::Accepted) {
            //Not too efficient
            keyModel_->profileIsAboutToChange();
            keyModel_->setKeyProfile(prof);
        }
    }
}

void MvQKeyListPage::slotEditTree(const QModelIndex& /*index*/)
{
    slotEditKey();
}

void MvQKeyListPage::slotAddKeyToProf()
{
    MvKeyProfile* allProf = allKeyModel_->profile();
    QModelIndex index     = allKeyTree_->currentIndex();

    if (allProf == 0 || !index.isValid())
        return;

    MvKeyProfile* prof = keyModel_->profile();
    if (prof) {
        MvKey* key = allProf->at(index.row())->clone();

        keyModel_->profileIsAboutToChange();
        prof->addKey(key);
        keyModel_->setKeyProfile(prof);
    }
}

void MvQKeyListPage::setAllKeyList(QList<MvKeyProfile*> allKeys)
{
    allKeyTree_->setModel(allKeyModel_);

    allKey_ = allKeys;

    foreach (MvKeyProfile* prof, allKey_) {
        allKeyCombo_->addItem(QString::fromStdString(prof->name()));
    }

    allKeyCombo_->setCurrentIndex(-1);

    connect(allKeyCombo_, SIGNAL(currentIndexChanged(int)),
            this, SLOT(slotSelectAllKeyGroup(int)));

    allKeyCombo_->setCurrentIndex(0);
}

void MvQKeyListPage::slotSelectAllKeyGroup(int index)
{
    if (index >= 0 && index < allKey_.count()) {
        allKeyModel_->profileIsAboutToChange();
        allKeyModel_->setKeyProfile(allKey_[index]);
    }
}

void MvQKeyListPage::writeSettings(QSettings& settings)
{
    settings.beginGroup("keyListPage");
    settings.setValue("splitter", splitter_->saveState());
    settings.setValue("allKeyCombo", allKeyCombo_->currentText());
    MvQ::saveTreeColumnWidth(settings, "keyTreeColumnWidth", keyTree_);
    MvQ::saveTreeColumnWidth(settings, "allKeyTreeColumnWidth", allKeyTree_);
    settings.endGroup();
}

void MvQKeyListPage::readSettings(QSettings& settings)
{
    settings.beginGroup("keyListPage");
    splitter_->restoreState(settings.value("splitter").toByteArray());
    MvQ::initComboBox(settings, "allKeyCombo", allKeyCombo_);
    MvQ::initTreeColumnWidth(settings, "keyTreeColumnWidth", keyTree_);
    MvQ::initTreeColumnWidth(settings, "allKeyTreeColumnWidth", allKeyTree_);
    settings.endGroup();
}

MvQKeyImportPage::MvQKeyImportPage(QString /*title*/, MvQKeyManager* manager, QWidget* parent) :
    QWidget(parent),
    manager_(manager)
{
    MvQKeyManager::KeyType type = MvQKeyManager::GribType;

    inManager_ = new MvQKeyManager(type);
    inManager_->loadProfiles();

    QLabel* label;

    auto* layout = new QVBoxLayout;
    setLayout(layout);

    auto* hb = new QHBoxLayout;
    layout->addLayout(hb);

    label = new QLabel(tr("Profiles in GribExaminer:"), this);
    hb->addWidget(label);

    auto* hbMain = new QHBoxLayout;
    layout->addLayout(hbMain);

    profList_ = new QListWidget(this);
    hbMain->addWidget(profList_);

    auto* vb = new QVBoxLayout;
    hbMain->addLayout(vb);

    auto* importPb = new QPushButton(tr("&Import"), this);
    importPb->setIcon(QIcon(QPixmap(QString::fromUtf8(":/keyDialog/profile_import.svg"))));
    importPb->setToolTip(tr("Import selected profiles"));

    auto* selectAllPb = new QPushButton(tr("&Select all"), this);
    selectAllPb->setToolTip(tr("Select all profiles"));

    auto* unselectAllPb = new QPushButton(tr("&Unselect all"), this);
    unselectAllPb->setToolTip(tr("Unselect all profiles"));

    vb->addWidget(importPb);
    vb->addWidget(selectAllPb);
    vb->addWidget(unselectAllPb);
    vb->addStretch(1);

    connect(importPb, SIGNAL(clicked()),
            this, SLOT(slotImport()));

    connect(selectAllPb, SIGNAL(clicked()),
            this, SLOT(slotSelectAll()));

    connect(unselectAllPb, SIGNAL(clicked()),
            this, SLOT(slotUnselectAll()));

    init();
}

MvQKeyImportPage::~MvQKeyImportPage()
{
    delete inManager_;
}

void MvQKeyImportPage::init()
{
    //QStringList items;
    for (auto prof : inManager_->data()) {
        auto* item = new QListWidgetItem(profList_);
        item->setText(QString(prof->name().c_str()));

        if (prof->systemProfile()) {
            item->setFlags(Qt::NoItemFlags);
            item->setIcon(MvQTheme::logo());
        }
        else {
            item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
            item->setCheckState(Qt::Unchecked);
        }
    }

    if (profList_->count() > 0)
        profList_->setCurrentRow(0);
}

void MvQKeyImportPage::slotSelectAll()
{
    for (int i = 0; i < profList_->count(); i++) {
        if (profList_->item(i)->flags() & Qt::ItemIsUserCheckable)
            profList_->item(i)->setCheckState(Qt::Checked);
    }
}

void MvQKeyImportPage::slotUnselectAll()
{
    for (int i = 0; i < profList_->count(); i++) {
        if (profList_->item(i)->flags() & Qt::ItemIsUserCheckable)
            profList_->item(i)->setCheckState(Qt::Unchecked);
    }
}

void MvQKeyImportPage::slotImport()
{
    bool done = false;
    for (int i = 0; i < profList_->count(); i++) {
        if (profList_->item(i)->flags() & Qt::ItemIsUserCheckable &&
            profList_->item(i)->checkState() == Qt::Checked) {
            MvKeyProfile* prof = inManager_->data().at(i);
            std::string name   = prof->name();

            QString qsName(name.c_str());
            qsName = manager_->findUniqueProfileName(qsName);

            manager_->addProfile(qsName.toStdString(), prof, inManager_->keyType());
            done = true;
        }
    }

    if (done)
        emit dataChanged();
}

MvQKeyEditDialog::MvQKeyEditDialog(MvKey* key, QWidget* parent) :
    QDialog(parent),
    key_(key)
{
    setWindowTitle(tr("Edit key"));

    auto* layout = new QVBoxLayout;
    setLayout(layout);

    auto* grid = new QGridLayout;
    layout->addLayout(grid);

    int row = 0;

    grid->addWidget(new QLabel(tr("Name:")), row, 0);
    nameLe_ = new QLineEdit(key->name().c_str(), this);
    if (!key->editable()) {
        nameLe_->setReadOnly(true);
        nameLe_->setToolTip(tr("Read only item!"));
    }
    grid->addWidget(nameLe_, row, 1);
    row++;

    grid->addWidget(new QLabel(tr("Header:"), this), row, 0);
    shortLe_ = new QLineEdit(key->shortName().c_str(), this);
    grid->addWidget(shortLe_, row, 1);
    row++;

    grid->addWidget(new QLabel(tr("Description:"), this), row, 0);
    descLe_ = new QLineEdit(key->description().c_str(), this);
    if (!key->editable()) {
        descLe_->setReadOnly(true);
        descLe_->setToolTip(tr("Read only item!"));
    }
    grid->addWidget(descLe_, row, 1);
    row++;

    //colourCb_=0;

    for (auto it = key->metaData().begin(); it != key->metaData().end(); it++) {
        QWidget* w;

        grid->addWidget(new QLabel(QString::fromStdString(it->first) + ":", this), row, 0);
        /*if(it->first == "colour" && !colourCb_)
		{
			colourCb_ = new QComboBox;
			colourCb_->setStandardColors();
			colourCb_->setColorDialogEnabled(true);
			colourCb_->setCurrentColor(QColor(QString::fromStdString(it->second)));
			w=colourCb_;
		}
		else
		{*/
        metaLe_[it->first] = new QLineEdit(QString::fromStdString(it->second), this);
        if (!key->editable()) {
            metaLe_[it->first]->setReadOnly(true);
            metaLe_[it->first]->setToolTip(tr("Read only item!"));
        }
        w = metaLe_[it->first];
        //}

        grid->addWidget(w, row, 1);
        row++;
    }

    auto* buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);

    connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
    connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

    layout->addWidget(buttonBox);
}

MvQKeyEditDialog::~MvQKeyEditDialog() = default;

void MvQKeyEditDialog::accept()
{
    key_->setName(nameLe_->text().toStdString());
    key_->setShortName(shortLe_->text().toStdString());
    key_->setDescription(descLe_->text().toStdString());
    QMapIterator<std::string, QLineEdit*> it(metaLe_);
    while (it.hasNext()) {
        it.next();
        key_->setMetaData(it.key(), it.value()->text().toStdString());
    }

    /*if(colourCb_)
	{
		key_->setMetaData("colour",colourCb_->currentColor().name().toStdString());
	}*/

    QDialog::accept();
}

void MvQKeyEditDialog::reject()
{
    QDialog::reject();
}


//======================================
//
// MvQKeyDialog
//
//=======================================

MvQKeyDialog::MvQKeyDialog(QString title, MvQKeyManager::KeyType type,
                           MvQKeyManager* manager, int currentRow, QList<MvKeyProfile*> allKeys,
                           QWidget* parent) :
    MvQConfigDialog(title, parent),
    manager_(manager)
{
#ifdef ECCODES_UI
    settingsName_ = "codesui-MvQKeyDialog_" + manager->keyTypeName(type);
#else
    settingsName_ = "mv-MvQKeyDialog_" + manager->keyTypeName(type);
#endif

    profPage_ = new MvQKeyProfileDialog("Profiles", manager_, currentRow, this);
    QIcon iconProf(QPixmap(QString::fromUtf8(":/keyDialog/profile.svg")));
    addPage(profPage_, iconProf, "Profiles");

    keyPage_ = new MvQKeyListPage("Keys", manager_, allKeys, this);
    QIcon iconKey(QPixmap(QString::fromUtf8(":/keyDialog/key.svg")));
    addPage(keyPage_, iconKey, "Keys");

    connect(profPage_, SIGNAL(currentProfileChanged(int)),
            keyPage_, SLOT(slotChangeCurrentProfile(int)));

    connect(profPage_, SIGNAL(dataChanged()),
            keyPage_, SLOT(slotProfilesChanged()));

    keyPage_->slotChangeCurrentProfile(currentRow);

    if (type == MvQKeyManager::FrameType) {
        auto* importPage = new MvQKeyImportPage("Import from GribExaminer", manager_, this);
        QIcon iconImport(QPixmap(QString::fromUtf8(":/keyDialog/profile_import.svg")));
        addPage(importPage, iconImport, "Import");

        connect(importPage, SIGNAL(dataChanged()),
                profPage_, SLOT(slotUpdate()));
    }

    readSettings();
}


MvQKeyDialog::~MvQKeyDialog()
{
    writeSettings();
}

void MvQKeyDialog::accept()
{
    QDialog::accept();
}

void MvQKeyDialog::reject()
{
    QDialog::reject();
}

void MvQKeyDialog::writeSettings()
{
    QSettings settings(MVQ_QSETTINGS_DEFAULT_ARGS, settingsName_);

    settings.beginGroup("dialog");
    settings.setValue("size", size());
    settings.setValue("currentRow", list_->currentRow());

    settings.endGroup();

    keyPage_->writeSettings(settings);
}

void MvQKeyDialog::readSettings()
{
    QSettings settings(MVQ_QSETTINGS_DEFAULT_ARGS, settingsName_);

    settings.beginGroup("dialog");

    if (settings.contains("size")) {
        resize(settings.value("size").toSize());
    }
    else {
        resize(QSize(750, 540));
    }

    int ival;
    if (settings.value("currentRow").isNull()) {
        ival = 1;
    }
    else {
        ival = settings.value("currentRow").toInt();
    }

    list_->setCurrentRow(ival);

    settings.endGroup();

    keyPage_->readSettings(settings);
}
