// 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 used to pass spectral results calculations to the plot from the core module and its components
// This has to use platform specific implementations (Android or iPhone OS etc.)
#ifndef SPECTRARESULTSQML_H
#define SPECTRARESULTSQML_H

#include <QObject>
#include "spectrum.h"
#include "bytrancore.h"
#include "radiance.h"

class SpectraResultsQml : public QObject
{
    Q_OBJECT

    Q_PROPERTY(Spectrum spectrum READ spectrum NOTIFY spectrumChanged)
    Q_PROPERTY(QVector<double> wnGrid READ wnGrid NOTIFY wnGridChanged)
    Q_PROPERTY(double minX READ minX NOTIFY minXChanged)
    Q_PROPERTY(double maxX READ maxX NOTIFY maxXChanged)
    Q_PROPERTY(double minY READ minY NOTIFY minYChanged)
    Q_PROPERTY(double maxY READ maxY NOTIFY maxYChanged)
    Q_PROPERTY(QString xAxisTitle READ xAxisTitle NOTIFY xAxisTitleChanged)
    Q_PROPERTY(QString yAxisTitle READ yAxisTitle NOTIFY yAxisTitleChanged)
    Q_PROPERTY(QString lineColor READ lineColor NOTIFY lineColorChanged)
    Q_PROPERTY(int currSpecIndex READ currSpecIndex WRITE setCurrSpecIndex NOTIFY currSpecIndexChanged)
    Q_PROPERTY(bool showTotal READ showTotal WRITE setShowTotal NOTIFY showTotalChanged)
    Q_PROPERTY(int heightPoints READ heightPoints WRITE setHeightPoints NOTIFY heightPointsChanged)
    Q_PROPERTY(bool showPlainTotal READ showPlainTotal WRITE setShowPlainTotal NOTIFY showPlainTotalChanged)
    Q_PROPERTY(bool showInstrTotal READ showInstrTotal WRITE setShowInstrTotal NOTIFY showInstrTotalChanged)

public:

    Q_INVOKABLE void updatePlot();
    Q_INVOKABLE void updatePlotMolsOnlyPreserveScale();
    Q_INVOKABLE void updatePlotAllPreserveScale();
    Q_INVOKABLE void updateXAxis();
    Q_INVOKABLE void updateYAxis();

    explicit SpectraResultsQml(QObject *parent = nullptr, BytranCore *inCore = nullptr);

    // Methods to get the scale range along the vertical and horizontal axes
    double minX() const;
    double maxX() const;
    double minY() const;
    double maxY() const;

    Spectrum spectrum() const;

    QVector<double> wnGrid() const;

    // Method to get the X axis title
    QString xAxisTitle();

    // Method to get the Y axis title
    QString yAxisTitle();

    // Color to use for plotting the spectrum
    QString lineColor() const;

    // Methods to get and set the current spectrum index
    int currSpecIndex() const;
    void setCurrSpecIndex(const int currSpecIndex);

    // Methods to get and set the showTotal variable
    bool showTotal() const;
    void setShowTotal(const bool &showTotal);

    // Methods to set the number of points along the vertical axis
    int heightPoints() const;
    void setHeightPoints(const int &heightPoints);

    // Method to set a variable indicating if the plain total spectrum is to be displayed
    bool showPlainTotal() const;
    void setShowPlainTotal(const bool &showPlainTotal);

    // Method to set a variable indicating if the instrument function processed spectrum is to be displayed
    bool showInstrTotal() const;
    void setShowInstrTotal(const bool &showInstrTotal);

signals:

    // Signals to notify of select all changed and units changed states
    void spectrumChanged();

    // Signal indicating that the wavenumber grid has changed
    void wnGridChanged();

    // Signals emited when the X and/or Y minimum and maximum axes values are changed
    void minXChanged();
    void maxXChanged();
    void minYChanged();
    void maxYChanged();

    // Signal emitted when the X axis title has been changed
    void xAxisTitleChanged();

    // Signal emited when the Y-axis titles has been changed
    void yAxisTitleChanged();

    // Signal indicating that the update plot variable has changed
    void updatePlotChanged();

    // Signal is emitted when the current spectrum index is modified
    void currSpecIndexChanged();

    // Signal indicating that the color of the line to be used for plotting the spectrum has changed
    void lineColorChanged();

    // Signal emited when the show total variable is changed
    void showTotalChanged();

    // Emited when the number of height points is changed
    void heightPointsChanged();

    // Signals emited when the variable indicating if the plain or instrument function processed spectrum is to be shown is changed
    void showPlainTotalChanged();
    void showInstrTotalChanged();

public slots:

    // Slot called to update spectra
    void setUpdateSpectra(bool updateScale, bool updateTotal);

private slots:

    void updateShowTotal(bool newShowTotal);
    void updateShowPlainTotal(bool newShowPlainTotal);
    void updateShowInstrTotal(bool newShowInstrTotal);

private:

    // Method to create connections
    void createActions();

    // Core module with the calculation results
    BytranCore *core;

    // Variable indicating the current spectrum index
    int m_currSpecIndex;

    // Horizontal and vertical axes titles
    QString m_xAxisTitle;
    QString m_yAxisTitle;

    // Spectrum and the wavenumber grid
    Spectrum m_spectrum;
    QVector<double> m_wnGrid;

    // Minimum and maximum values along the vertical and horizontal axes
    double m_minX;
    double m_maxX;
    double m_minY;
    double m_maxY;

    // Color of the line to be used for plotting the spectrum
    QString m_lineColor;

    // Variable indicates if the display mode is for the molecular spectra or the composite
    bool m_showTotal;

    // Number of height points
    int m_heightPoints;

    // Variable representing the currently active view mode
    int totalView;  // 0 - Both total and smoothed, 1 - Smoothed only red, 2 - Smoothed only black, 3 - Total only,

    // Variables indicating if the plain or instrument function processed spectrum is to be shown
    bool m_showPlainTotal;
    bool m_showInstrTotal;

    // Object to calculate the radiance
    Radiance *radiance;

};

#endif // SPECTRARESULTSQML_H
