
/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of XTPcpp.
 *
 *     XTPcpp 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.
 *
 *     XTPcpp 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 XTPcpp.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/

#include <QSettings>
#include <QFileDialog>
#include <QMessageBox>
#include <QDebug>
#include <QCommandLineParser>
#include "../config.h"
#include "mainwindow.h"

#include "ui_main.h"
#include <pappsomspp/pappsoexception.h>
#include "../utils/utils.h"
#include "output/xpip.h"
#include "masschroq_run_dialog/masschroqfileparameters.h"

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::Main)
{
  qSetMessagePattern(QString("%{file}@%{line}, %{function}(): %{message}"));
  // http://pappso.inra.fr/demande/ws/pappso_software/xtpcpp
  _p_app = QCoreApplication::instance();
  ui->setupUi(this);
  setWindowTitle(QString("%1 %2").arg(SOFTWARE_NAME).arg(XTPCPP_VERSION));
  setWindowIcon(QIcon(":/xtpcpp_icon/resources/xtandempipeline_icon.svg"));

  mp_worker = new WorkerThread(this);
  mp_worker->moveToThread(&_worker_thread);
  _worker_thread.start();

  _p_load_results_dialog       = new LoadResultsDialog(this);
  _p_export_spreadsheet_dialog = new ExportSpreadsheetDialog(this);
  _p_waiting_message_dialog    = new WaitingMessageDialog(this);


  _project_window = new ProjectWindow(this);

  ui->menu_export_files->setDisabled(true);
  ui->actionMassChroQ->setDisabled(true);
  ui->centralwidget->layout()->addWidget(_project_window);
  _project_window->hide();
  ui->action_save_project->setDisabled(true);
  ui->default_display_widget->show();
  //_protein_list_window = new ProteinListWindow(this);
  // QDockWidget *dock = new QDockWidget(tr("Protein List"), this);
  // dock->setWidget(_protein_list_window);
  // addDockWidget(Qt::RightDockWidgetArea, dock);

  qRegisterMetaType<ProjectSp>("ProjectSp");
  qRegisterMetaType<AutomaticFilterParameters>("AutomaticFilterParameters");
  qRegisterMetaType<GroupingType>("GroupingType");

#if QT_VERSION >= 0x050000
  // Qt5 code
  connect(_p_load_results_dialog,
          &LoadResultsDialog::accepted,
          this,
          &MainWindow::doAcceptedLoadResultDialog);
  connect(_p_export_spreadsheet_dialog,
          &ExportSpreadsheetDialog::accepted,
          this,
          &MainWindow::doAcceptedExportSpreadsheetDialog);
  connect(&m_onlineVersion,
          &HttpVersion::httpVersionReady,
          this,
          &MainWindow::doCheckNewVersion);
  connect(this,
          &MainWindow::operateFreeAllMsRunReaders,
          _project_window,
          &ProjectWindow::doCleanMsRunReaders);

#else
#endif
}

MainWindow::~MainWindow()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  _worker_thread.quit();
  _worker_thread.wait();
  // if (_p_ms_data_file != nullptr) delete _p_ms_data_file;
  delete ui;
  // delete _project_window;
  delete _p_load_results_dialog;
  delete _p_export_spreadsheet_dialog;
  delete _p_waiting_message_dialog;
  if(_p_export_masschroq_dialog != nullptr)
    {
      delete _p_export_masschroq_dialog;
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

bool
MainWindow::stopWorkerThread()
{
  return _p_waiting_message_dialog->stopWorkerThread();
}

void
MainWindow::closeEvent(QCloseEvent *event)
{
  if(_project_sp != nullptr)
    {
      if(_project_sp.get()->getProjectChangedStatus() == true)
        {
          event->ignore();
          int ret = chooseSaveMssgBox();

          switch(ret)
            {
              case QMessageBox::Save:
                doActionSaveProject();
                event->accept();
                break;
              case QMessageBox::Discard:
                event->accept();
                break;
              case QMessageBox::Cancel:
                event->ignore();
                break;
              default:
                break;
            }
        }
      else
        {
          event->accept();
        }
    }
  else
    {
      event->accept();
    }
}

void
MainWindow::viewError(QString error)
{
  hideWaitingMessage();
  QMessageBox::warning(
    this, tr("Oops! an error occurred in XTPCPP. Don't panic :"), error);
}

void
MainWindow::doDisplayJobFinished(QString message)
{
  qDebug() << message;
  hideWaitingMessage();
  QMessageBox::information(this, tr("job finished"), message);
}

void
MainWindow::doDisplayJobCanceled(QString message)
{
  hideWaitingMessage();
  QMessageBox::warning(this, tr("job canceled"), message);
}

void
MainWindow::doDisplayLoadingMessage(QString message)
{
  qDebug() << message;
  _p_waiting_message_dialog->message(message);
  ui->statusbar->showMessage(message);
}

void
MainWindow::doDisplayLoadingMessagePercent(QString message, int value)
{
  qDebug() << message << " " << value;
  _p_waiting_message_dialog->message(message, value);
  ui->statusbar->showMessage(message);
}

void
MainWindow::doWorkerSetText(QString text)
{
  _p_waiting_message_dialog->setText(text);
}
void
MainWindow::doWorkerAppendText(const char *text)
{
  _p_waiting_message_dialog->appendText(text);
}
void
MainWindow::doActionQuit()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  this->close();
}

void
MainWindow::doAcceptedExportSpreadsheetDialog()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  try
    {
      QString format = this->_p_export_spreadsheet_dialog->getExportFormat();
      QSettings settings;
      QString default_location =
        settings.value("path/export_ods", "").toString();

      QString filename;
      if(format == "ods")
        {
          filename = QFileDialog::getSaveFileName(
            this,
            tr("Save ODS file"),
            QString("%1/untitled.ods").arg(default_location),
            tr("Open Document Spreadsheet (*.ods)"));

          settings.setValue("path/export_ods",
                            QFileInfo(filename).absolutePath());
        }
      else
        {
          filename = QFileDialog::getExistingDirectory(
            this, tr("Save TSV files"), QString("%1").arg(default_location));

          QDir parent(filename);
          parent.cdUp();
          settings.setValue("path/export_ods", parent.canonicalPath());
          qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << " "
                   << parent.absolutePath();
        }
      if(filename.isEmpty())
        {
          return;
        }


      showWaitingMessage(
        tr("writing %1 ODS file").arg(QFileInfo(filename).fileName()));
      emit operateWritingOdsFile(filename, format, _project_sp);
      // emit operateXpipFile(filename);
    }
  catch(pappso::PappsoException &error)
    {
      viewError(tr("Error while writing ODS file :\n%1").arg(error.qwhat()));
    }

  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doAcceptedTandemRunDialog()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  showWaitingMessage(tr("Running X!Tandem"));

  emit operateRunningXtandem(_p_tandem_run_dialog->getTandemRunBatch());
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doAcceptedLoadResultDialog()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  AutomaticFilterParameters param =
    _p_load_results_dialog->getAutomaticFilterParameters();
  QSettings settings;
  settings.setValue(
    "automatic_filter/cross_sample",
    QString("%1").arg(param.getFilterCrossSamplePeptideNumber()));
  settings.setValue("automatic_filter/peptide_number",
                    QString("%1").arg(param.getFilterMinimumPeptidePerMatch()));
  settings.setValue("automatic_filter/peptide_evalue",
                    QString("%1").arg(param.getFilterPeptideEvalue()));
  settings.setValue("automatic_filter/protein_evalue",
                    QString("%1").arg(param.getFilterProteinEvalue()));

  QStringList file_list = _p_load_results_dialog->getFileList();
  bool is_individual    = _p_load_results_dialog->isIndividual();

  showWaitingMessage(tr("Loading files"));
  emit operateLoadingResults(is_individual, param, file_list);
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doOperationFailed(QString error)
{
  hideWaitingMessage();
  viewError(error);
}
void
MainWindow::doOperationFinished()
{
  hideWaitingMessage();
}
void
MainWindow::doGroupingFinished()
{
  hideWaitingMessage();
  _project_window->setProjectSp(_project_sp);
}
void
MainWindow::doLoadingResultsReady(ProjectSp project_sp)
{
  qDebug();
  if(_p_load_results_dialog != nullptr)
    {
      _p_load_results_dialog->setProjectContaminants(project_sp.get());
    }
  doProjectReady(project_sp);
  qDebug();
}

void
MainWindow::doProjectReady(ProjectSp project_sp)
{
  _project_sp = project_sp;
  qDebug() << _project_sp.get()->getFastaFileStore().getFastaFileList().size();

  showWaitingMessage(tr("grouping proteins"));
  emit operateGrouping(project_sp);

  ui->menu_export_files->setDisabled(false);
  ui->actionMassChroQ->setDisabled(false);
  ui->actionModifications->setDisabled(false);
  ui->actionLabeling_methods->setDisabled(false);

  std::vector<MsRunAlignmentGroupSp> group_list =
    _project_sp->getMsRunAlignmentGroupList();
  if(_project_sp->getMsRunAlignmentGroupList().size() == 0)
    {
      std::shared_ptr<MsRunAlignmentGroup> name =
        std::make_shared<MsRunAlignmentGroup>(_project_sp.get(), "All");
      for(MsRunSp ms_run_sp : _project_sp->getMsRunStore().getMsRunList())
        {
          name->addMsRunToMsRunAlignmentGroupList(ms_run_sp);
        }
      _project_sp->addMsRunAlignmentGroupToList(name);
    }

  // Reset masschroq_run_dialog with new project
  if(_p_export_masschroq_dialog != nullptr)
    {
      delete _p_export_masschroq_dialog;
      _p_export_masschroq_dialog = nullptr;
    }

  _project_window->show();
  showProjectName();

  ui->default_display_widget->hide();
  ui->action_save_project->setDisabled(false);
  qDebug() << "end";
}

void
MainWindow::doActionLabelingMethods()
{
  _project_window->editLabelingMethods();
}
void
MainWindow::doActionModifications()
{
  _project_window->editModifications();
}

void
MainWindow::doProjectNotReady(QString error)
{
  viewError(error);
}


void
MainWindow::doActionTandemRun()
{
  try
    {
      if(_p_tandem_run_dialog == nullptr)
        {
          _p_tandem_run_dialog = new TandemRunDialog(this);
          connect(_p_tandem_run_dialog,
                  &TandemRunDialog::accepted,
                  this,
                  &MainWindow::doAcceptedTandemRunDialog);
        }
      _p_tandem_run_dialog->show();
      _p_tandem_run_dialog->raise();
      _p_tandem_run_dialog->activateWindow();
    }
  catch(pappso::PappsoException &error)
    {
      viewError(tr("Error opening X!Tandem run dialog window :\n%1")
                  .arg(error.qwhat()));
    }
}
void
MainWindow::loadResults()
{

  _p_load_results_dialog->show();
  _p_load_results_dialog->raise();
  _p_load_results_dialog->activateWindow();
}

void
MainWindow::hideWaitingMessage()
{

  _p_waiting_message_dialog->hide();
  ui->statusbar->showMessage("");
}

void
MainWindow::showWaitingMessage(const QString title)
{
  _p_waiting_message_dialog->setWindowTitle(title);
  _p_waiting_message_dialog->show();
  _p_waiting_message_dialog->raise();
  _p_waiting_message_dialog->activateWindow();
}

void
MainWindow::selectXpipFile()
{
  try
    {
      QSettings settings;
      QString default_location = settings.value("path/xpipfile", "").toString();

      QString filename =
        QFileDialog::getOpenFileName(this,
                                     tr("Open XPIP File"),
                                     default_location,
                                     tr("xpip files (*.xpip);;all files (*)"));

      if(filename.isEmpty())
        {
          return;
        }

      settings.setValue("path/xpipfile", QFileInfo(filename).absolutePath());
      showWaitingMessage(
        tr("Loading %1 XPIP file").arg(QFileInfo(filename).fileName()));
      emit operateXpipFile(filename);
    }
  catch(pappso::PappsoException &error)
    {
      viewError(tr("Error while reading XPIP file :\n%1").arg(error.qwhat()));
    }
}


void
MainWindow::doActionSaveProject()
{
  try
    {
      // QMessageBox::warning(this,
      //                     tr("Experimental feature"), "WARNING : project
      //                     files export is not ready");
      QSettings settings;
      QString default_location = settings.value("path/xpipfile", "").toString();


      QString filename = QFileDialog::getSaveFileName(
        this,
        tr("Save XPIP file"),
        QString("%1/%2.xpip")
          .arg(default_location)
          .arg(_project_sp.get()->getProjectName()),
        tr("XPIP (*.xpip)"));

      if(filename.isEmpty())
        {
          return;
        }

      settings.setValue("path/xpipfile", QFileInfo(filename).absolutePath());
      showWaitingMessage(
        tr("Writing %1 XPIP file").arg(QFileInfo(filename).fileName()));
      emit operateWritingXpipFile(filename, _project_sp);
      _project_sp.get()->setProjectName(filename);
      showProjectName();
    }
  catch(pappso::PappsoException &error)
    {
      viewError(tr("Error while writing XPIP file :\n%1").arg(error.qwhat()));
    }
}

void
MainWindow::doActionSpreadsheet()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  try
    {
      if(_project_sp.get() != nullptr)
        {
          _p_export_spreadsheet_dialog->setProject(_project_sp.get());
        }
      _p_export_spreadsheet_dialog->show();
      _p_export_spreadsheet_dialog->raise();
      _p_export_spreadsheet_dialog->activateWindow();
    }
  catch(pappso::PappsoException &error)
    {
      viewError(tr("Error doActionSpreadsheet :\n%1").arg(error.qwhat()));
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doActionSpectralCountingMcq()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;

  QSettings settings;
  QString default_location = settings.value("path/scmcqfile", "").toString();

  QString filename = QFileDialog::getSaveFileName(
    this,
    tr("Save spectral count TSV file"),
    QString("%1/untitled.tsv").arg(default_location),
    tr("TSV (*.tsv)"));

  if(filename.isEmpty())
    {
      return;
    }

  settings.setValue("path/scmcqfile", QFileInfo(filename).absolutePath());

  showWaitingMessage(tr("Writing %1 spectral count file for MassChroqR")
                       .arg(QFileInfo(filename).fileName()));
  emit operateWritingMcqrSpectralCountFile(filename, _project_sp);
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doActionFasta()
{
  QSettings settings;
  QString default_location = settings.value("path/fastafile", "").toString();

  QString filename = QFileDialog::getSaveFileName(
    this,
    tr("Save FASTA file"),
    QString("%1/untitled.fasta").arg(default_location),
    tr("FASTA (*.fasta)"));

  if(filename.isEmpty())
    {
      return;
    }

  settings.setValue("path/fastafile", QFileInfo(filename).absolutePath());

  showWaitingMessage(
    tr("Writing %1 FASTA file").arg(QFileInfo(filename).fileName()));
  emit operateWritingFastaFile(filename, _project_sp, ExportFastaType::all);
}


void
MainWindow::doActionFastaOneBySubgroup()
{
  QSettings settings;
  QString default_location = settings.value("path/fastafile", "").toString();

  QString filename = QFileDialog::getSaveFileName(
    this,
    tr("Save FASTA file"),
    QString("%1/untitled.fasta").arg(default_location),
    tr("FASTA (*.fasta)"));

  if(filename.isEmpty())
    {
      return;
    }

  settings.setValue("path/fastafile", QFileInfo(filename).absolutePath());

  showWaitingMessage(
    tr("Writing %1 FASTA file").arg(QFileInfo(filename).fileName()));
  emit operateWritingFastaFile(
    filename, _project_sp, ExportFastaType::oneBySubgroup);
}

void
MainWindow::doActionFastaOneByGroup()
{
  QSettings settings;
  QString default_location = settings.value("path/fastafile", "").toString();

  QString filename = QFileDialog::getSaveFileName(
    this,
    tr("Save FASTA file"),
    QString("%1/untitled.fasta").arg(default_location),
    tr("FASTA (*.fasta)"));

  if(filename.isEmpty())
    {
      return;
    }

  settings.setValue("path/fastafile", QFileInfo(filename).absolutePath());

  showWaitingMessage(
    tr("Writing %1 FASTA file").arg(QFileInfo(filename).fileName()));
  emit operateWritingFastaFile(
    filename, _project_sp, ExportFastaType::oneByGroup);
}

void
MainWindow::doActionMassChroQ()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;

  try
    {
      _project_sp.get()->checkPsimodCompliance();
      if(_p_export_masschroq_dialog == nullptr)
        {
          _p_export_masschroq_dialog = new MassChroqRunDialog(this, mp_worker);
        }

      MasschroqFileParameters params;
      params.load();
      if(_project_sp.get() != nullptr)
        {
          _p_export_masschroq_dialog->setMasschroqFileParameters(params);
          _p_export_masschroq_dialog->setProjectSPtr(this->_project_sp);
          _p_export_masschroq_dialog->setAlignmentGroups();
        }
      _p_export_masschroq_dialog->show();
      _p_export_masschroq_dialog->raise();
      _p_export_masschroq_dialog->activateWindow();
    }
  catch(pappso::PappsoException &error)
    {
      viewError(tr("Error doActionMassChroQ :\n%1").arg(error.qwhat()));
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}


void
MainWindow::doAcceptedMassChroqRunDialog()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  try
    {

      MasschroqFileParameters params =
        _p_export_masschroq_dialog->getMasschroqFileParameters();
      params.save();
      qDebug() << params.alignment_groups.size();
      QSettings settings;
      QString default_location = settings.value("path/mcqfile", "").toString();

      QString filename = QFileDialog::getSaveFileName(
        this,
        tr("Save MassChroqML file"),
        QString("%1/untitled.masschroqml").arg(default_location),
        tr("MassChroqML (*.masschroqml)"));

      if(filename.isEmpty())
        {
          return;
        }

      settings.setValue("path/mcqfile", QFileInfo(filename).absolutePath());

      showWaitingMessage(
        tr("Writing %1 MassChroqML file").arg(QFileInfo(filename).fileName()));
      emit operateWritingMassChroqFile(filename, _project_sp, params);
    }
  catch(pappso::PappsoException &error)
    {
      viewError(
        tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat()));
    }

  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doWritingMassChroQmlFileFinished(QString masschroqml_file)
{
  if(_p_export_masschroq_dialog->getMassChroqRunStatus())
    {
      _p_export_masschroq_dialog->setMassChroqRunBatchParam(masschroqml_file);
      showWaitingMessage(tr("Running MassChroQ"));
      emit operateRunningMassChroq(
        _p_export_masschroq_dialog->getMassChroqRunBatchParam());
    }
}

void
MainWindow::doActionMassChroqPRM()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  try
    {
      _project_sp.get()->checkPsimodCompliance();

      QSettings settings;
      QString default_location =
        settings.value("path/mcqprmfile", "").toString();

      QString filename = QFileDialog::getSaveFileName(
        this,
        tr("Save MassChroqPRM file"),
        QString("%1/untitled.masschroqprm").arg(default_location),
        tr("MassChroqPRM (*.masschroqprm)"));

      if(filename.isEmpty())
        {
          return;
        }

      settings.setValue("path/mcqprmfile", QFileInfo(filename).absolutePath());

      showWaitingMessage(
        tr("Writing %1 MassChroqPRM file").arg(QFileInfo(filename).fileName()));
      emit operateWritingMassChroqPrmFile(filename, _project_sp);
      // emit operateXpipFile(filename);
    }
  catch(pappso::PappsoException &error)
    {
      viewError(
        tr("Error while writing MassChroqML file :\n%1").arg(error.qwhat()));
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doActionProticDb()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  try
    {
      _project_sp.get()->checkPsimodCompliance();

      QSettings settings;
      QString default_location =
        settings.value("path/proticfile", "").toString();

      QString filename = QFileDialog::getSaveFileName(
        this,
        tr("Save PROTICdbML file"),
        QString("%1/untitled.proticdbml").arg(default_location),
        tr("PROTICdbML (*.proticdbml)"));

      if(filename.isEmpty())
        {
          return;
        }

      settings.setValue("path/proticfile", QFileInfo(filename).absolutePath());

      showWaitingMessage(
        tr("Writing %1 PROTICdbML file").arg(QFileInfo(filename).fileName()));
      emit operateWritingProticFile(filename, _project_sp);
      // emit operateXpipFile(filename);
    }
  catch(pappso::PappsoException &error)
    {
      viewError(
        tr("Error while writing PROTICdbML file :\n%1").arg(error.qwhat()));
    }
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doActionAbout()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  if(_p_about_dialog == nullptr)
    {
      _p_about_dialog = new AboutDialog(this);
    }
  _p_about_dialog->show();
  _p_about_dialog->raise();
  _p_about_dialog->activateWindow();

  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doActionSettings()
{
  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
  if(_p_edit_settings == nullptr)
    {
      _p_edit_settings = new EditSettings(this);
    }
  _p_edit_settings->show();
  _p_edit_settings->raise();
  _p_edit_settings->activateWindow();

  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
}

void
MainWindow::doCheckNewVersion()
{
  qDebug();
  if(m_onlineVersion.isNewVersion())
    {

      hideWaitingMessage();
      int ret = QMessageBox::warning(
        this,
        tr("new version available"),
        tr("A new %1 version is available %2\nCheck our web site \n"
           "%3\n to download it")
          .arg(SOFTWARE_NAME)
          .arg(m_onlineVersion.getVersion())
          .arg(m_onlineVersion.getPermalink()));
      if(ret == QMessageBox::Ok)
        {
          QDesktopServices::openUrl(QUrl(m_onlineVersion.getPermalink()));
        }
    }

  qDebug();
}


// 10ms after the application starts this method will run
// all QT messaging is running at this point so threads, signals and slots
// will all work as expected.
void
MainWindow::run()
{

  QTextStream errorStream(stderr, QIODevice::WriteOnly);

  try
    {
      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
      QCommandLineParser parser;

      // throw pappso::PappsoException("test");
      parser.setApplicationDescription(
        QString(SOFTWARE_NAME).append(" ").append(XTPCPP_VERSION));
      parser.addHelpOption();
      parser.addVersionOption();
      parser.addPositionalArgument(
        "XPIP project file",
        QCoreApplication::translate("main", "Project file to open."));

      qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;

      // Process the actual command line arguments given by the user
      parser.process(*_p_app);


      QStringList xpip_list = parser.positionalArguments();
      if(xpip_list.size() > 0)
        {
          showWaitingMessage(tr("Loading %1 XPIP file").arg(xpip_list.at(0)));
          emit operateXpipFile(xpip_list.at(0));
        }
    }
  catch(pappso::PappsoException &error)
    {
      viewError(
        tr("Oops! an error occurred in X!TandemPipeline. Don't panic :\n%1")
          .arg(error.qwhat()));
    }

  catch(std::exception &error)
    {
      viewError(
        tr("Oops! an error occurred in X!TandemPipeline. Don't panic :\n%1")
          .arg(error.what()));
    }
}

void
MainWindow::showProjectName()
{
  if(_project_sp.get() != nullptr)
    {
      QString project_name = _project_sp.get()->getProjectName();
      setWindowTitle(QString("%1 - %2 %3")
                       .arg(project_name)
                       .arg(SOFTWARE_NAME)
                       .arg(XTPCPP_VERSION));
      emit projectNameChanged(project_name);
    }
}

int
MainWindow::chooseSaveMssgBox()
{
  QMessageBox save_box;
  save_box.setIcon(QMessageBox::Warning);
  save_box.setWindowTitle(
    QString("Save %1 Project?").arg(_project_sp.get()->getProjectName()));
  save_box.setText("The project has been modified.");
  save_box.setInformativeText("Do you want to save your changes?");
  save_box.setStandardButtons(QMessageBox::Save | QMessageBox::Discard |
                              QMessageBox::Cancel);
  save_box.setDefaultButton(QMessageBox::Save);
  int ret = save_box.exec();
  return ret;
}

WorkerThread *
MainWindow::getWorkerThread()
{
  return mp_worker;
}

void
MainWindow::doFreeAllMsRunReaders()
{
  emit operateFreeAllMsRunReaders();
}
