//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      App/AppOptions.cpp
//! @brief     Implements class ProgramOptions.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "App/AppOptions.h"
#include "GUI/Model/Util/Path.h"
#include <QApplication>
#include <QStringList>
#include <fstream>
#include <iostream>

namespace {

//! Converts string "1600x1000" to QSize(1600, 1000)
QSize windowSize(const QString& size_string)
{
    QStringList list = size_string.split("x");

    if (list.size() != 2)
        return QSize();

    return QSize(list[0].toInt(), list[1].toInt());
}

//! Returns true if windows size makes sence.
bool isValid(const QSize& win_size)
{
    return win_size.width() > 640 && win_size.height() > 480;
}

void exitWithGuiMessage(const QString msg)
{
    // As there were command-line arguments, we assume that the app was called from
    // a terminal. So we can print to console; no need to open a GUI message box.
    std::cerr << msg.toStdString() << std::endl;
    exit(-1);
}

} // namespace


ApplicationOptions::ApplicationOptions(int argc, char** argv)
{
    QCoreApplication app(argc, argv);

    auto m_helpOption =
        new QCommandLineOption({"h", "help"}, "Displays help on commandline options.");
    auto m_geometryOption =
        new QCommandLineOption({"g", "geometry"}, "Main window geometry, e.g., 1600x1000.", "size");
    auto m_projectFileOption =
        new QCommandLineOption({"p", "project-file"}, "Project file.", "file");

    m_parser.setApplicationDescription("BornAgain Graphical User Interface");
    m_parser.addOption(*m_helpOption);
    m_parser.addVersionOption();
    m_parser.addOption(*m_geometryOption);
    m_parser.addOption(*m_projectFileOption);

    // Parse the command-line arguments
    if (!m_parser.parse(QCoreApplication::arguments()))
        exitWithGuiMessage(m_parser.errorText());

    // Store parsed values
    if (m_parser.isSet(*m_geometryOption))
        m_geometryValue = m_parser.value(*m_geometryOption);

    if (m_parser.isSet(*m_projectFileOption))
        m_projectFileValue = m_parser.value(*m_projectFileOption);

    if (m_parser.isSet("help")) {
        std::cout << m_parser.helpText().toStdString();
        exit(0);
    }

    if (m_parser.isSet("version")) {
        std::cout << "BornAgain-" << GUI::Path::getBornAgainVersionString().toStdString()
                  << std::endl;
        exit(0);
    }

    if (m_parser.isSet(*m_geometryOption)) {
        QSize size = windowSize(m_geometryValue);
        if (!isValid(size))
            exitWithGuiMessage("Wrong window size, try --geometry=1600x900\n");
    }
}

bool ApplicationOptions::find(const QString& name) const
{
    return m_parser.isSet(name);
}

QSize ApplicationOptions::mainWindowSize() const
{
    return windowSize(m_geometryValue);
}

QString ApplicationOptions::projectFile() const
{
    return m_projectFileValue;
}
