// bytran -|- spectral calculations for portable devices using the HITRAN database
//
// Developed by Dzianis Pliutau (Denis Plutov) and Kostya Roslyakov
// www.bytran.org | contact@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 with all the main calculaion paramters
#ifndef PARAMS_H
#define PARAMS_H

#include <QObject>
#include <QVector>
#include "hitranonemol.h"
#include "oneslantlayer.h"

class Params: public QObject
{
    Q_OBJECT

public:

    Params(QObject *parent = 0);

    // Method to initialize the horizontal path parameters from the standard atmospheric models
    void initHorizPathParamsFromStandardAtmModel(OneAtmModel *newOneAtmModel);

    // Function to read the contents of the HITRAN TIPS file
    void readCumulativeTipsFileContents(QString fileName);

    // Method to read the TIPs values from individual files (2016 HITRAN format for the online database listing)
    // This method does not download the data from HITRAN online but assumes that all the data has already been downloaded
    void read2016HitranOnlineTipsFilesContents();
    // This method used signal-slots because on a cell phone the read operations are sometimes slow and not everything gets read (need to wait for each operation to complete)
    void read2016HitranOnlineTipsFilesContentsRecursively();

    // This method will read the TIPS data from the HITRAN online formatted one and prepare TIPS strings which may be embedded into an application
    void readConvert2016HitranOnlineTipsFilesContents(QString folderName);

    // Function to read the contents of the HITRAN file with the molecular parameters
    void readMolparamFileContents(QString fileName);

    // Horizonatal path parameters
    OneSlantLayer *getHorizParams();
    void setHorizParams(OneSlantLayer *newHorizParams);

    // Array (of type hitranOneMolObj) with the parameters for each isotope and molecule
    QVector<HitranOneMol> *getMol();
    void setMol(QVector<HitranOneMol> *newMol);
    HitranOneMol *getMolAt(int index);
    void setMolAt(int index, HitranOneMol *newMol);

    // Method to get molecule information at a particular index
    //HitranOneMol *getMolAt(int index);

    // Number of molecules in the HITRAN database;
    int getNumMols();
    void setNumMols(int newNumMols);

    // Variable indicating if the horizontal or slant path calculations are to be performed (o - horizontal, 1 - slant)
    int getHorizVsSlant();
    void setHorizVsSlant(int newHorizVsSlant);

    // Methods to get and set the total internal partition sums temperature values
    QVector<double> getTipsTempArray();
    void setTipsTempArray(QVector<double> newTempArray);
    double getTipsTempValueAtIndex(int index);
    void setTipsTempValueAtIndex(int index, double tempValue);

    // Method to get and set the HITRAN database units
    bool getHitranUnits();
    void setHitranUnits(bool newHitranUnits);

    // Methods to get and set the TIPS folder
    QString getTipsFolder();
    void setTipsFolder(QString newTipsFolder);

    // Methods to get and set the lineshape profile
    int getLineshapeProfile();
    void setLineshapeProfile(int newLineshapeProfile);

    // Methods to get and set the line wing (in saturated line widths) contribution
    int getWingContribSatHw();
    void setWingContribSatHw(int newLineWingContrib);
    // Absolute line wing contribution
    double getWingContribAbs();
    void setWingContribAbs(double newWingContribAbs);

    // Methods to get and set the line broadening type to use
    int getLineBroadening();
    void setLineBroadening(int newLineBroadening);

    // Method to get and set the intensity threshold
    double getIntensThresh();
    void setIntensThresh(double newIntensThresh);

    // Method to set the state of a variable indicating if the line shift should be used or not
    bool getUseLineShift();
    void setUseLineShift(bool newUseLineShift);

    // Methods to get and set the state of the variable indicating if not selected molecules are to be included in calcualtions
    bool getCalcNotSelectedMols();
    void setCalcNotSelectedMols(bool newCalcNotSelectedMols);

signals:

    // Signal is called to read one TIPS file
    void accessNextTipsFile(int i, int j);
    void readingTipsFilesComplete();
    void readingMolParamsComplete();

    // Signal used to send notifications to the user of what is going on in the program
    void notify(QString message, double value, bool visible, bool cancelButtonVisible);

private slots:

    // Slot to read a single TIPS file
    void readOneTipsFile(int i, int j);

    // Slot to read in temperature values corresponding to the TIPS values
    void readTempTipsValues();

private:

    // Methos to create connections
    void createActions();

    // Method to initialize the molecular parameters from internal variables
    void initMolParams();

    // Method to initialize colors for molecules
    void initColorsAndGlobalIds();

    // Horizonatal path parameters
    OneSlantLayer horiz;  // Horizontal path parameters (temperature, total pressure, horizontal path length)

    QVector<HitranOneMol> mol;  // Array (of type hitranOneMolObj) with the parameters for each isotope and molecule
    int numMols;       // Number of molecules in the HITRAN database;
    int horizVsSlant;  // Variable indicating if the horizontal or slant path calculations are to be performed (o - horizontal, 1 - slant)

    QVector<double> tipsTempValues;  // Temperature values corresponding to the Total Internal Partition sum values

    bool hitranUnits;    // Absorption coefficient units, 0 - cm^2 / molec, 1 - cm-1;
    QString tipsFolder;  // Path to the folder containing the TIPS coefficients data

    // Parameters related to an individual spectral line
    int lineshapeProfile;   // 0 - Doppler, 1 - Lorentz, 2 - Voigt, 3 - Hartmann-Tran
    int wingContribSatHw;   // Line wing contribution in saturated line widths
    double wingContribAbs;  // Absolute wing contribution (in cm-1)
    int lineBroadening;     // 0 - Air, 1 - Self, 2 - Both (Air and self)
    double intensThresh;    // HAPI equivalent - Absolute value of minimum intensity in cm/molec to consider. NOTE: default value is 0.
    bool useLineShift;      // Variable indicates that the line shift should be used in calculations

    // Variable indicating the number of TIPS data points
    double numTipsPoints;   // Number of TIPS data points

    // Variable indicates if not selected molecules are to be included in calculations
    bool calcNotSelectedMols;

};

#endif // PARAMS_H
