//
// Copyright (C) 2001-2009 Agile Molecule
//

#include "Args.h"
#include "Path.h"
#include "Create.h"
#include "Application.h"
#include "Configuration.h"
#include "Dynamic_configuration.h"
#include "Program_title.h"

#include "Main_window.h"
#include "Module.h"

#ifdef MM_WIN32
#include <direct.h>
#else
#include <unistd.h>
#endif

#ifdef MM_WIN32
#pragma warning (disable : 4996)
#endif

#include "Log.h"

#include <string>
#include <iostream>


#include <QApplication>
#include <QSettings>
#include <QCleanlooksStyle>
//#include <QMainWindow>
//#include "Graphic_configuration.h"
#include <QGLFormat>

#include <rm/rm.h>

//#include <cutil.h>

using namespace MM;

int main (int argc, char* argv[])
{
    using namespace std;

    ::argc = argc;
    ::argv = argv;

    getcwd (Path::start_dir(), 1000);
    cout   << "Start at " << Path::start_dir () << "\n\n";
    log () << "Start at " << Text(Path::start_dir ()) << "\n\n";

    QApplication    application (argc, argv);

    QStyle *style = new QCleanlooksStyle;

    QString name (program_title ());

    double k = 1.1;
    //    double k = 1.05;

#ifdef ASCALAPH
    {
        //k = 1.05;

        QApplication::setPalette (QPalette 
            (QColor(int(k*210), int(k*210), int(k*200))));
    }
#else
	{
        //k = .98;
        //k = 1.;
        //k = 1.05;
        QApplication::setPalette (QPalette 
            (QColor(int(k*210), int(k*210), int(k*200))));

			//(QColor(int(k*227), int(k*219), int(k*200))));
            //(QColor(int(k*227), int(k*222), int(k*200))));
            //(QColor(int(k*222), int(k*222), int(k*200))));
            //(QColor(int(k*222), int(k*225), int(k*200))));
    }
#endif

    QApplication:: setStyle (style);


    
    if (! QGLFormat::hasOpenGL()) 
        qWarning ("OpenGL was not detected!\n\n"
        "This program requires hardware or software OpenGL drivers! "
        "Please, consult with website of manufacturer of your videocard "
        "or your notebook/desktop and install the latest videodrivers.");

    rmInit();

    //FreeConsole();
    //AllocConsole();
    //SetConsoleActiveScreenBuffer (0);


    QSettings settings("Ascalaph", argv[0]);

    if (argc == 2)
    {
        if (QString (argv[1]) == "install")
        {
            settings.setValue("bin", Path::start_dir());

            string   message;
            message += "Installed in ";
            message += Path::start_dir ();
            message += "\n";
            cout  << message;
            log() << message.c_str();
            return 0;
        }
        else if (QString (argv[1]) == "uninstall")
        {
            settings.clear ();

            string   message;
            message += "Uninstalled ";
            message += Path::start_dir ();
            message += "\n";
            cout  << message;
            log() << message.c_str();
            return 0;
        }
    }

    QString bin = settings.value ("bin").toString ();
    
    if (!bin.isEmpty ())
    {
        if (!bin.endsWith("bin"))
        {
            Text   message;
            message += "Program should be installed in dir /bin\nbut it was installed in ";
            message += bin;
            cout  << message.c_str();
            log() << message;
            return 1;
        }

        QString prefix = bin.left (bin.length() - 3);
        Path::home() = prefix;
    }

    Dynamic_configuration config (argc, argv);

    Main_window *main_window = Main_window::singleton ();
    Module::init_all();
    main_window->show();

#ifdef MM_WIN32
    qApp->setStyleSheet
        ("QFrame, QAbstractButton, QComboBox, QLineEdit, QSpinBox, QMenuBar,"
         "QDoubleSpinBox { font: bold }");
#endif

    int result = application.exec ();

    Prototype_repository::destroy();
    return result;
}

//*/
/*
#include "Create.h"
#include "Path.h"
#include "Model.h"
#include "Force_field.h"
#include "CC_energy.h"
#include <fstream>
#include "Configuration.h"
#include "Dynamic_configuration.h"

using namespace std;
using namespace MM;

int main (int argc, char* argv[])
{
    Dynamic_configuration config (argc, argv);

    ofstream out ((Path::report () + "result.txt").c_str());

    Text bonds             = Path::force_field() + "a94str.txt";
    Text VdW               = Path::force_field() + "a94nbd.txt";
    Text angles            = Path::force_field() + "a94ben.txt";
    Text torsions          = Path::force_field() + "a94tor.txt";
    Text improper_torsions = Path::force_field() + "a94imp.txt";

    Force_field     *amber94 = new Force_field  
        (bonds.c_str(), VdW.c_str(), angles.c_str(), 
         torsions.c_str(), improper_torsions.c_str(), 
         1/1.2, .5, 1.);

    Model *model =  prototype <Model> (). clone ();
    model->load (Path::tests() + "B_DNA_6.hin");
    Model_energy energy (*model, *model, *amber94);
    out << "B_DNA_6.hin                             Energy = " 
         << energy.energy () << endl;
    model->save_as ("B_DNA_6.mol");


    model->load ("model-I-A-3A_600K-500ps-2-free-turn.hin");
    Model_energy energy2 (*model, *model, *amber94);
    out << "model-I-A-3A_600K-500ps-2-free-turn.hin Energy = " 
         << energy2.energy () << endl;
    

    return 0;
}

// result.txt
//
//B_DNA_6.hin                             Energy = 5177.48
//model-I-A-3A_600K-500ps-2-free-turn.hin Energy = 1.35802

//*/

/*
#include "mm.md.h"

using namespace MM;

int main (int argc, char* argv[])
{
    Dynamic_configuration config (argc, argv);

    //======================================================

    MD_simulator md;
    md.model().load (Path::tests() + "Harmonic_H2.xyz");

    Harmonic_potential *interaction 
        = new Harmonic_potential (md.model().atom(0), md.model().atom(1));
    interaction->set_equilibrium_distance (6.);
    interaction->set_force_constant       (.25);
    md.adopt_interaction (interaction);

    int steps = 20;
    md.set_steps (steps);
    md.set_step_length ((1./steps) * 2. * __Pi__);
    md.after_each_step ("Collect_phase_trajectory"); 
    md.run ();

    //======================================================

    return 0;
}

//*/
