/* 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 <QtSql>
#include <QSqlDatabase>
#include <QStringList>

/////////////////////// Local includes
#include <minexpert/nongui/globals.hpp>
#include <minexpert/nongui/MassSpecDataSet.hpp>
#include <libmass/MassSpectrum.hpp>
#include <minexpert/nongui/History.hpp>
#include <minexpert/nongui/MassSpecDataFileLoader.hpp>
#include <minexpert/nongui/MassSpecSqlite3Handler.hpp>


namespace msXpSmineXpert
{


//! The MassSpecDataFileLoaderSqlite3  class provides a file loader.
/*!

  This class implements a file loader for the SQLite3 db file format. This
  file format can be used starting from a mzML-formatted file using the
  convert feature of mineXpert (run mineXpert --help).


*/
class MassSpecDataFileLoaderSqlite3 : public MassSpecDataFileLoader
{
  Q_OBJECT

  private:
  //! Holder for details of the mass spectrometry data file.
  MassSpecFileMetaData m_msFileMetaData;

  //! Number of parsed spectra before updating the feedback message.
  /*!

    Upon loading mass spectrometry data files, which might be lengthy, we
    provide feedback messages to be displayed to the user. This number indicates
    at what mass spectrum load interval the feedback message is updated to the
    user.

*/
  // How many spectra do we parse before providing a feedback message on the
  // progression of the parsing of the file?
  int m_parseProgressionNumber = 100;

  QString formatDescription() const override;

  bool isDriftExperiment(MassSpecSqlite3Handler &handler,
                         QSqlDatabase &database);

  QString craftSqlSelectStatementForStreamedIntegration(
    const History &history, bool withRecordCountStatement, bool integrateToDt);

  int loadSpectra(QSqlDatabase &database,
                  MassSpecSqlite3Handler &handler,
                  int firstId,
                  int lastId,
                  MassSpecDataSet *massSpecDataSet,
                  int &dataKind);

  int loadSpectra(QSqlDatabase &database,
                  MassSpecSqlite3Handler &handler,
                  const QString &sqlQueryString,
                  MassSpecDataSet *massSpecDataSet,
                  int &dataKind);

  int loadSpectraByRt(double retentionTime /*scanStartTime*/,
                      QList<msXpSlibmass::MassSpectrum *> *massSpectra);

  int streamedRtIntegration(const History &history,
                            QVector<double> *keyVector,
                            QVector<double> *valVector);

  int streamedMzIntegration(const History &history,
                            QVector<double> *keyVector,
                            QVector<double> *valVector);

  int streamedDtIntegration(const History &history,
                            QVector<double> *keyVector,
                            QVector<double> *valVector);

  public:
  MassSpecDataFileLoaderSqlite3(const QString &fileName = QString());
  virtual ~MassSpecDataFileLoaderSqlite3();

  static bool canLoadData(QString fileName);

  int readSpectrumCount() override;
  int readSpectrumCount(QSqlDatabase &database,
                        MassSpecSqlite3Handler &handler);

  int loadData(QSqlDatabase &database,
               MassSpecSqlite3Handler &handler,
               MassSpecDataSet *massSpecDataSet);

  int streamedIntegration(const History &history,
                          IntegrationType integrationType,
                          QVector<double> *keyVector,
                          QVector<double> *valVector);

  int streamedTicIntensity(const History &history, double *intensity);
};


} // namespace msXpSmineXpert
// namespace msXpSmineXpert
