#include "Panel_solvation.h"

#ifndef ASCALAPH
#include "Solvation_interactions.h"
#else
#include "List_interactions.h"
#endif

#include "Model.h"
#include "Model_kit.h"
#include "Path.h"

#include <fstream>
#include <math.h>

namespace MM
{

Panel_solvation::
Panel_solvation ()
:
    Panel ("H2O", "right")
{
    setupUi (this);

    checkBox_Smooth->hide();
    doubleSpinBox_Smooth->hide();
    checkBox_R_H->hide();
    checkBox_R_H_Sheffield->hide();
	//checkBox_FF_radii->hide();
    //doubleSpinBox_Phi->hide();
    //label_Phi->hide();
    //doubleSpinBox_Shift->hide();
    //label_Shift->hide();

    checkBox_Implicit_water ->setCheckState (List_interactions::implicit_water() ? Qt::Checked : Qt::Unchecked);

#ifndef ASCALAPH
    doubleSpinBox_sigma     ->setValue (Solvation_interactions::Sigma);
    doubleSpinBox_F         ->setValue (Solvation_interactions::F);
    doubleSpinBox_Phi       ->setValue (Solvation_interactions::Phi);
    doubleSpinBox_a         ->setValue (Solvation_interactions::a);
    doubleSpinBox_b         ->setValue (Solvation_interactions::b);
    doubleSpinBox_Shift     ->setValue (pow (Solvation_interactions::Shift, .5));
    doubleSpinBox_Power     ->setValue (Solvation_interactions::Power);
    doubleSpinBox_R_probe   ->setValue (Solvation_interactions::R_probe);
    doubleSpinBox_R_H       ->setValue (Solvation_interactions::RH);

    checkBox_ignore_HNO     ->setCheckState (Solvation_interactions::ignore_HNO ? Qt::Checked   : Qt::Unchecked);
    checkBox_FF_radii       ->setCheckState (Solvation_interactions::FF_radii   ? Qt::Checked   : Qt::Unchecked);
#endif

    doubleSpinBox_a_Sheffield  ->setValue (List_interactions::Sheffield_a  ());
    doubleSpinBox_R_H_Sheffield->setValue (List_interactions::Sheffield_RH ());

    if (List_interactions::Sheffield_water())
        set_method ("Sheffield");
    else
        set_method ("Generalized Born");

    connect(checkBox_Implicit_water,SIGNAL (stateChanged (int)),
            this,                   SLOT   (set_on       (int)));


    connect(comboBox,               
            SIGNAL (currentIndexChanged (const QString &)),
            this,                   SLOT   (set_method (const QString &)));


#ifndef ASCALAPH
    connect(doubleSpinBox_sigma,    SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_Sigma    (double)));

    connect(doubleSpinBox_F,        SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_F        (double)));

    connect(doubleSpinBox_Phi,      SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_Phi      (double)));

    connect(doubleSpinBox_a,        SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_a       (double)));

    connect(doubleSpinBox_b,        SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_b       (double)));

    connect(doubleSpinBox_Shift,    SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_Shift    (double)));

    connect(doubleSpinBox_Power,    SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_Power    (double)));

    connect(doubleSpinBox_R_probe,  SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_R_probe  (double)));

    connect(doubleSpinBox_R_H,      SIGNAL (valueChanged (double)),
            this,                   SLOT   (set_R_H      (double)));

    connect(checkBox_ignore_HNO,    SIGNAL (stateChanged (int)),
            this,                   SLOT   (set_ignore_HNO (int)));

    connect(checkBox_FF_radii,      SIGNAL (stateChanged (int)),
            this,                   SLOT   (set_FF_radii (int)));
#endif



    connect(doubleSpinBox_a_Sheffield,  SIGNAL (valueChanged   (double)),
            this,                       SLOT   (set_a_Sheffield(double)));

    connect(doubleSpinBox_R_H_Sheffield, SIGNAL (valueChanged      (double)),
            this,                        SLOT   (set_R_H_Sheffield (double)));



    connect(pushButton_Check,      	SIGNAL (clicked ()),
            this,                   SLOT   (check ()));

    //connect(pushButton_Check_AMBER94, SIGNAL (clicked ()),
    //        this,                   SLOT   (check_AMBER94 ()));

#ifdef ASCALAPH
    comboBox->removeItem (0);
    //set_method ("Sheffield");
#else
    //set_method ("Generalized Born");
#endif
}

Panel_solvation::
~Panel_solvation ()
{
}

void Panel_solvation::
set_method (const QString & text)
{
    if (text == "Sheffield")
    {
        comboBox->setCurrentIndex (comboBox->findText("Sheffield"));
        stackedWidget->setCurrentIndex (0);
        groupBox_Nonpolar_solvation->hide();
        List_interactions::set_Sheffield_water (true);
    }
    else if (text == "Generalized Born")
    {
        comboBox->setCurrentIndex (comboBox->findText("Generalized Born"));
        stackedWidget->setCurrentIndex (1);
        groupBox_Nonpolar_solvation->show();
        List_interactions::set_Sheffield_water (false);
    }
    else
        FLAW("unknown method");

    set_on (checkBox_Implicit_water->isChecked());
}

void Panel_solvation::set_on         (int v) 
{
    List_interactions::set_implicit_water (v);

    if (comboBox->currentText() == "Sheffield")
    {
        List_interactions::set_Sheffield_water (v);
    }
    else if (comboBox->currentText() == "Generalized Born")
        List_interactions::set_Sheffield_water (false);
    else
        FLAW("unknown method");
}


#ifndef ASCALAPH
void Panel_solvation::set_Sigma   (double v) {Solvation_interactions::Sigma   = v;}
void Panel_solvation::set_F       (double v) {Solvation_interactions::F       = v;}
void Panel_solvation::set_Phi     (double v) {Solvation_interactions::Phi     = v;}
void Panel_solvation::set_a       (double v) {Solvation_interactions::a       = v;}
void Panel_solvation::set_b       (double v) {Solvation_interactions::b       = v;}
void Panel_solvation::set_Shift   (double v) {Solvation_interactions::Shift   = pow (v, 2);}
void Panel_solvation::set_Power   (double v) {Solvation_interactions::Power   = v;}
void Panel_solvation::set_R_probe (double v) {Solvation_interactions::R_probe = v;}
void Panel_solvation::set_R_H     (double v) {Solvation_interactions::RH      = v;}
void Panel_solvation::set_ignore_HNO (int v) {Solvation_interactions::ignore_HNO = v;}
void Panel_solvation::set_FF_radii   (int v) {Solvation_interactions::FF_radii = v;}
#endif

void Panel_solvation::set_a_Sheffield   (double v) {List_interactions::set_Sheffield_a  (v);}
void Panel_solvation::set_R_H_Sheffield (double v) {List_interactions::set_Sheffield_RH (v);}

Text Panel_solvation::
path () const
{
    return Path::aminoacids();
    //return Path::aminoacids_tinker();
}

//void Panel_solvation::
//check_OPLS ()
//{
//    check ("OPLS");
//}
//
//void Panel_solvation::
//check_AMBER94 ()
//{
//    check ("AMBER94");
//}

void Panel_solvation::
check ()
{
    check (comboBox_Check->currentText().toLatin1 ());
}

void Panel_solvation::
calc (Model & model, const char * ff_name)
{
    model.kit().set_force_field (ff_name);  
    model.kit().strip (true); 
    model.kit().interaction().common().potential ();
}

void Panel_solvation::
check (const char * ff_name)
{
    using namespace std;

    Own <Model>     model (prototype <Model> (). clone ());
    
    Common_interactions & interactions = model().kit().interaction().common();

    model().load (path() + "Gly.mlm" );  calc (model(), ff_name); //  0.94 Glycine 
    double Eg = interactions.last_continuum_solvation_potential();


    //double E;
    ofstream out ((Path::report() + "check_" + ff_name + ".xls").c_str());
    out << "res   \t chx-wat \t me   \t OPLS     \t AMBER \t vap-wat  \n";

    // Radizicka, A. and Wolfenden, R. 1988. Biochemistry, v.27. pp1664-1670
    
    model(). load (path() + "Ala.mlm" ); calc (model(), ff_name); //  1.81 Alanine 
    out << "Ala   \t  "<< 1.81-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -13.0805+13.7098 <<" \t "<< -12.3860+13.2011  <<"   \t  "<< 1.94-2.39 << "\n";

    //model().load (path() + "Arg+.mlm");  calc (model(), ff_name); //-14.92 Arginine 
    //out << "Arg+  \t "<< -14.92-0.94 <<"  \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
    //<< -80.5023+13.7098 <<" \t "<< -75.5872+13.2011  <<"  \t "<< -19.92-2.39 << "\n";

    model().load (path() + "Asn.mlm" );   calc (model(), ff_name); // -6.64 Asparagine 
    out << "Asn   \t "<< -6.64-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -28.4528+13.7098 <<" \t "<< -27.3687+13.2011  <<"   \t "<< -9.68-2.39 << "\n";

    //model().load (path() + "Asp-.mlm");   calc (model(), ff_name); // -8.72 Aspartic acid 
    //out << "Asp-  \t "<< -8.72-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
    //<< -84.6869+13.7098 <<" \t "<< -79.7101+13.2011  <<"   \t "<< -10.95-2.39 << "\n";

    model().load (path() + "Cys.mlm" );  calc (model(), ff_name); //  1.28 Cysteine 
    out << "Cys    \t  "<< 1.28-0.94 <<"  \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -15.2745+13.7098 <<" \t "<< -13.4418+13.2011  <<"  \t "<< -1.24-2.39 << "\n";


    model().load (path() + "Gln.mlm" );  calc (model(), ff_name); // -5.54 Glutamine 
    out << "Gln   \t "<< -5.54-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -24.3874+13.7098 <<" \t "<< -24.9896+13.2011  <<"   \t "<< -9.38-2.39 << "\n";

    //model().load (path() + "Glu-.mlm");   calc (model(), ff_name); // -6.81 Glutamic acid 
    //out << "Glu-  \t "<< -6.81   \t "<<"  \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
    //<< -94.5898+13.7098 <<" \t "<< -88.1826+13.2011  << -10.24-2.39 << "\n";

    model().load (path() + "Gly.mlm" );  calc (model(), ff_name); //  0.94 Glycine 
    out << "Gly   \t  "<< 0.94-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -13.7098+13.7098 <<" \t "<< -13.2011+13.2011  <<"   \t  "<< 2.39-2.39 << "\n";

    //model().load (path() + "His+.mlm");  calc (model(), ff_name); // -4.66 Histidine 
    //out << "His+  \t "<< -4.66-0.94 <<"  \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
    //<< -76.6452+13.7098 <<" \t "<< -74.4488+13.2011  <<"   \t "<< -10.27-2.39 << "\n";

    model().load (path() + "Ile.mlm" );   calc (model(), ff_name); //  4.92 Isoleucine 
    out << "Ile   \t  "<< 4.92-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -12.0019+13.7098 <<" \t "<< -10.9896+13.2011  <<"   \t  "<< 2.15-2.39 << "\n";

    model().load (path() + "Leu.mlm" );  calc (model(), ff_name); //  4.92 Leucine 
    out << "Leu   \t  "<< 4.92-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -11.8656+13.7098 <<" \t "<< -10.7380+13.2011  <<"   \t  "<< 2.28-2.39 << "\n";

    //model().load (path() + "Lys+.mlm");  calc (model(), ff_name); // -5.55 Lysine 
    //out << "Lys+  \t "<< -5.55-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
    //<< -95.8007+13.7098 <<" \t "<< -84.4491+13.2011  <<"   \t "<< -9.52-2.39 << "\n";

    model().load (path() + "Met.mlm" );   calc (model(), ff_name); //  2.35 Methionine 
    out << "Met   \t  "<< 2.35-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -17.8222+13.7098 <<" \t "<< -14.1034+13.2011  <<"   \t "<< -1.48-2.39 << "\n";

    model().load (path() + "Phe.mlm" );   calc (model(), ff_name); //  2.98 Phenylalanine 
    out << "Phe   \t  "<< 2.98-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -11.8131+13.7098 <<" \t "<< -11.4356+13.2011  <<"   \t "<< -0.76-2.39 << "\n";

    //model().load (path() + "Pro.mlm" );   calc (model(), ff_name); //       Proline 
    //out << "Pro   \t         \t" << interactions.last_continuum_solvation_potential()-Eg << "\t -12.7124 \t -11.7816   "  << "\n";

    model().load (path() + "Ser.mlm" );   calc (model(), ff_name); // -3.40 Serine 
    out << "Ser   \t "<< -3.40-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -17.6971+13.7098 <<" \t "<< -16.8811+13.2011  <<"   \t "<< -5.06-2.39 << "\n";

    model().load (path() + "Thr.mlm" );   calc (model(), ff_name); // -2.57 Threonine 
    out << "Thr   \t "<< -2.57-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -16.4848+13.7098 <<" \t "<< -15.0150+13.2011  <<"   \t "<< -4.88-2.39 << "\n";

    model().load (path() + "Trp.mlm" );   calc (model(), ff_name); //  2.33 Tryptophan 
    out << "Trp   \t  "<< 2.33-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -15.5688+13.7098 <<" \t "<< -14.8535+13.2011  <<"   \t "<< -5.88-2.39 << "\n";

    model().load (path() + "Tyr.mlm" );   calc (model(), ff_name); // -0.14 Tyrosine 
    out << "Tyr   \t "<< -0.14-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -17.5330+13.7098 <<" \t "<< -16.2236+13.2011  <<"   \t "<< -6.11-2.39 << "\n";

    model().load (path() + "Val.mlm" );   calc (model(), ff_name); //  4.04 Valine 
    out << "Val   \t  "<< 4.04-0.94 <<"   \t" << interactions.last_continuum_solvation_potential()-Eg << "\t "
        << -12.5206+13.7098 <<" \t "<< -11.7038+13.2011  <<"   \t  "<< 1.99-2.39 << "\n";
}


}//MM
