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


#pragma once


/////////////////////// StdLib includes
#include <chrono>

/////////////////////// Qt includes
#include <QString>
#include <QByteArray>
#include <QRegularExpression>
#include <QTextStream>


/////////////////////// Local includes
#include "types.h"
#include "processing/specglob/types.h"
#include "exportinmportconfig.h"


namespace pappso
{

class Trace;

class PMSPP_LIB_DECL Utils
{
  public:
  static QString getVersion();
  static QRegularExpression unsignedDoubleNumberNoExponentialRegExp;
  static QRegularExpression anythingButDigitDotDash;
  static QRegularExpression signedDoubleNumberExponentialRegExp;

  //! Regular expression matching <numerical value><non-numerical*><numerical
  //! value>
  static QRegularExpression xyMassDataFormatRegExp;

  //! Regular expression matching <m/z value><non-numerical*>
  static QRegularExpression mzListDataFormatRegExp;

  //! Regular expression matching <size_t><non-numerical*>
  static QRegularExpression sizetListDataFormatRegExp;

  //! Regular expression that tracks the end of line in text files.
  static QRegularExpression endOfLineRegExp;

  static const QString getLexicalOrderedString(unsigned int num);
  static void writeLexicalOrderedString(QTextStream *p_out, unsigned int num);

  static int zeroDecimalsInValue(pappso_double value);
  static pappso_double roundToDecimals(pappso_double value, int decimal_places);
  static long long int
  roundToDecimal32bitsAsLongLongInt(pappso::pappso_double input);

  static std::string toUtf8StandardString(const QString &text);

  static bool writeToFile(const QString &text, const QString &file_name);
  static bool appendToFile(const QString &text, const QString &file_name);
  static std::size_t
  extractScanNumberFromMzmlNativeId(const QString &spectrum_native_id);

  static QString pointerToString(const void *const pointer);

  static bool almostEqual(double value1, double value2, int decimalPlaces = 10);

  static double nearestGreater(double value);

  static QString
  chronoTimePointDebugString(const QString &msg,
                             std::chrono::system_clock::time_point chrono_time =
                               std::chrono::system_clock::now());

  static QString chronoIntervalDebugString(
    const QString &msg,
    std::chrono::system_clock::time_point chrono_start,
    std::chrono::system_clock::time_point chrono_finish =
      std::chrono::system_clock::now());

  static std::vector<double>
  splitMzStringToDoubleVectorWithSpaces(const QString &text,
                                        std::size_t &error_count);

  static std::vector<std::size_t>
  splitSizetStringToSizetVectorWithSpaces(const QString &text,
                                          std::size_t &error_count);

  /** @brief convenient function to transform a boolean to QString "TRUE" or
   * "FALSE" QString returned is readable by R
   * @return QString "TRUE" or "FALSE"
   */
  static QString booleanToString(bool value);

  /** @brief Convenience function to return a string describing the MzFormat of
   * a file
   * @return QString like "brukerTims" for enum value MzFormat::brukerTims.
   */
  static QString msDataFormatAsString(MsDataFormat mz_format);
  static QString fileReaderTypeAsString(FileReaderType file_reader_type);

  /** @brief Convenience function to return a string describing the specglob
  alingment type
   * @return QString
   */
  static QString toString(specglob::SpectralAlignmentType type);

  /** @brief Convenience function to return a string describing the specglob
   * experimental spectrum data point
   * @return QString
   */
  static QString toString(specglob::ExperimentalSpectrumDataPointType type);
};

} // namespace pappso
