/***************************** 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 "MvQTreeExpandState.h"

#include <QDebug>
#include <QModelIndex>
#include <QTreeView>

//#define _MVQTREEEXPANDSTATE_DEBUG

ExpandNode::~ExpandNode()
{
    clear();
}

void ExpandNode::clear()
{
    name_.clear();
    qDeleteAll(children_.begin(), children_.end());
    children_.clear();
}

ExpandNode* ExpandNode::add(QString name)
{
    auto* n = new ExpandNode(name);
    children_ << n;
    return n;
}

//==========================================================
//
// MvQTreeExpandState
//
//==========================================================

MvQTreeExpandState::MvQTreeExpandState(QTreeView* view) :
    view_(view)
{
}

MvQTreeExpandState::~MvQTreeExpandState()
{
    clear();
}

void MvQTreeExpandState::clear()
{
    if (root_)
        delete root_;

    root_ = nullptr;
    selectionParent_ = nullptr;
    selectionName_.clear();
}

ExpandNode* MvQTreeExpandState::setRoot(QString name)
{
    if (root_)
        clear();

    root_ = new ExpandNode(name);
    return root_;
}

void MvQTreeExpandState::init(QStringList topLevelNodes)
{
    clear();
    setRoot("");
    foreach (QString s, topLevelNodes) {
        root_->add(s);
    }
}

void MvQTreeExpandState::save()
{
    clear();

    QModelIndex selIdx = view_->currentIndex();
    if (selIdx.isValid()) {
        selectionName_ = selIdx.data(Qt::DisplayRole).toString();
    }

#if 0
    VInfo_ptr s=currentSelection();
    if(s)
    {
        if(node->server() == s->server())
          expandState_->selection_=s;
    }
#endif

    // If the root cannot be expanded
    if (view_->rootIsDecorated()) {
        QModelIndex idx;  // root
        setRoot("");
#ifdef _MVQTREEEXPANDSTATE_DEBUG
        qDebug() << "MvQTreeExpandState::save --> root";
#endif
        saveExpand(root_, idx, selIdx);
    }

    // TODO: implement the case when the root can be expanded
}

void MvQTreeExpandState::saveExpand(ExpandNode* parentExpand, const QModelIndex& idx, const QModelIndex& selIdx)
{
    if (idx == selIdx.parent()) {
        selectionParent_ = parentExpand;
    }

    for (int i = 0; i < view_->model()->rowCount(idx); i++) {
        QModelIndex chIdx = view_->model()->index(i, 0, idx);

        if (!view_->isExpanded(chIdx))
            continue;
        else {
#ifdef _MVQTREEEXPANDSTATE_DEBUG
            qDebug() << "MvQTreeExpandState::saveExpand " << chIdx.data(Qt::DisplayRole).toString();
#endif
            ExpandNode* expand = parentExpand->add(chIdx.data(Qt::DisplayRole).toString());
            saveExpand(expand, chIdx, selIdx);
        }
    }
}

// Save the expand state for the given node (it can be a server as well)
void MvQTreeExpandState::restore()
{
    if (!root_)
        return;

    restoreExpand(root_, QModelIndex());
    clear();
}

void MvQTreeExpandState::restoreExpand(ExpandNode* expand, const QModelIndex& idx)
{
#ifdef _MVQTREEEXPANDSTATE_DEBUG
    qDebug() << "MvQTreeExpandState::restoreExpand -->" << idx;
#endif

    QStringList nameLst;
    for (int i = 0; i < view_->model()->rowCount(idx); i++) {
        QModelIndex chIdx = view_->model()->index(i, 0, idx);
        nameLst << chIdx.data(Qt::DisplayRole).toString();
    }

    if (selectionParent_ && selectionParent_ == expand) {
        int row = -1;
        if ((row = nameLst.indexOf(selectionName_)) != -1) {
            view_->setCurrentIndex(view_->model()->index(row, 0, idx));
        }
    }


    for (auto chExpand : expand->children_) {
        QString name = chExpand->name_;
#ifdef _MVQTREEEXPANDSTATE_DEBUG
        qDebug() << " child" << i << name << nameLst.indexOf(name);
#endif
        int row = -1;
        if ((row = nameLst.indexOf(name)) != -1) {
            QModelIndex chIdx = view_->model()->index(row, 0, idx);
            if (chIdx != QModelIndex()) {
                view_->setExpanded(chIdx, true);
                restoreExpand(chExpand, chIdx);
            }
        }
    }
}
