//=========================================================================
//  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 "qtStagesModel.h"
#include "qtProjectRuntime.h"

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

#include <QDebug>
#include <QFont>
#include <QString>

namespace smtk
{
namespace simulation
{
namespace ace3p
{

qtStagesModel::qtStagesModel(QWidget* parent)
  : m_projectCurrentStage(-1)
{
}

QVariant qtStagesModel::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];
  }

  return QAbstractItemModel::headerData(section, orientation, role);
}

int qtStagesModel::rowCount(const QModelIndex& parent) const
{
  if (!m_ace3pProject /*|| !parent.isValid()*/)
  {
    return 0;
  }

  return static_cast<int>(m_ace3pProject->numberOfStages());
}

int qtStagesModel::columnCount(const QModelIndex& parent) const
{
  Q_UNUSED(parent);
  return m_nCols;
}

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

  if (!m_ace3pProject)
  {
    return variant;
  }

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

  // check if we are on a stage
  if (row >= m_ace3pProject->numberOfStages())
  {
    return variant;
  }

  std::shared_ptr<Stage> stage = m_ace3pProject->stage(row);

  smtk::simulation::ace3p::AttributeUtils attUtils;
  smtk::attribute::AttributePtr analysisAtt = attUtils.getAnalysisAtt(stage->attributeResource());
  assert(analysisAtt != nullptr);
  smtk::attribute::ConstStringItemPtr analysisItem = analysisAtt->findString("Analysis");

  // get the data out of the Attribute Resource
  if (role == Qt::DisplayRole || role == Qt::EditRole)
  {
    switch (col)
    {
      case 0: // name
        variant = QVariant(stage->attributeResource()->name().c_str());
        break;
      case 1: // analysis code
        if (analysisItem->isSet())
          variant = QVariant(analysisItem->value().c_str());
        else
          variant = QVariant(tr("(not set)"));
        break;
      case 2: // description
        variant = QVariant(stage->description().c_str());
        break;
      case 3: // analysis mesh
        variant = QVariant(stage->analysisMesh().c_str());
        break;
    }
  }

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

  /* // STAN
  if (role == Qt::FontRole)
  {
    if (row == m_projectCurrentStage)
    {
      QFont font;
      font.setBold(true);
      variant = font;
    }
  }
  */

  return variant;
}

bool qtStagesModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
  if (!m_ace3pProject)
  {
    return false;
  }

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

  if (role == Qt::EditRole)
  {
    std::string str = value.toString().toStdString();
    if (col == 0)
    {
      m_ace3pProject->stage(row)->attributeResource()->setName(str);
      //m_ace3pProject->stage(row).setDescription(str);
      emit dataChanged(index, index);
      return true;
    }
    else if (col == 2)
    {

      m_ace3pProject->stage(row)->setDescription(str);
      emit dataChanged(index, index);
      return true;
    }
  }

  return false;
}

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

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

bool qtStagesModel::insertRows(int row, int count, const QModelIndex& parent)
{
  this->beginInsertRows(parent, row, row + count - 1);
  // all data is stored by project (nothing locally), so nothing to do here
  this->endInsertRows();

  return true;
}

bool qtStagesModel::removeRows(int row, int count, const QModelIndex& parent)
{
  this->beginRemoveRows(parent, row, row + count - 1);
  // all data is stored by project (nothing locally), so nothing to do here
  this->endRemoveRows();

  return true;
}

void qtStagesModel::setProject(smtk::project::ProjectPtr project)
{
  this->beginResetModel();
  m_ace3pProject = std::dynamic_pointer_cast<Project>(project);
  this->endResetModel();
}

void qtStagesModel::addStage(int stageNumber)
{
  if (!m_ace3pProject)
  {
    return;
  }

  this->insertRow(stageNumber);
}

void qtStagesModel::removeStage(int rowIndex)
{
  this->removeRow(rowIndex);
}

int qtStagesModel::projectCurrentStage() const
{
  return m_projectCurrentStage;
}

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