/** @file src/gui/project_view/projectwindow.h
 *
 * project centric GUI
 */

/*******************************************************************************
 * Copyright (c) 2017 Olivier Langella <olivier.langella@u-psud.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 <QThread>
#include <set>
#include "../../core/project.h"
#include "../../core/tidd/tiddparameters.h"
#include "../edit/edit_label_methods/editlabelmethods.h"
#include "../edit/edit_modifications/editmodifications.h"
#include "../lists/protein_list_view/proteinlistwindow.h"
#include "../lists/peptide_list_view/peptidelistwindow.h"
#include "../ptm_island_list_view/ptmislandlistwindow.h"
#include "../protein_view/proteinwindow.h"
#include "../peptide_detail_view/peptidewindow.h"
#include "gui/widgets/automatic_filter_widget/automaticfilterwidget.h"
#include "../waiting_message_dialog/waitingmessagedialog.h"
#include "../xic_view/xicwindow.h"
#include <qcustomplot.h>
#include "../lists/ms_identification_run_list_view/msidentificationlistwindow.h"
#include "../lists/ms_identification_run_list_view/engine_detail_view/enginedetailwindow.h"
#include "../edit/deepprot_gui/deepprotgui.h"

class MainWindow;

// http://doc.qt.io/qt-4.8/qt-itemviews-chart-mainwindow-cpp.html
namespace Ui
{
class ProjectView;
}

class ProjectWindow : public QMainWindow
{
  Q_OBJECT

  friend class ProteinListWindow;
  friend class PeptideListWindow;
  friend class MsRunIdListWindow;
  friend class PtmIslandListWindow;

  public:
  explicit ProjectWindow(MainWindow *parent = 0);
  Project *getProjectP();
  void setProjectSp(ProjectSp project_sp);
  ProjectSp getProjectSP();


  const QString getProjectName() const;

  /** @brief Open a new window to edit modifications
   */
  void editModifications();

  /** @brief Open a new window to edit labeling methods
   */
  void editLabelingMethods();

  /** @brief Open a new window dedicated to DeepProt post process
   */
  void deepProtPostProcessInterface();

  void openInXicViewer(const PeptideEvidence *p_peptide_evidence);
  void popEngineDetailView();
  ~ProjectWindow();

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

  /** @brief Open a new window dedicated to view used engine parameters
   */
  void doViewEngineDetail(IdentificationDataSourceSp *identificationEngine);

  public slots:
  void doViewPtmIslandList(IdentificationGroup *p_identification_group);
  void doPtmIslandGrouping(IdentificationGroup *p_identification_group);
  void doViewProteinList(IdentificationGroup *p_identification_group = nullptr);
  void doViewMsIdentificationList();
  void setDefaultProteinListWindow(ProteinListWindow *p_protein_list_window);
  void doAutomaticFilterParametersChanged();
  void doMassPrecisionUnitChanged(QString combo_value);
  void doOperationFailed(QString);
  void doOperationFinished();
  void doGroupingFinished();
  void doIdentificationsComboboxChanged(int index);
  void doDisplayLoadingMessage(QString message);
  void doDisplayLoadingMessagePercent(QString message, int value);
  void doDisplayLoadingPercent(int value);
  void doDisplaySubTaskPercent(int value);

  void refreshGroup(IdentificationGroup *p_ident_group);
  void refreshPtmGroup(IdentificationGroup *p_ident_group);
  void doAcceptedLabelingMethod();
  void doViewPeptideDetail(PeptideEvidence *peptide_evidence);

  /** @brief ask to view peptide detail (MS2 annotated spectrum)
   * this function takes a shared pointer, more safe memory usage
   */
  void doViewPeptideEvidenceSpDetail(
    std::shared_ptr<PeptideEvidence> peptide_evidence_sp);
  void doFilterChanged();
  void doApplyFilter();
  void doApplyDecoy();
  void doComputePsmQvalues();
  void doComputeTidd();
  void doProjectNameChanged(QString name);
  void doProjectStatusChanged();
  void doBestMsRunForAlignmentFinished(MsRunSp msrun_sp);
  void doCleanMsRunReaders();
  void doOpenMassChroQDialog();
  void doExportXicAreaToCsv(QString filename, std::vector<XicBox *> xic_boxs);
  void doExportXicAreaToCsvFinished();
  void doShowStopButton();


  void receiveTiddResults(TiddResults message);
  // void setColor(const QColor &color);
  // void setShape(Shape shape);


  signals:
  void identificationGroupGrouped(IdentificationGroup *p_identification_group);
  void
  identificationPtmGroupGrouped(IdentificationGroup *p_identification_group);
  void peptideEvidenceSelected(PeptideEvidence *peptide_evidence);
  void operateGrouping(ProjectSp project_sp);
  void operateTiddComputing(ProjectSp project_sp, TiddParameters tidd_params);
  void operatePtmGroupingOnIdentification(
    IdentificationGroup *p_identification_group, PtmMode ptm_mode);
  void operateGroupingOnIdentification(
    IdentificationGroup *p_identification_group,
    ContaminantRemovalMode contaminant_removal_mode,
    GroupingType grouping_type);
  // void peptideChanged(pappso::PeptideSp peptide);
  void projectNameChanged(QString name);
  void projectStatusChanged();
  void bestMsRunFound(MsRunSp msrun_sp);
  void operateMassChroqExportDialog();
  void operateWriteXicAreaInCsv(QString filename,
                                ProjectSp project_sp,
                                std::vector<XicBox *> xic_boxs);

  // @brief emit this when peptide/protein filters are done (finished)
  void filterChangeFinished();

  protected:
  void doViewPeptideList(IdentificationGroup *p_ident_group,
                         ProteinMatch *protein_match);
  void doViewProteinDetail(ProteinMatch *protein_match);

  void doIdentificationGroupEdited(IdentificationGroup *p_identification_group);
  void doContaminantSelectionChanged();
  void doDecoySelectionChanged();
  void computeFdr();
  void computeMassPrecision();

  private:
  void connectNewPtmIslandListWindow();
  void connectNewProteinListWindow();
  void connectNewMsRunListWindow();
  void connectNewPeptideListWindow();
  void connectNewProteinDetailWindow();
  void connectNewEngineDetailWindow();
  void connectNewPeptideDetailWindow();
  void refresh();
  void showWaitingMessage(const QString title);
  void hideWaitingMessage();
  void viewError(const QString &error);

  /** @brief get PTM mode of the current project
   */
  PtmMode getPtmMode();


  private:
  //   QThread _worker_thread;
  Ui::ProjectView *ui;
  QWidget *_p_identification_widget = nullptr;

  /** @brief pointer on the main window
   */
  MainWindow *mp_mainWindow;
  std::list<ProteinListWindow *> _protein_list_window_collection;
  ProteinListWindow *_p_current_protein_list_window = nullptr;
  std::list<MsIdentificationListWindow *>
    _ms_identification_list_window_collection;
  MsIdentificationListWindow *_p_current_ms_identification_list_window =
    nullptr;
  std::list<EngineDetailWindow *> m_engine_detail_window_collection;
  EngineDetailWindow *m_current_engine_detail_window = nullptr;
  std::list<PeptideListWindow *> _peptide_list_window_collection;
  PeptideListWindow *_p_current_peptide_list_window = nullptr;
  std::list<ProteinWindow *> _protein_detail_window_collection;
  ProteinWindow *_p_current_protein_detail_window = nullptr;

  std::list<PeptideWindow *> _peptide_detail_window_collection;
  PeptideWindow *_p_current_peptide_detail_window = nullptr;
  std::list<PtmIslandListWindow *> _ptm_island_list_window_collection;
  PtmIslandListWindow *_p_current_ptm_island_list_window = nullptr;

  EditModifications *_p_edit_modifications = nullptr;
  EditLabelMethods *_p_edit_label_methods  = nullptr;
  XicWindow *_p_xic_window                 = nullptr;

  ProjectSp msp_project;

  std::vector<FastaFileSp> _fastafile_list;
  WaitingMessageDialog *_p_waiting_message_dialog;

  DeepProtGui *mpa_deepProtGui = nullptr;
  // QCPBars *_p_bars;

  std::vector<std::shared_ptr<PeptideEvidence>>
    m_memoryGuardPeptideEvidenceList;
};
