// 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 stores curently active total pressure units and performs conversion from / to the default pressure units to the current pressure units
#include "concpressunitsconvert.h"
#include <QDebug>

ConcPressUnitsConvert::ConcPressUnitsConvert()
{

}

// Method to get and set the current pressure units
quint8 ConcPressUnitsConvert::getPressUnits() { return this->pressUnits; }
void ConcPressUnitsConvert::setPressUnits(quint8 newPressUnits) { this->pressUnits = newPressUnits; }

// Method to get the abbreviated string representation of the current units
QString ConcPressUnitsConvert::getCurrPressUnitsAbbrevStr()
{
    // 0 - Atmospheres, atm;  1 - Millibar, mbar;  2 - Torr, Torr;  3 - Pascal, Pa;  4 - Pounds per square inch, psi;

    switch (pressUnits)
    {
        case 0:  // from atm to atm, atm
            return "atm";
            break;
        case 1:  // from atm to Milibar, mb
            return "mbar";
            break;
        case 2:  // from atm to Torr, Torr
            return "Torr";
            break;
        case 3:  // from atm to Pascal
            return "Pa";
            break;
        case 4:  // from atm to Pounds per square inch, psi
            return "psi";
            break;
        default: // returning atm
            return "atm";
            break;
    }
}

// Method to get the abbreviated string representation of the current combined units
QString ConcPressUnitsConvert::getCurrCombinedUnitsAbbrevStr()
{
    switch(concUnits)
    {
        case 0:
            return "%";
            break;
        case 1:
            return "ppmv";
            break;
        case 2:
            return getCurrPressUnitsAbbrevStr();
            break;
        default:
            return "%";
            break;
    }
}

// Getting and setting the concentration units
quint8 ConcPressUnitsConvert::getConcUnits() { return this->concUnits; }
void ConcPressUnitsConvert::setConcUnits(quint8 newConcUnits) { this->concUnits = newConcUnits; }

// Method to convert from default Pressure units to current Pressure units
double ConcPressUnitsConvert::fromDefaultToCurrentPressUnits(double defaultValue)
{
    // 0 - Atmospheres, atm;  1 - Millibar, mbar;  2 - Torr, Torr;  3 - Pascal, Pa;  4 - Pounds per square inch, psi;

    switch (pressUnits)
    {
        case 0:  // from atm to atm, atm
            return defaultValue;
            break;
        case 1:  // from atm to Milibar, mb
            return 1013.2533539 * defaultValue;
            break;
        case 2:  // from atm Torr, Torr
            return 760.000810626234 * defaultValue;
            break;
        case 3:  // from atm to Pascal
            return 101325.33539 * defaultValue;
            break;
        case 4:  // from atm to Pounds per square inch, psi
            return 14.6952133916117 * defaultValue;
            break;
        case 5:  // from atm to mm Hg
            return 760.0024073571305 * defaultValue;
            break;
        case 6:  // from atm to inch Hg
            return 29.92135462035947 * defaultValue;
            break;
        default: // returning atm
            return defaultValue;
            break;
    }
}

// Method to convert from the current Pressure units to the default Pressure units
double ConcPressUnitsConvert::fromCurrentToDefaultPressUnits(double currentValue)
{
    // 0 - Atmospheres, atm;  1 - Millibar, mbar;  2 - Torr, Torr;  3 - Pascal, Pa;  4 - Pounds per square inch, psi;
    double atmValue;
    atmValue = fromSpecifiedToDefaultPressUnits(pressUnits, currentValue);

    return atmValue;
}

// Method to convert from specified Pressure units to the default Pressure units
double ConcPressUnitsConvert::fromSpecifiedToDefaultPressUnits(quint8 fromUnits, double fromValue)
{
    // 0 - Atmospheres, atm;  1 - Millibar, mbar;  2 - Torr, Torr;  3 - Pascal, Pa;  4 - Pounds per square inch, psi;

    switch (fromUnits)
    {
        case 0:  // from atm to atm
            return fromValue;
            break;
        case 1:  // from Milibar (mbar) to atm
            return 0.00098692 * fromValue;
            break;
        case 2:  // from Torr (Torr) to atm
            return 0.001315788094764 * fromValue;
            break;
        case 3:  // from Pascal (Pa) to atm
            return 0.0000098692 * fromValue;
            break;
        case 4:  // from Pounds per square inch (psi) to atm
            return 0.06804936863692 * fromValue;
            break;
        case 5:  // from mmHg to atm
            return 0.001315785305835 * fromValue;
            break;
        case 6:  // from inchHg to atm
            return 0.033420946768217 * fromValue;
            break;
        default:
            return fromValue;
            break;
    }
}

// Method to convert from default Pressure units to the specified Pressure units
double ConcPressUnitsConvert::fromDefaultToSpecifiedPressUnits(double defaultValue, quint8 toPressUnits)
{
    // 0 - Atmospheres, atm;  1 - Millibar, mbar;  2 - Torr, Torr;  3 - Pascal, Pa;  4 - Pounds per square inch, psi;

    switch (toPressUnits)
    {
        case 0:  // from atm to atm, atm
            return defaultValue;
            break;
        case 1:  // from atm to Milibar, mb
            return 1013.2533539 * defaultValue;
            break;
        case 2:  // from atm Torr, Torr
            return 760.000810626234 * defaultValue;
            break;
        case 3:  // from atm to Pascal
            return 101325.33539 * defaultValue;
            break;
        case 4:  // from atm to Pounds per square inch, psi
            return 14.6952133916117 * defaultValue;
            break;
        case 5:  // from atm to mm Hg
            return 760.0024073571305 * defaultValue;
            break;
        case 6:  // from atm to inch Hg
            return 29.92135462035947 * defaultValue;
            break;
        default: // returning atm
            return defaultValue;
            break;
    }
}

// Method to convert from default Concentration units to current Concentration units
double ConcPressUnitsConvert::fromDefaultToCurrentConcUnits(double defaultUnitsConcValue, double totalPressAtm)
{
    double atmPress;  // Pressure value in mbar units


    // Convertion techniques are according to
    // http://www.cee.mtu.edu/~reh/courses/ce251/251_notes_dir/node2.html

    switch (concUnits)
    {
        case 0:  // Concentration in %
            return (defaultUnitsConcValue * 0.0001);
            break;
        case 1:  // Parts per million by volume (ppmv)
            return defaultUnitsConcValue;
            break;
        case 2:  // Regular pressure units
            atmPress = totalPressAtm * defaultUnitsConcValue * 1E-6;
            return fromDefaultToCurrentPressUnits(atmPress);
            break;
        default: // The default is the concentration in percent
            return defaultUnitsConcValue * 0.0001;
            break;
    }
}

// Method to convert from the current Concentration units to the default Concentration units
double ConcPressUnitsConvert::fromCurrentToDefaultConcUnits(double currentUnitsConcValue, double totalPressAtm)
{
    double atmPress;  // Pressure in mbar default units

    // Convertion techniques are according to
    // http://www.cee.mtu.edu/~reh/courses/ce251/251_notes_dir/node2.html

    switch (concUnits)
    {
        case 0:  // Concentration in %
            return currentUnitsConcValue * 10000;
            break;
        case 1:  // Parts per million by volume (ppmv)
            return currentUnitsConcValue;
            break;
        case 2:  // Regular pressure units
            atmPress = fromCurrentToDefaultPressUnits(currentUnitsConcValue);
            return (atmPress / totalPressAtm) * 1E+6;
            break;
        default: // The default is the concentration in percent
            return currentUnitsConcValue * 10000;;
            break;
    }
}

// Method to get the combined units number
quint8 ConcPressUnitsConvert::getCombinedUnits()
{
    switch(concUnits)
    {
        case 0:
            return 0;
            break;
        case 1:
            return 1;
            break;
        case 2:
            return 2 + this->pressUnits;
            break;
        default:
            return 0;
            break;
    }
}
// Method to set the concentration and the pressure units based on the combined units
void ConcPressUnitsConvert::setCombinedUnits(quint8 newCombinedUnits)
{
    if (newCombinedUnits < 2)
    {
        this->concUnits = newCombinedUnits;
    }
    else
    {
        this->concUnits = 2;
        this->pressUnits = newCombinedUnits - 2;
    }
}
