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

 Copyright 2016 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 "MvQFileListWidget.h"

#include <QDebug>
#include <QDir>
#include <QFileSystemModel>
#include <QHBoxLayout>
#include <QLabel>
#include <QListView>
#include <QSortFilterProxyModel>
#include <QSplitter>
#include <QToolButton>
#include <QTreeView>
#include <QVBoxLayout>

#include "MvQFileList.h"
#include "MvQFileListModel.h"

#define _MVQFILELISTWIDGET_DEBUG

//===========================
// MvQFsFilterModel
//===========================

class MvQFsFilterModel : public QSortFilterProxyModel
{
public:
    MvQFsFilterModel(QObject* parent = 0);
    bool filterAcceptsRow(int, const QModelIndex&) const;
    bool lessThan(const QModelIndex&, const QModelIndex&) const;
};

MvQFsFilterModel::MvQFsFilterModel(QObject* parent) :
    QSortFilterProxyModel(parent)
{
}

bool MvQFsFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const
{
    QModelIndex index         = sourceModel()->index(sourceRow, 0, sourceParent);
    QFileSystemModel* fsModel = qobject_cast<QFileSystemModel*>(sourceModel());

    if (!fsModel)
        return false;

    QString fileName = fsModel->fileName(index);

    if (fsModel->isDir(index)) {
        if (fileName.endsWith("#") == false)
            return true;
        else
            return false;
    }

    if (fileName.startsWith(".") == false &&
        fileName.startsWith("..") == false) {
        return true;
    }

    return false;
}

bool MvQFsFilterModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
{
    QFileSystemModel* fsModel = qobject_cast<QFileSystemModel*>(sourceModel());

    if (!fsModel)
        return false;

    if (fsModel->isDir(right)) {
        if (!fsModel->isDir(left))
            return false;
    }
    else {
        if (fsModel->isDir(left))
            return true;
    }

    return QSortFilterProxyModel::lessThan(left, right);
}


MvQFileListWidget::MvQFileListWidget(QWidget* parent) :
    QWidget(parent),
    fileLst_(0)
{
    QVBoxLayout* vb = new QVBoxLayout(this);
    vb->setContentsMargins(0, 0, 0, 0);
    vb->setSpacing(0);

    QWidget* titleBar = new QWidget(this);
    titleBar->setProperty("headerStyle", "1");
    vb->addWidget(titleBar);

    QHBoxLayout* titleHb = new QHBoxLayout(titleBar);
    titleHb->setContentsMargins(0, 0, 0, 0);
    titleHb->addSpacing(4);
    //hb->setSpacing(0);
    //QLabel* titleLabel=new QLabel("<b>" + tr("Files") + "</b>",this);
    QLabel* titleLabel = new QLabel(tr("Files"), this);
    titleLabel->setProperty("headerStyle", "1");
    titleHb->addWidget(titleLabel);

    QToolButton* clearTb = new QToolButton(this);
    clearTb->setAutoRaise(true);
    clearTb->setIcon(QPixmap(":/examiner/wastebasket_orange.svg"));
    clearTb->setProperty("headerStyle", "1");
    clearTb->setToolTip(tr("Clear file list"));
    titleHb->addWidget(clearTb);
    ;

    connect(clearTb, SIGNAL(clicked(bool)),
            this, SIGNAL(clearPanel(bool)));

    QToolButton* closeTb = new QToolButton(this);
    closeTb->setAutoRaise(true);
    //closeTb->setIcon(QPixmap(":/find/close.svg"));
    closeTb->setIcon(QPixmap(":/examiner/panel_close.svg"));
    closeTb->setToolTip(tr("Close files panel"));
    closeTb->setProperty("headerStyle", "1");
    titleHb->addWidget(closeTb);

    connect(closeTb, SIGNAL(clicked(bool)),
            this, SIGNAL(closePanel(bool)));

#if 0
    splitter_=new QSplitter(this);
    splitter_->setOrientation(Qt::Vertical);
    vb->addWidget(splitter_);


    //filesystem
    QWidget* w=new QWidget(this);
    QVBoxLayout* fsLayout=new QVBoxLayout(w);
    fsLayout->setContentsMargins(0,0,0,0);
    fsLayout->setSpacing(0);

    fsModel_=new QFileSystemModel(this);
    fsFilterModel_=new MvQFsFilterModel(this);
    fsFilterModel_->setSourceModel(fsModel_);
    fsView_=new QTreeView(this);
    fsView_->setModel(fsFilterModel_);
    fsLayout->addWidget(fsView_);
    splitter_->addWidget(w);
#endif

#if 0
    //file list
    w=new QWidget(this);
    QVBoxLayout* lstLayout=new QVBoxLayout(w);
    lstLayout->setContentsMargins(0,0,0,0);
    lstLayout->setSpacing(0);
#endif

    lstModel_ = new MvQFileListModel(this);
    lstView_  = new QListView(this);
    lstView_->setModel(lstModel_);
    vb->addWidget(lstView_);
    lstView_->setProperty("sidebar", "1");

    connect(lstView_, SIGNAL(clicked(QModelIndex)),
            this, SLOT(slotFileSelect(QModelIndex)));

    connect(lstView_, SIGNAL(activated(QModelIndex)),
            this, SLOT(slotFileSelect(QModelIndex)));
}

void MvQFileListWidget::setFileList(MvQFileList* lst)
{
    Q_ASSERT(lst);
    fileLst_ = lst;
    lstModel_->setFileList(fileLst_);

    if (fileLst_->count() > 0)
        lstView_->setCurrentIndex(lstModel_->index(0, 0));

#if 0
    if(fileLst_->count() >0)
    {
        QString p=fileLst_->files().first().absoluteDir().path();
        qDebug() << p;
        fsModel_->setRootPath(QDir::rootPath());
        //fsView_->setRootIndex(fsModel_->index(p));
        QModelIndex idx=fsFilterModel_->mapFromSource(fsModel_->index(p));
        fsView_->setCurrentIndex(idx);
        fsView_->scrollTo(idx);

    }
#endif
}

void MvQFileListWidget::slotFileSelect(const QModelIndex& idx)
{
#ifdef _MVQFILELISTWIDGET_DEBUG
    qDebug() << "MvQFileListWidget::slotFileSelect -->" << idx;
#endif
    if (!idx.isValid())
        return;

    emit fileSelected(lstModel_->indexToPath(idx));
}

void MvQFileListWidget::selectFile(QString f, bool broadcast)
{
#ifdef _MVQFILELISTWIDGET_DEBUG
    qDebug() << "MvQFileListWidget::selectFile -->" << f;
#endif

    QModelIndex idx = lstModel_->pathToIndex(f);
    if (idx.isValid() && idx != lstView_->currentIndex()) {
#ifdef _MVQFILELISTWIDGET_DEBUG
        qDebug() << "index" << idx;
#endif
        lstView_->setCurrentIndex(idx);

        if (broadcast)
            emit fileSelected(lstModel_->indexToPath(idx));
    }
}
