//=========================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//=========================================================================
#include "qtResourceModel.h"

#include "smtk/attribute/Resource.h"
#include "smtk/attribute/StringItem.h"
#include "smtk/project/Project.h"
#include "smtk/simulation/ace3p/utility/AttributeUtils.h"

#include <QDebug>
#include <QString>

namespace smtk
{
namespace simulation
{
namespace ace3p
{

qtResourceModel::qtResourceModel(QWidget* parent)
  : m_project(nullptr)
{
}

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

  if (orientation == Qt::Horizontal && section < m_nCols)
    return m_headers[section];
  else
    return QStringLiteral("%1").arg(section);
}

int qtResourceModel::rowCount(const QModelIndex& parent) const
{
  if (parent.isValid())
  {
    return 0;
  }
  return m_nRows;
}
int qtResourceModel::columnCount(const QModelIndex& parent) const
{
  Q_UNUSED(parent);
  return m_nCols;
}

QVariant qtResourceModel::data(const QModelIndex& index, int role) const
{
  // default return value
  QVariant ret = QVariant();

  const int row = index.row();
  const int col = index.column();

  // check if we are on an analysis
  if (row >= m_resources.size())
  {
    return ret;
  }

  // get the data out of the Attribute Resource
  if (role == Qt::DisplayRole || role == Qt::EditRole)
  {
    switch (col)
    {
      case 0: // resource type
        ret = QVariant(tr(m_resources[row]->typeName().c_str()));
        break;
      case 1: // resource name
        ret = QVariant(tr(m_resources[row]->name().c_str()));
        break;
      case 2: // description
        ret = QVariant(tr(m_descriptions[row].c_str()));
        break;
      case 3: // uuid
        ret = QVariant(tr(m_resources[row]->id().toString().c_str()));
        break;
    }
  }

  if (role == Qt::TextAlignmentRole)
  {
    ret = QVariant(m_textAlignmentRoles[col]);
  }

  return ret;
}

bool qtResourceModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
  const int row = index.row();
  const int col = index.column();

  if (role == Qt::EditRole)
  {
    std::string str = value.toString().toStdString();
    if (col == 2) //description
    {

      m_descriptions[row] = str;
      emit dataChanged(index, index);
      return true;
    }
    if (col == 1) // name
    {
      m_resources[row]->setName(str);
      emit dataChanged(index, index);
      return true;
    }
  }
  return false;
}

Qt::ItemFlags qtResourceModel::flags(const QModelIndex& index) const
{
  const int col = index.column();

  Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
  if (col == 1 || col == 2)
  {
    defaultFlags |= Qt::ItemIsEditable;
  }
  return defaultFlags;
}

////////////////////////////////////////////////////////////////////////////////
void qtResourceModel::populateResources(smtk::project::ProjectPtr project)
{
  if (!m_project)
  {
    m_project = project;
  }
  updateResources(nullptr); // show all resources when project is opened
}

void qtResourceModel::updateResources(smtk::resource::ResourcePtr att)
{
  smtk::resource::ResourceSet resources;
  if (att)
  {
    auto attCasted = smtk::dynamic_pointer_cast<smtk::attribute::Resource>(att);
    resources = attCasted->associations();
  }
  else
  {
    resources = m_project->resources().find<smtk::resource::Resource>();
  }
  m_resources.resize(resources.size());
  m_resources.assign(resources.begin(), resources.end());
  m_descriptions.resize(resources.size(), m_defaultDescp);

  int nRowsOld = m_nRows;
  m_nRows = m_resources.size();
  if (m_nRows != nRowsOld)
  {
    QModelIndex topLeft = this->createIndex(0, 0);
    emit beginInsertRows(topLeft, nRowsOld, m_nRows - 1);
    emit endInsertRows();
  }
  emit layoutAboutToBeChanged();
  emit layoutChanged();
}

} // namespace ace3p
} // namespace simulation
} // namespace smtk
