//=========================================================================
//  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 "smtk/simulation/ace3p/qt/qtJobsModel.h"
#include "smtk/simulation/ace3p/qt/qtJobsWidget.h"
#include "smtk/simulation/ace3p/qt/ui_qtJobsWidget.h"

#include <iostream>

#include <QDebug>
namespace smtk
{
namespace simulation
{
namespace ace3p
{

qtJobsWidget::qtJobsWidget(QWidget* parentWidget)
  : QWidget(parentWidget)
  , m_jobs_model(new qtJobsModel(this))
  , ui(new Ui::qtJobsWidget)
{
  // initialize the UI
  this->ui->setupUi(this);

  // setup jobs table
  this->ui->m_jobsTable->setModel(m_jobs_model);
  this->ui->m_jobsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
  this->ui->m_jobsTable->setSelectionMode(QAbstractItemView::SingleSelection);
  this->ui->m_jobsTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
  this->ui->m_jobsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);

  // we use the JobsModel to fill the details panel, but we only want a few fields in the table
  for(int i = 4; i < 12; ++i)
  {
    this->ui->m_jobsTable->hideColumn(i);
  }

  // hide the jobs details panel when first opened
  this->ui->m_JobsDetails->hide();

  // connect selection model to details section
  auto selection = this->ui->m_jobsTable->selectionModel();
  QObject::connect(
    selection, &QItemSelectionModel::selectionChanged,
    this, &qtJobsWidget::toggleDetailsVisibility);

  // connect job name field to job model setData
  QObject::connect(
    this->ui->m_job_name_field, &QLineEdit::textEdited,
    this, &qtJobsWidget::jobNameChanged);

  QObject::connect(
    this->ui->m_notes_field, &QPlainTextEdit::textChanged,
    this, &qtJobsWidget::notesChanged);
}

void qtJobsWidget::setProject(smtk::project::ProjectPtr project)
{
  if(project)
  {
    m_jobs_model->populateJobs(project);
  }
}

void qtJobsWidget::onJobsUpdated()
{
  m_jobs_model->updateJobs();
}

void qtJobsWidget::toggleDetailsVisibility(
    const QItemSelection &selected,
    const QItemSelection &deselected)
{
  // get the list of selected items
  auto selectedList = selected.indexes();

  // if the selection is empty, hide the details panel and return
  if(!selectedList.size())
  {
    this->ui->m_JobsDetails->hide();
    return;
  }

  // fill in all the fields in the details panel
  const int job = selectedList[0].row();
  QModelIndex index;
  QVariant fieldData;

  index = m_jobs_model->index(job, qtJobsModel::Machine);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_machine->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::Nodes);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_nodes->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::Status);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_job_status->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::AnalysisType);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_analysis_type->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::Notes);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_notes_field->setPlainText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::RemoteDir);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_remote_dir->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::LocalDir);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_local_dir->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::InputDir);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_input_dir->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::Processes);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_processes->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::SlurmID);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_slurm_id->setText(fieldData.toString());

  index = m_jobs_model->index(job, qtJobsModel::JobName);
  fieldData = m_jobs_model->data(index, Qt::DisplayRole);
  this->ui->m_job_name_field->setText(fieldData.toString());

  this->ui->m_JobsDetails->show();
}

void qtJobsWidget::jobNameChanged(const QString& text)
{
  // get index of current job
  auto selection = this->ui->m_jobsTable->selectionModel();
  QModelIndexList rowList = selection->selectedRows(qtJobsModel::JobName);
  this->m_jobs_model->setData(rowList[0], text);
  this->m_jobs_model->updateJobs();
}

void qtJobsWidget::notesChanged()
{
  // get index of current job
  auto selection = this->ui->m_jobsTable->selectionModel();
  QModelIndexList rowList = selection->selectedRows(qtJobsModel::Notes);
  this->m_jobs_model->setData(rowList[0], this->ui->m_notes_field->toPlainText());
  this->m_jobs_model->updateJobs();
}

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

