//
// This file is part of MorphoGraphX - http://www.MorphoGraphX.org
// Copyright (C) 2012-2015 Richard S. Smith and collaborators.
//
// If you use MorphoGraphX in your work, please cite:
//   http://dx.doi.org/10.7554/eLife.05864
//
// MorphoGraphX is free software, and is licensed under under the terms of the 
// GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
// 
#ifndef TASKEDITDLG_HPP
#define TASKEDITDLG_HPP

#include <Process.hpp>

#include <QAbstractItemModel>
#include <QList>
#include <QMap>

#include <ui_TaskEditor.h>

class QPushButton;

typedef QList<float> floatList;

Q_DECLARE_METATYPE(floatList)

class TasksModel : public QAbstractItemModel 
{
  Q_OBJECT
public:
  typedef QList<mgx::ProcessDefinition> task_t;
  typedef QMap<QString, task_t> tasks_t;

  TasksModel(const tasks_t& ts, QObject* parent = 0);

  int rowCount(const QModelIndex& parent = QModelIndex()) const;
  int columnCount(const QModelIndex& parent = QModelIndex()) const;
  QVariant data(const QModelIndex& index, int role) const;
  QMap<int, QVariant> itemData(const QModelIndex& index) const;
  QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
  Qt::ItemFlags flags(const QModelIndex& index) const;
  bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
  bool setItemData(const QModelIndex& index, const QMap<int, QVariant>& roles);
  QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
  QModelIndex taskIndex(int task_id) const {
    return index(task_id, 0);
  }
  QModelIndex taskIndex(const QString& task_name) const {
    return index(task_names.indexOf(task_name), 0);
  }
  QModelIndex processIndex(int task_id, int row) const {
    return index(row, 0, taskIndex(task_id));
  }

  QModelIndex parent(const QModelIndex& index) const;

  bool insertRows(int position, int rows, const QModelIndex& index = QModelIndex());
  bool removeRows(int position, int rows, const QModelIndex& index = QModelIndex());
  bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent);
  QStringList mimeTypes() const;
  Qt::DropActions supportedDropActions() const;
  Qt::DropActions supportedDragActions() const { return Qt::MoveAction; }
  QMimeData* mimeData(const QModelIndexList& indexes) const;

  bool addTask(const QString& name);
  bool addProcess(const QString& task_name, const mgx::ProcessDefinition& def);
  bool deleteTask(const QString& name);
  bool renameTask(const QString& old_name, const QString& new_name);
  bool copyTask(const QString& old_name, const QString& new_name);

  void deleteItems(const QModelIndexList& lst);
  void deleteItems(QList<QList<int> > lst);

  QStringList task_names;
  QList<int> task_numbers;
  tasks_t tasks;

  bool isTask(const QModelIndex& idx) const;
};

class TaskEditDlg : public QDialog 
{
  Q_OBJECT

public:
  typedef TasksModel::task_t task_t;
  typedef TasksModel::tasks_t tasks_t;
  typedef mgx::ProcessDefinition ProcessDefinition;

  TaskEditDlg(const tasks_t& ts, QMap<QString, ProcessDefinition>& procs,
                                            QWidget* parent = 0, Qt::WindowFlags f = 0);

  tasks_t tasks() {
    return model->tasks;
  }

  static void readTasks(const QString& filename, QMap<QString, ProcessDefinition>& procs,
                                                                             tasks_t& newTasks);
  static void writeTask(QTextStream& pout, const QString& name, const task_t& task);
  static void writeTasks(QTextStream& pout, const tasks_t& tasks);

protected:
  void setProcesses(QTreeWidget* widget);
  int getSelectedRow(int default_row = 0);
  QString getSelectedTaskName(const QString& op, const QString& msg);
  QString getCurrentTaskName();

protected slots:
  void on_newTask_clicked();
  void on_deleteTask_clicked();
  void on_exportTask_clicked();
  void on_importTask_clicked();
  void on_renameTask_clicked();
  void on_copyTask_clicked();
  void on_makeSharedTask_clicked();
  void on_copyTaskToLocal_clicked();
  void on_tasks_deleteItems(const QModelIndexList& lst);
  void on_tasks_activated(const QModelIndex& index);

private:
  Ui::TaskEditDlg ui;
  TasksModel* model;

  QMap<QString, ProcessDefinition>& procs;
};

#endif
