/***************************** 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 <QFileIconProvider>
#include <QFileSystemModel>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QListView>
#include <QPushButton>
#include <QSettings>
#include <QTextEdit>
#include <QToolButton>
#include <QVBoxLayout>

#include "MvQPlaceMarkDialog.h"
#include "MvQPlaceMark.h"
#include "MvQMethods.h"

class MvQPmFileIconProvider : public QFileIconProvider
{
public:
    MvQPmFileIconProvider(){};
    QIcon icon(const QFileInfo& info) const;
};

QIcon MvQPmFileIconProvider::icon(const QFileInfo& info) const
{
    QString suffix = info.suffix();
    if (suffix != "png") {
        return QFileIconProvider::icon(info);
    }

    return QIcon(info.absoluteFilePath());
}


MvQIconSelector::MvQIconSelector(QString path, QWidget* parent) :
    QDialog(parent),
    path_(path)
{
    setWindowTitle(tr("Select Icon"));

    QVBoxLayout* layout = new QVBoxLayout;

    QDir dir(path_);
    QFileInfoList dirs = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::Dirs);

    if (dirs.count() == 0)
        QDialog::reject();


    QHBoxLayout* hb = new QHBoxLayout;

    QLabel* label       = new QLabel(tr("Categories:"));
    QComboBox* dirCombo = new QComboBox;
    foreach (QFileInfo info, dirs) {
        dirCombo->addItem(info.baseName());
    }

    connect(dirCombo, SIGNAL(currentIndexChanged(QString)),
            this, SLOT(slotCategoryChanged(QString)));

    hb->addWidget(label);
    hb->addWidget(dirCombo);
    layout->addLayout(hb);

    QStringList filter;
    filter << "*.png";

    fsModel_ = new QFileSystemModel;
    fsModel_->setNameFilters(filter);
    //	QModelIndex rootIndex=fsModel_->setRootPath(path);

    MvQPmFileIconProvider* iconProvider = new MvQPmFileIconProvider;
    fsModel_->setIconProvider(iconProvider);

    listView_ = new QListView(this);
    listView_->setViewMode(QListView::IconMode);
    listView_->setFlow(QListView::LeftToRight);
    listView_->setGridSize(QSize(90, 60));
    listView_->setResizeMode(QListView::Adjust);
    listView_->setModel(fsModel_);

    //This will set the rootindex for the listview
    if (dirCombo->currentIndex() != 0) {
        dirCombo->setCurrentIndex(0);
    }
    else {
        slotCategoryChanged(dirCombo->itemText(0));
    }

    //listView_->setRootIndex(rootIndex);

    connect(listView_, SIGNAL(clicked(const QModelIndex&)),
            this, SLOT(slotSelectIcon(const QModelIndex&)));

    layout->addWidget(listView_);

    //-----------------------------
    // Buttonbox
    //-----------------------------

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


    layout->addWidget(buttonBox);


    setLayout(layout);

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

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

MvQIconSelector::~MvQIconSelector()
{
}

void MvQIconSelector::slotCategoryChanged(const QString& catName)
{
    QString catPath      = path_ + catName;
    QModelIndex catIndex = fsModel_->index(catPath);
    listView_->setRootIndex(catIndex);
}

void MvQIconSelector::slotSelectIcon(const QModelIndex& index)
{
    selection_ = fsModel_->filePath(index);
}

void MvQIconSelector::accept()
{
    hide();

    emit iconChanged(selection_);
}

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

void MvQIconSelector::writeSettings()
{
}

void MvQIconSelector::readSettings()
{
}

MvQPlaceMarkDialog::MvQPlaceMarkDialog(MvQPlaceMarkNode* pm, QString iconPath, QWidget* parent) :
    QDialog(parent),
    pm_(pm),
    systemIconPath_(iconPath)
{
    //setAttribute(Qt::WA_DeleteOnClose);

    setWindowTitle(tr("PlaceMark Dialog"));

    QLabel* label;
    QLineEdit* lEdit;
    QTextEdit* tEdit;
    QToolButton* tb;

    QVBoxLayout* layout = new QVBoxLayout;

    QGridLayout* grid = new QGridLayout;
    int cnt           = 0;

    //Name
    label         = new QLabel(tr("Name:"), this);
    lEdit         = new QLineEdit(pm_->name(), this);
    elem_["name"] = lEdit;

    grid->addWidget(label, cnt, 0);
    grid->addWidget(elem_["name"], cnt, 1);
    cnt++;

    //XPos
    label         = new QLabel(tr("X-position:"), this);
    lEdit         = new QLineEdit(QString::number(pm_->coordinates().x()), this);
    elem_["xpos"] = lEdit;

    grid->addWidget(label, cnt, 0);
    grid->addWidget(elem_["xpos"], cnt, 1);
    cnt++;

    //YPos
    label         = new QLabel(tr("Y-position:"), this);
    lEdit         = new QLineEdit(QString::number(pm_->coordinates().y()), this);
    elem_["ypos"] = lEdit;

    grid->addWidget(label, cnt, 0);
    grid->addWidget(elem_["ypos"], cnt, 1);
    cnt++;

    //icon
    label = new QLabel(tr("Icon:"), this);
    tb    = new QToolButton(this);
    pix_  = pm_->pixmap();
    tb->setIcon(pix_);
    elem_["icon"] = tb;

    grid->addWidget(label, cnt, 0);
    grid->addWidget(elem_["icon"], cnt, 1);
    cnt++;

    //Description
    label         = new QLabel(tr("Description:"), this);
    tEdit         = new QTextEdit(pm_->description(), this);
    elem_["desc"] = tEdit;

    grid->addWidget(label, cnt, 0);
    grid->addWidget(elem_["desc"], cnt, 1, 3, 1);
    cnt++;

    layout->addLayout(grid);

    //-----------------------------
    // Buttonbox
    //-----------------------------

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


    layout->addWidget(buttonBox);


    setLayout(layout);

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

    connect(elem_["icon"], SIGNAL(clicked(bool)),
            this, SLOT(slotLoadIconSelector(bool)));

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


MvQPlaceMarkDialog::~MvQPlaceMarkDialog()
{
}

void MvQPlaceMarkDialog::slotLoadIconSelector(bool)
{
    //The dialog will set the node!!!
    MvQIconSelector dialog(systemIconPath_);

    connect(&dialog, SIGNAL(iconChanged(QString)),
            this, SLOT(slotIconChanged(QString)));


    if (dialog.exec() == QDialog::Accepted) {
        //We update the model (this will will update the view)
        //model_->updateItem(view_->currentIndex());
    }
}

void MvQPlaceMarkDialog::slotIconChanged(QString iconPath)
{
    if (iconPath.isEmpty())
        return;


    pix_            = QPixmap(iconPath);
    QToolButton* tb = static_cast<QToolButton*>(elem_["icon"]);
    tb->setIcon(pix_);
}

void MvQPlaceMarkDialog::accept()
{
    QLineEdit* lEdit;
    QTextEdit* tEdit;

    lEdit = static_cast<QLineEdit*>(elem_["name"]);
    pm_->setName(lEdit->text());

    lEdit     = static_cast<QLineEdit*>(elem_["xpos"]);
    double xp = lEdit->text().toFloat();

    lEdit     = static_cast<QLineEdit*>(elem_["ypos"]);
    double yp = lEdit->text().toFloat();

    QPointF pp(xp, yp);
    pm_->setCoordinates(pp);

    tEdit = static_cast<QTextEdit*>(elem_["desc"]);
    pm_->setDescription(tEdit->toPlainText());

    pm_->setPixmap(pix_);

    hide();
}

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

void MvQPlaceMarkDialog::writeSettings()
{
    QSettings settings(MVQ_QSETTINGS_DEFAULT_ARGS, "MvQPlaceMarkDialog");

    settings.beginGroup("dialog");
    settings.setValue("geometry", saveGeometry());
    //settings.setValue("state",saveState());
    settings.endGroup();
}

void MvQPlaceMarkDialog::readSettings()
{
    QSettings settings(MVQ_QSETTINGS_DEFAULT_ARGS, "MvQPlaceMarkDialog");

    settings.beginGroup("dialog");
    restoreGeometry(settings.value("geometry").toByteArray());
    //restoreState(settings.value("state").toByteArray());

    settings.endGroup();
}
