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

#include "BufrFlatDataItem.h"

#include <QColor>
#include <QDebug>
#include <QJsonDocument>
#include <QFont>


BufrFlatDataModel::BufrFlatDataModel(QObject* parent) :
    QAbstractItemModel(parent),
    root_(nullptr),
    compressed_(false),
    subsetNumber_(-1)
{
}

BufrFlatDataModel::~BufrFlatDataModel()
{
    if (root_)
        delete root_;
}

void BufrFlatDataModel::clear()
{
    beginResetModel();
    compressed_ = false;
    subsetNumber_ = -1;
    if (root_) {
        delete root_;
        root_ = nullptr;
    }
    endResetModel();
}


bool BufrFlatDataModel::loadDumpData(const std::string& dump, bool compressed, QString& err)
{
    if (!dump.empty()) {
        beginResetModel();
        compressed_ = compressed;
        if (compressed_)
            subsetNumber_ = 0;
        else
            subsetNumber_ = -1;

        if (root_)
            delete root_;

        root_ = BufrFlatDataItem::loadDump(dump, err);
        endResetModel();
        return (err.isEmpty()) ? true : false;
    }
    else {
        clear();
        err = "Flat dump is empty";
        return false;
    }

    return false;
}

void BufrFlatDataModel::setSubsetNumber(int subsetNumber)
{
    if (compressed_) {
        if (subsetNumber_ != subsetNumber) {
            subsetNumber_ = subsetNumber;
            emit dataChanged(QModelIndex(), QModelIndex());
        }
    }
}

bool BufrFlatDataModel::hasData() const
{
    return (root_ && root_->childCount() > 0);
}

int BufrFlatDataModel::rowCount(const QModelIndex& parent) const
{
    if (!root_)
        return 0;

    if (parent.column() > 0)
        return 0;

    if (!parent.isValid()) {
        return root_->childCount();
    }
    else if (BufrFlatDataItem* pItem = indexToItem(parent)) {
        return (pItem->isGroup()) ? pItem->childCount() : 0;
    }

    return 0;
}

int BufrFlatDataModel::columnCount(const QModelIndex& /*parent*/) const
{
    return 2;
}

QVariant BufrFlatDataModel::data(const QModelIndex& index, int role) const
{
    if (!root_ || !index.isValid())
        return {};

    BufrFlatDataItem* item = indexToItem(index);
    Q_ASSERT(item);

    if (role == Qt::DisplayRole) {
        if (index.column() == 0) {
            if (item->isGroup())
                return item->title(subsetNumber_);
            return item->key();
        }
        else if (index.column() == 1) {
            if (!item->isGroup())
                return item->value(subsetNumber_);
            return {};
        }
    }
    else if (role == Qt::FontRole) {
        /*if(item->isGroup())
          {
              QFont f;
              f.setBold(true);
              return f;
         }*/
        return {};
    }

    return {};
}

QVariant BufrFlatDataModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (role != Qt::DisplayRole)
        return {};

    if (orientation == Qt::Horizontal) {
        switch (section) {
            case 0:
                return tr("Key");
            case 1:
                return tr("Value");
            default:
                return {};
        }
    }

    return {};
}

QModelIndex BufrFlatDataModel::index(int row, int column, const QModelIndex& parent) const
{
    if (BufrFlatDataItem* parentItem = indexToItem(parent)) {
        // qDebug() <<  "parentItem" << parentItem->key();

        if (BufrFlatDataItem* item = parentItem->childAt(row)) {
            return createIndex(row, column, item);
        }
        else {
            return {};
        }
    }

    return {};
}

QModelIndex BufrFlatDataModel::parent(const QModelIndex& index) const
{
    if (!index.isValid())
        return {};

    if (BufrFlatDataItem* ch = indexToItem(index)) {
        BufrFlatDataItem* p = ch->parent();
        if (p == root_) {
            return {};
        }

        return createIndex(p->indexInParent(), 0, p);
    }

    return {};
}


BufrFlatDataItem* BufrFlatDataModel::indexToItem(const QModelIndex& idx) const
{
    if (!idx.isValid())
        return root_;

    return static_cast<BufrFlatDataItem*>(idx.internalPointer());
}










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

//Copyright 2019 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 <QDebug>

//#include <sstream>
//#include <cassert>

//#include "BufrFlatDataModel.h"
//#include "MvKeyProfile.h"
//#include "MvMiscellaneous.h"















//BufrFlatDataModel::BufrFlatDataModel(QObject* parent) :
//    QAbstractItemModel(parent)
//{
//    templateProf_ = new MvKeyProfile("bufrFlatDump");
//    auto* kKey = new MvKey("Key", "Key");
//    templateProf_->addKey(kKey);
//    auto* nKey = new MvKey("Value", "Value");
//    templateProf_->addKey(nKey);
//}

//BufrFlatDataModel::~BufrFlatDataModel()
//{
//    delete templateProf_;
//    if (prof_)
//        delete prof_;
//}

//void BufrFlatDataModel::clear()
//{
//    beginResetModel();
//    if (prof_) {
//        delete prof_;
//    }
//    prof_ = nullptr;
//    endResetModel();
//}

//bool BufrFlatDataModel::loadDumpData(const std::string& dump, QString& /*err*/)
//{
//    MvKeyProfile* prof = templateProf_->clone();
//    MvKey* kKey = prof->at(0);
//    MvKey* vKey = prof->at(1);

//    // parse text

//    // the format is:
//    // key=value

//    std::istringstream f(dump);
//    std::string line;
//    std::string key;
//    std::string value;
//    bool arrayVal = false;
//    while (std::getline(f, line)) {
//        std::size_t pos = line.find("=");
//        if (pos != std::string::npos) {
//            arrayVal = false;
//            if (!key.empty()) {
//                kKey->addValue(key);
//                vKey->addValue(value);
//            }
//            key.clear();
//            value.clear();

//            if (pos+1 <= line.length()) {
//                key = line.substr(0, pos);
//                value = line.substr(pos+1);
//                if (value[0] == '{' ||  value.substr(0,2) == " {") {
//                    arrayVal = true;
//                    value = metview::simplified(value);
//                }
//            }
//        } else if(arrayVal) {
//            value += metview::simplified(line);
//        }
//    }

//    if (!key.empty()) {
//        kKey->addValue(key);
//        vKey->addValue(value);
//    }


//    beginResetModel();
//    if (prof_) {
//        delete prof_;
//    }
//    prof_ = prof;
//    endResetModel();

//    return true;
//}

//int BufrFlatDataModel::columnCount(const QModelIndex& /* parent */) const
//{
//    return templateProf_->size();
//}

//int BufrFlatDataModel::rowCount(const QModelIndex& index) const
//{
//    if (!prof_)
//        return 0;

//    if (!index.isValid()) {
//        return prof_->valueNum();
//    }
//    else {
//        return 0;
//    }
//}

//QVariant BufrFlatDataModel::data(const QModelIndex& index, int role) const
//{
//    if (!index.isValid()) {
//        return {};
//    }

//    if (role == Qt::DisplayRole) {
//        int row = index.row();
//        int column = index.column();

//        if (!prof_ || row < 0 || row >= prof_->valueNum() ||
//            column < 0 || column >= static_cast<int>(prof_->size())) {
//            return {};
//        }

//        MvKey* key = prof_->at(column);
//        return QString::fromStdString(key->stringValue()[row]);
//    }

//    return {};
//}

//QVariant BufrFlatDataModel::headerData(const int section, const Qt::Orientation orient, const int role) const
//{
//    if (orient != Qt::Horizontal ||
//        section < 0 || section >= static_cast<int>(templateProf_->size())) {
//        return QAbstractItemModel::headerData(section, orient, role);
//    }

//    if (role == Qt::DisplayRole) {
//        if (!templateProf_->at(section)->shortName().empty())
//            return QString(templateProf_->at(section)->shortName().c_str());
//        else
//            return QString(templateProf_->at(section)->name().c_str());
//    }

//    return {};
//}

//QModelIndex BufrFlatDataModel::index(int row, int column, const QModelIndex& /*parent*/) const
//{
//    if (!prof_) {
//        return {};
//    }

//    return createIndex(row, column, (void*)nullptr);
//}


//QModelIndex BufrFlatDataModel::parent(const QModelIndex& /*index*/) const
//{
//    return {};
//}
