/* BEGIN software license
 *
 * msXpertSuite - mass spectrometry software suite
 * -----------------------------------------------
 * Copyright(C) 2009,...,2018 Filippo Rusconi
 *
 * http://www.msxpertsuite.org
 *
 * This file is part of the msXpertSuite project.
 *
 * The msXpertSuite project is the successor of the massXpert project. This
 * project now includes various independent modules:
 *
 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
 *
 * This program 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.
 *
 * This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * END software license
 */


#pragma once


/////////////////////// Qt includes
#include <QMainWindow>
#include <QGraphicsScene>
#include <QClipboard>
#include <QProgressBar>


/////////////////////// Local includes
#include <ui_SequenceEditorWnd.h>
#include <massxpert/gui/AbstractMainTaskWindow.hpp>
#include <massxpert/nongui/CalcOptions.hpp>
#include <massxpert/nongui/Polymer.hpp>
#include <libmass/IonizeRule.hpp>
#include <massxpert/nongui/PolChemDef.hpp>
#include <massxpert/gui/MonomerCodeEvaluator.hpp>
#include <massxpert/gui/SequenceEditorGraphicsView.hpp>


namespace msXpSmassXpert
{

class SequenceEditorGraphicsView;


class SequenceEditorFindDlg;

class SequenceEditorWnd : public AbstractMainTaskWindow
{
  Q_OBJECT

  private:
  Ui::SequenceEditorWnd m_ui;

  // The results-exporting strings. ////////////////////////////////
  QString *mpa_resultsString;
  QString m_resultsFilePath;
  //////////////////////////////////// The results-exporting strings.

  QMenu *fileMenu;
  QMenu *fileImportMenu;
  QMenu *editMenu;
  QMenu *chemistryMenu;
  QMenu *optionsMenu;
  QMenu *calculatorMenu;

  QAction *closeAct;
  QAction *saveAct;
  QAction *saveAsAct;
  QAction *importRawAct;
  QAction *importPdbProtAct;
  QAction *exportClipboardAct;
  QAction *exportFileAct;
  QAction *exportSelectFileAct;

  QAction *clipboardCopyAct;
  QAction *clipboardCutAct;
  QAction *clipboardPasteAct;
  QAction *findSequenceAct;

  QAction *modifMonomerAct;
  QAction *modifPolymerAct;
  QAction *crossLinkMonomersAct;
  QAction *cleaveAct;
  QAction *fragmentAct;
  QAction *massSearchAct;
  QAction *mzCalculationAct;
  QAction *compositionsAct;
  QAction *pkaPhPiAct;

  QAction *decimalPlacesOptionsAct;

  QAction *newCalculatorWholeSequenceMassesAct;
  QAction *newCalculatorSelectedSequenceMassesAct;

  // Allocated but reparented to QStatusBar.
  QProgressBar *mp_progressBar;

  Polymer *mpa_polymer = 0;
  PolChemDef *mp_polChemDef;
  CalcOptions m_calcOptions;
  msXpSlibmass::IonizeRule m_ionizeRule;

  QList<Prop *> m_propList;

  void writeSettings();
  void readSettings();

  // Before the creation of the polChemDef/polymer relationship.
  bool initialize();

  // Creates the polChemDef/polymer relationship.
  bool postInitialize();

  void closeEvent(QCloseEvent *event);

  void focusInEvent(QFocusEvent *event);
  void focusOutEvent(QFocusEvent *event);

  void createActions();
  void createMenus();

  void keyPressEvent(QKeyEvent *);

  // The results-exporting functions. ////////////////////////////////
  void prepareResultsTxtString();
  //////////////////////////////////// The results-exporting functions.

  public:
  SequenceEditorWnd(MainWindow *parent);

  ~SequenceEditorWnd();

  bool m_forciblyClose   = 0;
  bool m_postInitialized = 0;

  SequenceEditorGraphicsView *mpa_editorGraphicsView;
  QGraphicsScene *mpa_editorGraphicsScene;

  QProgressBar *progressBar();

  bool openSequence(QString &);
  bool newSequence(QString &);
  bool maybeSave();

  void updateMonomerPosition(int);

  PolChemDef *preparePolChemDef(const QString &);
  void populateCalculationOptions();
  bool populateMonomerCodeList(bool = false);

  bool readFile(const QString &);

  const PolChemDef *polChemDef() const;
  PolChemDef *polChemDef();

  Polymer *polymer();
  QList<Prop *> *propList();

  const CalcOptions &calcOptions() const;
  const msXpSlibmass::IonizeRule &ionizeRule() const;

  void clearCompletionsListSelection();
  void completionsListSelectAt(int);

  void setWindowModified(bool);

  void updateWindowTitle();

  void getsFocus();

  void wholeSequenceMasses(double * = 0, double * = 0);
  void selectedSequenceMasses(double * = 0, double * = 0);

  void updatePolymerEndsModifs();

  void newCalculator(QString, QString);

  signals:
  void polymerSequenceModifiedSignal();
  void polymerSequenceWndAboutToClose(SequenceEditorWnd *);


  public slots:
  bool save();
  bool saveAs();

  void updateWholeSequenceMasses(bool = false);
  void updateSelectedSequenceMasses(bool = false);

  // Sequence importers.
  void importRaw();
  void importPdbProt();

  void exportClipboard();
  void exportFile();
  bool exportSelectFile();

  void clipboardCopy(QClipboard::Mode = QClipboard::Clipboard);
  void clipboardCut(QClipboard::Mode = QClipboard::Clipboard);
  void clipboardPaste(QClipboard::Mode = QClipboard::Clipboard);
  void clipboardClear(QClipboard::Mode);
  void findSequence();

  void vignetteSizeChanged();
  void nameLineEditChanged(const QString &text);

  void calculationOptionsChanged();

  void leftModifOptionsChanged();
  void forceLeftModifOptionsChanged();
  void rightModifOptionsChanged();
  void forceRightModifOptionsChanged();

  void multiRegionSelectionOptionChanged(int);
  bool isMultiRegionSelection();

  void regionSelectionOligomerOptionChanged(bool);
  void regionSelectionResChainOptionChanged(bool);

  int coordinatesManuallyEdited(const QString &);

  void multiSelectionRegionOptionChanged(int);
  bool isMultiSelectionRegion();

  void monomerModifOptionChanged(int);

  void monomerCrossLinkOptionChanged(int);

  void modifMonomer();

  void modifPolymer();
  void modifLeftEnd();
  void modifRightEnd();

  void crossLinkMonomers();

  void cleave();
  void fragment();
  void massSearch();
  void mzCalculation();
  void compositions();
  void pkaPhPi();

  void decimalPlacesOptions();

  void newCalculatorWholeSequenceMasses();
  void newCalculatorSelectedSequenceMasses();

  void crossLinksPartiallyEncompassedSlot(int);

  void vignetteListWidgetItemDoubleClicked(QListWidgetItem *);
};

} // namespace msXpSmassXpert
