//
// File: test_massrange.cpp
// Created by: Olivier Langella
// Created on: 4/3/2015
//
/*******************************************************************************
 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
 *
 * This file is part of the PAPPSOms++ library.
 *
 *     PAPPSOms++ is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     PAPPSOms++ is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with PAPPSOms++.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *     Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
 *implementation
 ******************************************************************************/

// make test ARGS="-V -I 4,4"

#include <pappsomspp/mzrange.h>
#include <pappsomspp/utils.h>

#include <iostream>
#include <QDebug>
#include <QString>
#include <cmath>

using namespace pappso;
using namespace std;


int
main()
{
  PrecisionPtr precision  = PrecisionFactory::getPpmInstance(10);
  PrecisionPtr precisionb = PrecisionFactory::getDaltonInstance(6.0);
  if(precision == precisionb)
    {
      cerr << "precision == precisionb ERROR "
           << precision->toString().toStdString() << " "
           << precisionb->toString().toStdString() << std::endl;
      return 1;
    }
  precisionb = PrecisionFactory::getPpmInstance(10);
  if(precision != precisionb)
    {
      cerr << "precision != precisionb ERROR "
           << precision->toString().toStdString() << " "
           << precisionb->toString().toStdString() << std::endl;
      return 1;
    }

  cout << std::endl << "..:: Mass Ranges ::.." << std::endl;
  MzRange mz_range1(pappso_double(1200.001),
                    PrecisionFactory::getDaltonInstance(6.0));
  MzRange mz_range2(pappso_double(1200.001),
                    PrecisionFactory::getPpmInstance(10));
  MzRange mz_range3(pappso_double(1200.001),
                    PrecisionFactory::getPpmInstance(10),
                    PrecisionFactory::getPpmInstance(30));
  cout << "mz_range1: " << mz_range1.toString().toStdString() << std::endl;
  cout << "mz_range2: " << mz_range2.toString().toStdString() << std::endl;
  cout << "mz_range3: " << mz_range3.toString().toStdString() << std::endl;

  cout << std::endl << "..:: Contains ::.." << std::endl;
  cout << mz_range1.toString().toStdString() << std::endl;
  if(mz_range1.contains(pappso_double(600)))
    {
      cerr << "mz_range1.contains(pappso_double(600)) ERROR" << std::endl;
      return 1;
    }

  cout << mz_range1.toString().toStdString() << std::endl;
  if(!mz_range1.contains(pappso_double(1200)))
    {
      cerr << "!mz_range1.contains(pappso_double(1200)) ERROR" << std::endl;
      return 1;
    }

  cout << mz_range2.toString().toStdString() << std::endl;
  if(mz_range2.contains(pappso_double(600)))
    {
      cerr << "mz_range2.contains(pappso_double(600)) ERROR" << std::endl;
      return 1;
    }

  cout << mz_range2.toString().toStdString() << std::endl;
  if(!mz_range2.contains(pappso_double(1200)))
    {
      cerr << "!mz_range2.contains(pappso_double(1200)) ERROR" << std::endl;
      return 1;
    }

  cout << mz_range2.toString().toStdString() << std::endl;
  if(!mz_range2.contains(pappso_double(1200.00001)))
    {
      cerr << "!mz_range2.contains(pappso_double(1200.00001)) ERROR" << std::endl;
      return 1;
    }
  cout << mz_range2.toString().toStdString() << std::endl;
  if(mz_range2.contains(pappso_double(1200.1)))
    {
      cerr << "mz_range2.contains(pappso_double(1200.1)) ERROR" << std::endl;
      return 1;
    }


  // test :
  MzRange mz_range_test_ref(pappso_double(633.29706487392),
                            PrecisionFactory::getPpmInstance(10));
  cerr.precision(17);
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_test_ref.getMz()) != Utils::roundToDecimal32bitsAsLongLongInt(633.29706487392))
    {
      cerr << "mz_range_test_ref.getMz() != 633.29706487392 ERROR "
           << Utils::roundToDecimal32bitsAsLongLongInt(mz_range_test_ref.getMz())
           << " != " << Utils::roundToDecimal32bitsAsLongLongInt(633.29706487392) << std::endl;
      return 1;
    }
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_test_ref.lower()) != Utils::roundToDecimal32bitsAsLongLongInt(633.290731903271))
    {
      cerr << "mz_range_test_ref.lower() != 633.290731903271 ERROR "
           << mz_range_test_ref.lower() << std::endl;
      return 1;
    }
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_test_ref.upper()) != Utils::roundToDecimal32bitsAsLongLongInt(633.303397844569))
    {
      cerr << "mz_range_test_ref.upper() != 633.303397844569 ERROR"
           << mz_range_test_ref.upper() << std::endl;
      return 1;
    }

  // test :
  MzRange mz_range_test(pappso_double(633.29706487392),
                        PrecisionFactory::getPpmInstance(10),
                        PrecisionFactory::getPpmInstance(10));
  cerr.precision(17);
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_test.getMz()) != Utils::roundToDecimal32bitsAsLongLongInt(633.29706487392))
    {
      cerr << "mz_range_test.getMz() != 633.29706487392 ERROR "
           << mz_range_test.getMz() << std::endl;
      return 1;
    }
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_test.lower()) != Utils::roundToDecimal32bitsAsLongLongInt(633.290731903271))
    {
      cerr << "mz_range_test.lower() != 633.290731903271 ERROR "
           << mz_range_test.lower() << std::endl;
      return 1;
    }
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_test.upper()) != Utils::roundToDecimal32bitsAsLongLongInt(633.303397844569))
    {
      cerr << "mz_range_test.upper() != 633.303397844569 ERROR"
           << mz_range_test.upper() << std::endl;
      return 1;
    }

  MzRange mz_range_lower_upper_test(pappso_double(633.29706487392),
                                    PrecisionFactory::getPpmInstance(10),
                                    PrecisionFactory::getDaltonInstance(1));
  cerr.precision(17);

  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_lower_upper_test.getMz()) !=
     Utils::roundToDecimal32bitsAsLongLongInt(633.79389838859572))
    {
      cerr << "mz_range_lower_upper_test.getMz() != 633.79389838859572 ERROR "
           << mz_range_lower_upper_test.getMz() << std::endl;
      return 1;
    }
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_lower_upper_test.lower()) !=
     Utils::roundToDecimal32bitsAsLongLongInt(633.290731903271))
    {
      cerr << "mz_range_lower_upper_test.lower() != 633.290731903271 ERROR "
           << mz_range_lower_upper_test.lower() << std::endl;
      return 1;
    }
  if(Utils::roundToDecimal32bitsAsLongLongInt(mz_range_lower_upper_test.upper()) !=
     Utils::roundToDecimal32bitsAsLongLongInt(634.29706487392))
    {
      cerr << "mz_range_lower_upper_test.upper() != 633.303397844569 ERROR"
           << mz_range_lower_upper_test.upper() << std::endl;
      return 1;
    }
  // SUCCESS
  return 0;
}
