//=========================================================================
//  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.
//=========================================================================
#ifndef smtk_simulation_ace3p_qt_qtJobsWidget
#define smtk_simulation_ace3p_qt_qtJobsWidget

#include "smtk/simulation/ace3p/qt/Exports.h"

#include "smtk/PublicPointerDefs.h"

#include <QSortFilterProxyModel>
#include <QString>
#include <QWidget>

class QItemSelection;
class qtProgressDialog;

namespace newt
{
class qtDownloadFolderRequester;
}

namespace Ui
{
class qtJobsWidget;
}

namespace smtk
{
namespace simulation
{
namespace ace3p
{

class qtJobsModel;

class SMTKACE3PQTEXT_EXPORT qtJobsWidget : public QWidget
{
  Q_OBJECT

public:
  qtJobsWidget(::qtProgressDialog* progressDialog, QWidget* parentWidget = nullptr);
  ~qtJobsWidget() = default;

signals:
  /** \brief emitted when download remote button is clicked */
  void requestDownloadRemote(const QString& dir);

  /** \brief emitted when a navigate button is clicked */
  void requestNavigateDir(const QString& dir);

  /** \brief emmited when job load button is clicked */
  void requestLoadJob(const QString& jobId, bool remote);

public slots:
  /** \brief set pointer to current project */
  void setProject(smtk::project::ProjectPtr project);

  /** \brief call when the project is closed by the app (reset widget) */
  void onProjectClosed();

  /** \brief Updates Job List based on a change in the active Stage. */
  void onStageSelected(int stageIndex);

  /** \brief slot called when job is created */
  void onJobAdded(const QString& jobId);

  /** \brief notifies job model that a job's data has been overwritten */
  void onJobOverwritten(const QString& jobId);

protected slots:
  /** \brief toggle the visibility of the jobs details panel */
  void toggleDetailsVisibility(const QItemSelection& selected);

  /** \brief update the job name on manifest */
  void jobNameChanged(const QString& text);

  void notesChanged();

  /** \brief connect to navigate remote button pressed signal */
  void onNavigateRemoteClicked();

  /** \brief connect to navigate input button pressed signal */
  void onNavigateInputClicked();

  /** \brief request the plugin to load the job's data into paraview */
  void onLoadJobClicked();

  /** \brief request the plugin to load the job's data into paraview */
  void onLoadJobRemoteClicked();

  // @brief request folder download from Cumulus proxy
  void downloadJob();

  // Updates tool buttons if downloaded job is currently selected
  void onJobDownloaded();

  void pollingCheckBoxStateChanged(bool checked);
  void
  on_m_addJobButton_clicked(); // TODO - delete later, temporary code for creating a testing project

  void onJobStatus(
    const QString& /*cumulusJobId*/,
    const QString& status,
    const QString& /*queueJobId*/,
    qint64 /*startTimeStamp*/);

  void onDownloadComplete();

protected:
  // Enables polling widget if signed in and jobs exists.
  // Returns true if widgets are enabled.
  bool enablePollingWidgets();

  // Download single file (uses QNetworkReply::readyRead signal to stream data)
  void downloadFile(const QString& machine, const QString& remotePath, const QString& localPath);

  // Stops download; used when error occurs, e.g.
  void stopDownload(const QString& msg, bool isError = true);

private:
  /** \brief pointer to UI information */
  Ui::qtJobsWidget* ui;

  /** \brief pointer to jobs table model */
  qtJobsModel* m_jobs_model = nullptr;
  QSortFilterProxyModel* m_proxyModel = nullptr;
  qtProgressDialog* m_progressDialog = nullptr;

  /** \brief pointer to job download helper */
  ::newt::qtDownloadFolderRequester* m_downloadRequester = nullptr;
  ;

  QString m_downloadJobId;

  int m_activeStageIndex = -1;
};

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

#endif
