/** @file src/gui/mainwindow.h
 * Main window and central widget of i2MassChroQ
 */

/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of i2MassChroQ.
 *
 *     i2MassChroQ is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     i2MassChroQ is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with i2MassChroQ.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/


#pragma once

#include <QMainWindow>
#include <QFileInfo>
#include <QCloseEvent>
#include <pappsomspp/core/types.h>
#include <pappsomspp/core/peptide/peptide.h>
#include <pappsomspp/core/massspectrum/massspectrum.h>
#include "core/project.h"
#include "project_view/projectwindow.h"
#include "load_results_dialog/loadresultsdialog.h"
#include "export/export_spreadsheet_dialog/exportspreadsheetdialog.h"
#include "waiting_message_dialog/waitingmessagedialog.h"
#include "about_dialog/aboutdialog.h"
#include "tandem_run_dialog/tandemrundialog.h"
#include "core/tandem_run/tandemrunbatch.h"
#include "core/sage_run/sagerunbatch.h"
#include "utils/httpversion.h"
#include "gui/edit/edit_settings/editsettings.h"
#include "gui/run/sage/sagerundialog.h"
#include "gui/masschroq_run_dialog/masschroqrundialog.h"
#include "workerthread.h"
#include "gui/run/msstats/msstatsrunview.h"
#include "gui/run/mcqr/mcqrrunviewng.h"
#include "gui/run/mcqr_spectral_count/mcqrscrunview.h"


namespace Ui
{
class Main;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT
  // friend class WorkerThread;

  public:
  explicit MainWindow(QWidget *parent = 0);
  virtual ~MainWindow();

  /** @brief tells if the worker should stop running his job
   * @param bool true asks to stop
   */
  bool stopWorkerThread();
  WorkerThread *getWorkerThread();


  /** @brief enable or disable DeepProt studio feature
   */
  void enableDeepProtStudio(bool enabled);

  const ProjectSp &getProjectSp() const;

  public slots:
  void run();
  void loadResults();
  void selectXpipFile();
  void doActionAbout();
  void doActionQuit();
  void doActionFastaAllValidTargetProteins();
  void doActionFasta();
  void doActionFastaOneBySubgroup();
  void doActionFastaOneByGroup();
  void doActionMcqrSpectralCount();
  void doActionMcqrDev();
  void doActionMsStats();
  void doActionMassChroQ();
  // void doActionXicMcqr(QAction *action);
  void doActionOneGroupMcqr(QAction *action_group);
  void doActionMassChroqPRM();
  void doActionProticDb();
  void doActionLabelingMethods();
  void doActionDeepProtStudio();
  void doActionTandemRun();
  void doActionSageRun();
  void doActionSettings();
  void doActionSpreadsheet();
  void doActionFann();
  void doActionModifications();
  void doActionSaveProject();
  void doDisplayLoadingMessage(QString message);
  void doDisplayLoadingMessagePercent(QString message, int value);
  void doDisplayLoadingPercent(int value);
  void doDisplayJobFinished(QString message);
  void doDisplayJobCanceled(QString message);
  void doWorkerAppendText(const char *);
  void doWorkerAppendQString(QString message);
  void doWorkerSetText(QString);
  void doProjectReady(ProjectSp project_sp);
  void doLoadingResultsReady(ProjectSp project_sp);
  void doProjectNotReady(QString error);
  void doAcceptedLoadResultDialog();
  void doAcceptedTandemRunDialog();
  void doAcceptedSageRunDialog();
  void doAcceptedExportSpreadsheetDialog();
  void doAcceptedMassChroqRunDialog();
  void doWritingMassChroQmlFileFinished(
    QString masschroqml_file,
    std::vector<MsRunAlignmentGroupSp> quantified_groups);
  void doOperationFailed(QString);
  void doOperationFinished();
  void doGroupingFinished();
  void doCheckNewVersion();
  void doFreeAllMsRunReaders();
  void doShowStopButton();
  // void peptideEdited(QString peptideStr);
  // void setColor(const QColor &color);
  // void setShape(Shape shape);
  signals:
  // void peptideChanged(pappso::PeptideSp peptide);
  void operateXpipFile(QString xpip_file);
  void operateLoadingResults(bool is_individual,
                             AutomaticFilterParameters param,
                             QStringList file_list);
  void operateWritingXpipFile(QString filename, ProjectSp project_sp);
  void
  operateWritingOdsFile(QString filename,
                        QString format,
                        ProjectSp project_sp,
                        ExportSpreadsheetDialog *export_spreadsheet_dialog);
  void operateWritingMassChroqFile(QString filename, ProjectSp project_sp);
  void operateWritingMassChroqPrmFile(QString filename, ProjectSp project_sp);
  void operateWritingProticFile(QString filename, ProjectSp project_sp);
  void operateWritingFannDataFile(QString filename, ProjectSp project_sp);
  void operateWritingMcqrSpectralCountFile(QString filename,
                                           ProjectSp project_sp);
  void operateWritingFastaFile(QString filename,
                               ProjectSp project_sp,
                               ExportFastaType type);
  void operateGrouping(ProjectSp project_sp);
  void operateRunningXtandem(TandemRunBatch tandem_run_batch);
  void operateRunningSage(SageRunBatch sage_run_batch);
  void operateRunningMassChroq(MassChroQRunBatch masschroq_batch_param);
  void projectNameChanged(QString project_name);
  void operateFreeAllMsRunReaders();

  protected:
  void closeEvent(QCloseEvent *event) override;

  /** @brief centralized way to modify the project name
   * if this windows contains a project, then it will modify its name
   * this will emit a signal to provide the new name to any widget
   */
  void showProjectName();


  public:
  void showWaitingMessage(const QString title);
  void hideWaitingMessage();
  void viewError(QString error);

  private:
  int chooseSaveMssgBox();

  private:
  QCoreApplication *_p_app;
  Ui::Main *ui;
  QThread _worker_thread;
  WorkerThread *mp_worker;

  ProjectSp _project_sp = nullptr;

  ProjectWindow *_project_window                        = nullptr;
  LoadResultsDialog *_p_load_results_dialog             = nullptr;
  ExportSpreadsheetDialog *_p_export_spreadsheet_dialog = nullptr;
  MassChroqRunDialog *_p_export_masschroq_dialog        = nullptr;
  WaitingMessageDialog *_p_waiting_message_dialog       = nullptr;
  AboutDialog *_p_about_dialog                          = nullptr;
  TandemRunDialog *_p_tandem_run_dialog                 = nullptr;
  EditSettings *_p_edit_settings                        = nullptr;
  MsStatsRunView *mp_msstatsRun                         = nullptr;
  McqrRunViewNg *mp_mcqrRun                             = nullptr;
  McqrScRunView *mp_mcqrScRun                           = nullptr;
  SageRunDialog *mp_sageRunDialog                       = nullptr;

  HttpVersion m_onlineVersion;
  QMutex m_mutex;
};
