// 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.



// Auxiliary functions used in the program
#include "auxiliary.h"
#include "limits.h"
#include "float.h"
#include <QMessageBox>
#include <QDebug>

Auxiliary::Auxiliary()
{

}

// Copying the spectrum data from one variable to another
void Auxiliary::copySpectrum(Spectrum *from, Spectrum *to)
{
    to->setStartWn(from->getStartWn());
    to->setMiddleWn(from->getMiddleWn());
    to->setEndWn(from->getEndWn());
    to->setStartMicron(from->getStartMicron());
    to->setMiddleMicron(from->getMiddleMicron());
    to->setEndMicron(from->getEndMicron());
    to->setClosestMidIndex(from->getClosestMidIndex());  // Value of the data main grid index closest to the center wavenumber of the spectral line
    to->setMidIndex(from->getMidIndex());      // The number of the middle point (in the center of the points distribution)
    to->setStartIndex(from->getStartIndex());  // Index in the wavenumber array grid corresponding to the minilmum wavenumber value

    // Coppying spectral arrays (the resizing of the arrays is carried out within the Spectrum object)
    to->setY(from->getY());
    to->setX(from->getX());
}

// Method to carry out selection sort algorithm on an array (performed on int values)
void Auxiliary::selectionSort(QVector<int> *array)
{
    int i;  // Loop variable
    int j;  // Loop variable
    int minValue = 1000;  // Minimum value found among a selected range of array elements, not sure why I picked a 1000 here, maybe should use INT_MIN instead
    int minIndex;

    // Reordering the numbers in the array
    for (j = 0; j < array->count(); j++)
    {
        for (i = j; i < array->count(); i++)
        {
            if ((*array)[i] < minValue) { minValue = (*array)[i];
                                          minIndex = i; }
        }
        minValue = (*array)[minIndex];
        (*array)[minIndex] = (*array)[j];
        (*array)[j] = minValue;
        minValue = 1000;
    }
}
// Method to carry out selection sort algorithm on an array (performed on double values)
void Auxiliary::selectionSort(QVector<double> *array)
{
    int i;  // Loop variable
    int j;  // Loop variable
    double minValue = DBL_MIN;  // Minimum value found among a selected range of array elements
    int minIndex;

    // Reordering the numbers in the array
    for (j = 0; j < array->count(); j++)
    {
        for (i = j; i < array->count(); i++)
        {
            if ((*array)[i] < minValue) { minValue = (*array)[i];
                                          minIndex = i; }
        }
        minValue = (*array)[minIndex];
        (*array)[minIndex] = (*array)[j];
        (*array)[j] = minValue;
        minValue = DBL_MIN;
    }
}

// Method to find the maximum value in an array (real and imaginary implementations)
double Auxiliary::maximum(QVector<double> *array)
{
    int i;  // Loop variable
    double max;  // Maximum value

    max = DBL_MIN;
    for (i = 0; i < array->count(); i++)
    {
        if (array->at(i) > max) { max = array->at(i); }
    }
    return max;
}
//static std::complex<double> Auxiliary::maximum(QVector<std::complex<double> > *array)
//{
//}

// Method to find the minimum value in an array (real and imaginary implementation)
double Auxiliary::minimum(QVector<double> *array)
{
    int i;  // Loop variable
    double min;  // Minimum value

    min = DBL_MAX;
    for (i = 0; i < array->count(); i++)
    {
        if (array->at(i) < min) { min = array->at(i); }
    }
    return min;
}
//static std::complex<double> Auxiliary::minimum(QVector<std::complex<double> > *array)
//{
//}

// Method to check the numerical input to avoid value acceptance when not needed
bool Auxiliary::acceptInput(QString value)
{
    bool result;

    result = (value != "") && (value.right(1) != ".") && (value.right(1) != ",") && (value.right(1) != "e") && (value.right(1) != "E") && (value.right(1) != "-") && (value.right(1) != "+");
    return result;
}

