// bytran -|- spectral calculations for portable devices using the HITRAN database
//
// Developed by Dzianis Pliutau (Denis Plutov) and Kostya Roslyakov
// www.bytran.org | bytran@bytran.org
// Copyright (c) 2016 Dzianis Pliutau
// Distributed under the MIT license
//
// The MIT License (MIT)
// Copyright (c) 2016 Dzianis Pliutau
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.



// Object to read/write HITRAN lines within a specified spectral range
#ifndef HITRANINPUTOUTPUT_H
#define HITRANINPUTOUTPUT_H

#include <QVector>
#include "hitranonerec.h"
#include "spectrum.h"
#include "hitranonemol.h"
#include <QByteArray>

class HitranInputOutput
{

public:

    HitranInputOutput();

    // Methods to get and set the path to the HITRAN database file
    QString getHitranDbFilePath();
    void setHitranDbFilePath(QString newHitranDbFilePath);

    // Method to get and set the segmented HITRAN folder
    QString getSegmentedHitranFolder();
    void setSegmentedHitranFolder(QString newSegmentedHitranFolder);

    // Method to get the number of the start and end record corresponding to a given start and end wavenumbers
    void getCumulativeStartEndRecNum(QString fileName, double wn, quint64 *byte);
    void getCumulativeStartEndRecNum(double fromWn, double toWn, quint64 *fromByte, quint64 *toByte);
    void getCumulativeStartEndRecNum(QString fileName, double fromWn, double toWn, quint64 *fromByte, quint64 *toByte);

    // Method to read HITRAN records from the cumulative HITRAN file based on the start and end indexes as opposed to wavenumber range
    bool readCumulativeHitranData(QString filePath, quint64 fromByte, quint64 toByte);
    void readCumulativeHitranData(quint64 fromByte, quint64 toByte);

    // Reading records from a certain wavenumber up to a given wavenumber from the HITRAN database
    void readRecordsText(QString fileName, double fromWn, double toWn);
    void readRecordsText(double fromWn, double toWn);

    // Method to get the segmented HITRAN folder start and end byte indexes and file numbers
    void getSegmentedStartEndRecNum(double fromWn, double toWn, int *fromFileIndex, int *toFileIndex, quint64 *fromByte, quint64 *toByte);

    // Method to read a segment from the segmented HITRAN folder and return new starting points variables
    void readSegmentedHitran(quint64 *fromByte, int *fromFileIndex, quint64 downloadBytes);

    // Method to get the number of records for segmented HITRAN files based on the start and end index and file number
    quint64 getNumSegmentedRecsToProcess(int fromFileIndex, int toFileIndex, quint64 fromByte, quint64 toByte);

    // Method to get the array with the read in HITRAN data
    QVector<HitranOneRec> *getReadInData();

    // Method to get the string lines read in from the HITRAN database (no conversion to numerical representation)
    QVector<QString> *getStrLines();

    // Method to save data to file (usually appending at the right place)
    void saveDataToFile(QString *data);

    // Method to find the HITRAN download grid
    void findHitranDownloadGrid(QString fileName, QString outputFile);

    // Method to set the byte array and convert it to HITRAN variables
    void setByteArrayData(QByteArray *hitranData);

private:

    // Function to extract line-by-line data for a single spectral line
    void extractLineByLineData2004Hitran(QString lineStr, HitranOneRec *lineData);

    // Bubble sort for the lidar of file name strings
    void bubbleSort(QStringList *arr);

    // Variable with the HITRAN data
    QVector<HitranOneRec> data;

    // HITRAN lines
    QVector<QString> strLines;

    // Path to the HITRAN database file
    QString hitranDbFilePath;

    // Path to segmented files HITRAN database folder
    QString segmentedHitranFolder;

};

#endif // HITRANINPUTOUTPUT_H
