//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Tests/Unit/GUI/Utils.cpp
//! @brief     Implements auxiliary test functions in a namespace.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2015
//! @authors   Scientific Computing Group at MLZ Garching
//
//  ************************************************************************************************

#include "Tests/Unit/GUI/Utils.h"
#include "Base/Axis/MakeScale.h"
#include "Device/Data/Datafield.h"
#include "Device/Histo/DiffUtil.h"
#include "Device/IO/IOFactory.h"
#include "GUI/Model/Data/DataItem.h"
#include "GUI/Model/Device/RealItem.h"
#include "GUI/Model/Model/RealModel.h"
#include "GUI/Model/Project/ProjectUtil.h"

namespace {

const int nxsize = 5;
const int nysize = 10;

} // namespace

void UTest::GUI::create_dir(const QString& dir_name)
{
    if (QFile::exists(dir_name))
        QDir(dir_name).removeRecursively();

    if (!QDir(".").mkdir(dir_name))
        throw std::runtime_error("UTest::GUI::create_dir -> Error. Cannot create '"
                                 + dir_name.toLatin1() + "' in parent directory '.'.");
}

std::unique_ptr<Datafield> UTest::GUI::createData(double value, DIM n_dim)
{
    std::vector<const Scale*> axes;
    axes.emplace_back(newEquiDivision("x", nxsize, -1.0, 1.0));
    if (n_dim == DIM::D2)
        axes.emplace_back(newEquiDivision("y", nysize, 0.0, 2.0));

    std::unique_ptr<Datafield> result(new Datafield(std::move(axes)));
    result->setAllTo(value);
    return result;
}

RealItem* UTest::GUI::createRealData(const QString& name, RealModel& model, double value, DIM n_dim)
{
    RealItem* result = model.pushNewItem();
    result->setDatafield(createData(value, n_dim).release());
    result->setRealItemName(name);
    return result;
}

bool UTest::GUI::isTheSame(const Datafield& data1, const Datafield& data2)
{
    double diff = DiffUtil::meanRelVecDiff(data1.flatVector(), data2.flatVector());
    return diff < 1e-10;
}

bool UTest::GUI::isTheSame(const QString& fileName, const Datafield& data)
{
    std::unique_ptr<Datafield> dataOnDisk(IO::readData2D(fileName.toStdString()));
    return isTheSame(*dataOnDisk, data);
}
