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

 Copyright 2014 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 "MvQFolderViewHandler.h"

#include <QStackedLayout>
#include <QWidget>

#include "Folder.h"
#include "FolderSettings.h"
#include "MvQFolderViewBase.h"
#include "MvQFolderItemProperty.h"

MvQFolderViewHandler::MvQFolderViewHandler(QStackedLayout* p, MvQFolderItemProperty* itemProp) :
    stacked_(p),
    itemProp_(itemProp)
{
    currentMode_ = FolderSettings::defaultViewMode();
}

void MvQFolderViewHandler::add(Desktop::FolderViewMode mode, MvQFolderViewBase* b)
{
    // Check if the same widget/base has been already set for another mode
    Desktop::FolderViewMode parentMode = mode;
    for (auto& base : bases_)
        if (base.second == b) {
            parentMode = base.first;
            break;
        }

    bases_[mode] = b;
    QWidget* w = b->concreteWidget();
    widgets_[mode] = w;

    int cnt = stacked_->count();
    if (parentMode == mode) {
        stacked_->addWidget(w);
        indexes_[mode] = cnt;
    }
    // If the widget is already in the stack we just register its layout index
    else {
        indexes_[mode] = indexes_[parentMode];
    }
}

MvQFolderViewBase* MvQFolderViewHandler::base(Desktop::FolderViewMode mode) const
{
    auto it = bases_.find(mode);
    return (it != bases_.end()) ? it->second : nullptr;
}

QWidget* MvQFolderViewHandler::widget(Desktop::FolderViewMode mode)
{
    auto it = widgets_.find(mode);
    return (it != widgets_.end()) ? it->second : nullptr;
}

bool MvQFolderViewHandler::setCurrentMode(Desktop::FolderViewMode mode, Folder* folder, int iconSize)
{
    bool retVal = false;

    // Check if currentMode is valid
    if (bases_.find(currentMode_) == bases_.end()) {
        // If the currentMode is invalid we set it to icon view
        currentMode_ = Desktop::IconViewMode;

        // Check if there is icon view
        if (bases_.find(currentMode_) == bases_.end()) {
            // If there area any views defined we set current to the first
            if (bases_.size() > 0)
                currentMode_ = bases_.begin()->first;
            // Otherwise something really bad happened!
            else
                return false;
        }
    }

    // Note: when a view is diabled we completely detach it from the model, clear its content and block all
    // its signals. So when the view becomes enabled again we need to do exactly the opposite. Out of this


    // We change the mode
    if (mode != currentMode_ && bases_.find(mode) != bases_.end()) {
        QWidget* wNew = widget(mode);

        // Set the mode
        currentMode_ = mode;

        // Set the folder view rendering properties. We need to do it before enabeling the view.
        itemProp_->setViewMode(currentMode_);

        // Update the view
        if (wNew) {
            // This will NOT call reset in the view!!!
            wNew->setEnabled(true);
        }
    }

    // Disable the other views
    QWidget* currentWidget = widget(currentMode_);
    for (auto& widget : widgets_)
        if (widget.first != currentMode_ && widget.second && widget.second != currentWidget)
            widget.second->setEnabled(false);


    // Update the folder in the current view
    if (MvQFolderViewBase* b = base(currentMode_)) {
        // If changing the folder is successfull it calls reset and returns true
        retVal = b->changeFolder(folder, iconSize);

        // We need to reset if the
        // folder change was not successful (we stayed in the same folder)
        if (!retVal) {
            b->doReset();
        }
    }

    // Set the layout
    stacked_->setCurrentIndex(indexes_[currentMode_]);

    return retVal;
}

void MvQFolderViewHandler::setCurrentMode(Desktop::FolderViewMode mode)
{
    if (MvQFolderViewBase* b = base(mode)) {
        setCurrentMode(mode, b->currentFolder());
    }
}

void MvQFolderViewHandler::setCurrentMode(int id)
{
    Desktop::FolderViewMode m = FolderSettings::toViewMode(id);
    setCurrentMode(m);
}

QList<QWidget*> MvQFolderViewHandler::uniqueWidgets()
{
    QList<QWidget*> lst;
    for (auto& widget : widgets_) {
        if (lst.indexOf(widget.second) == -1)
            lst << widget.second;
    }
    return lst;
}

bool MvQFolderViewHandler::changeFolder(Folder* f)
{
    if (f) {
        FolderSettings* fi = f->settings();
        return setCurrentMode(fi->viewMode(), f, fi->iconSize());
    }

    return false;
}

bool MvQFolderViewHandler::changeFolder(QString path)
{
    if (Folder* f = Folder::folder(path.toStdString(), false)) {
        return changeFolder(f);
    }
    return false;
}
