// 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 contains parameters responsible for the vertical axis display and scaling
#include "yaxis.h"
#include "math.h"
#include <QDebug>

YAxis::YAxis()
{
    // Setting the default values
    this->minAtten = 0;
    this->maxAtten = 100;
    this->displayedValue = 0;
    this->yPlotUnits = 2;
    this->enableRulers = true;
    this->showTotal = false;
    // Absorption cross-section vertical scale settings
    this->minCrossSection = 0;
    this->maxCrossSection = 1e-22;
    this->crossSectionAutoRecalc = true;
    // Radiance vertical scale settings
    this->minRadiance = 0;
    this->maxRadiance = 1e-06;
    this->radianceAutoRecalc = true;

    // Saving the vertical axis units
    this->yAxisTitles.resize(5);
    this->yAxisTitles[0] = "Cross-section,  cm^2 / molecule";
    this->yAxisTitles[1] = "Optical depth";
    this->yAxisTitles[2] = "Absorption (%)";
    this->yAxisTitles[3] = "Transmission (%)";
    this->yAxisTitles[4] = "Radiance,  W / ( sr * cm^2 * cm-1 )";  // Radiance
}

// Methods to get and set the minimum vertical axis value
double YAxis::getMinYPlot()
{
    if (this->displayedValue == 0)
    {
        if (yPlotUnits == 0) { return this->minCrossSection; }
        else { return this->minAtten; }
    }
    else if (this->displayedValue == 1) { return this->minRadiance; }
    else { return this->minAtten; }
}
void YAxis::setMinYPlot(double newMinYPlot)
{
    if (this->displayedValue == 0)
    {
        if (yPlotUnits == 0) { this->minCrossSection = newMinYPlot; }
        else { this->minAtten = newMinYPlot; }
    }
    else if (this->displayedValue == 1) { this->minRadiance = newMinYPlot; }
}

// Methods to get and set the maximum vertical axis value
double YAxis::getMaxYPlot()
{
    if (this->displayedValue == 0)
    {
        if (yPlotUnits == 0) { return this->maxCrossSection; }
        else { return this->maxAtten; }
    }
    else if (this->displayedValue == 1) { return this->maxRadiance; }
    else { return this->maxAtten; }
}
void YAxis::setMaxYPlot(double newMaxYPlot)
{
    if (this->displayedValue == 0)
    {
        if (yPlotUnits == 0) { this->maxCrossSection = newMaxYPlot; }
        else { this->maxAtten = newMaxYPlot; }
    }
    else if (this->displayedValue == 1) { this->maxRadiance = newMaxYPlot; }
}

// Method to set the current displayed value (Attenuation, Cross-section or Radiance)
quint8 YAxis::getDisplayedValue() { return this->displayedValue; }
void YAxis::setDisplayedValue(quint8 newDisplayedValue) { this->displayedValue = newDisplayedValue; }

// Methods to get and set the vertical axis plot units
quint8 YAxis::getYPlotUnits() { return this->yPlotUnits; }
void YAxis::setYPlotUnits(quint8 newYPlotUnits) { this->yPlotUnits = newYPlotUnits; }

// Methods to get the minimum and maximum Attenuation values
double YAxis::getMinAtten() { return this->minAtten; }
void YAxis::setMinAtten(double newMinAtten) { this->minAtten = newMinAtten; }
double YAxis::getMaxAtten() { return this->maxAtten; }
void YAxis::setMaxAtten(double newMaxAtten) { this->maxAtten = newMaxAtten; }

// Getting and setting the minimum and maximum cross-sectional values
double YAxis::getMinCrossSection() { return this->minCrossSection; }
void YAxis::setMinCrossSection(double newMinCrossSection) { this->minCrossSection = newMinCrossSection; }
double YAxis::getMaxCrossSection() { return this->maxCrossSection; }
void YAxis::setMaxCrossSection(double newMaxCrossSection) { this->maxCrossSection = newMaxCrossSection; }

// Methods to set a variable responsible for auto recalculation of the absorption cross-section scale
bool YAxis::getCrossSectionAutoRecalc() { return this->crossSectionAutoRecalc; }
void YAxis::setCrossSectionAutoRecalc(bool newCrossSectionAutoRecalc) { this->crossSectionAutoRecalc = newCrossSectionAutoRecalc; }

// Methods to get and set the minimum and maximum radiance values
double YAxis::getMinRadiance() { return this->minRadiance; }
void YAxis::setMinRadiance(double newMinRadiance) { this->minRadiance = newMinRadiance; }
double YAxis::getMaxRadiance() { return this->maxRadiance; }
void YAxis::setMaxRadiance(double newMaxRadiance) { this->maxRadiance = newMaxRadiance; }

// Methods to set a variable responsible for auto recalculation of the radiance scale
bool YAxis::getRadianceAutoRecalc() { return this->radianceAutoRecalc; }
void YAxis::setRadianceAutoRecalc(bool newRadianceAutoRecalc) { this->radianceAutoRecalc = newRadianceAutoRecalc; }

// Method to enable / disable rulers on zoom / zoom out
bool YAxis::getEnableRulers() { return this->enableRulers; }
void YAxis::setEnableRulers(bool newEnableRulers) { this->enableRulers = newEnableRulers; }

// Methods to get and set the showTotal variable
bool YAxis::getShowTotal() { return this->showTotal; }
void YAxis::setShowTotal(bool newShowTotal) { this->showTotal = newShowTotal; }

// Method to get the vertical axis title (current units)
QString YAxis::getYAxisTitle()
{
    if (this->displayedValue == 0)
    {
        if (yPlotUnits == 0) { return this->yAxisTitles[0]; }
        else { return this->yAxisTitles[this->yPlotUnits]; }
    }
    else if (this->displayedValue == 1) { return this->yAxisTitles[4]; }
    else { return this->yAxisTitles[this->yPlotUnits]; }
}

// Method to convert the vertical axis units from the default to current
double YAxis::toCurrentFromDefault(double defaultUnitsValue)
{
    if (displayedValue == 0)
    {
             if (this->yPlotUnits == 0) { return defaultUnitsValue; }  // Cross-section
        else if (this->yPlotUnits == 1) { return defaultUnitsValue; }  // Optical depth
        else if (this->yPlotUnits == 2) { return 100 * (1 - exp(-defaultUnitsValue)); }  // Absorption
        else if (this->yPlotUnits == 3) { return 100 * exp(-defaultUnitsValue); }  // Transmission
    }
    else
    {
        return defaultUnitsValue;
    }

    // If none of the above work, return the default
    return defaultUnitsValue;
}
