#ifndef AKMA_SYSTEM_OF_UNITS_H
#define AKMA_SYSTEM_OF_UNITS_H

#ifndef SYSTEM_OF_UNITS_H
#include "System_of_Units.h"
#endif

#ifndef LENGTH_UNIT_H
#include "Length_unit.h"
#endif

#ifndef ENERGY_UNIT_H
#include "Energy_unit.h"
#endif

#ifndef MASS_UNIT_H
#include "Mass_unit.h"
#endif

#ifndef CHARGE_UNIT_H
#include "Charge_unit.h"
#endif

#ifndef DURATION_UNIT_H
#include "Duration_unit.h"
#endif

#ifndef FORCE_UNIT_H
#include "Force_unit.h"
#endif

#ifndef PRESSURE_UNIT_H
#include "Pressure_unit.h"
#endif

#ifndef TEMPERATURE_UNIT_H
#include "Temperature_unit.h"
#endif

namespace MM
{

class AKMA_System_of_Units : public System_of_Units
{
public:
    double      Boltzmann_constant () const                                     {return gas_constant()/Avogadro_constant();} // kcal K-1
    double      gas_constant () const                                           {return 0.001987191;} // kcal mol-1 K-1

    double      length  (Length_unit const & v) const                           {return v.A();}
    double      energy  (Energy_unit const & v) const                           {return v.kcalImol();}
    double      mass    (Mass_unit   const & v) const                           {return v.amu();}
    double      charge  (Charge_unit const & v) const                           {return v.electron();}
    double      time     (Duration_unit const & v,
                                  double * step_length = 0) const
    {
        double result = v.AKMA ();
        if (step_length != 0)
        {
            double steps = v.steps();
            if (steps == 0.)
                *step_length = 0.;
            else
                *step_length = result / steps;
        }
        return result;
    }

    double      force   (Force_unit const & v) const                            {return v.kcalImolA();}
    double      pressure(Pressure_unit const & v) const                         {return v.kcalImolA3();}
    //virtual double      electric_conversion_factor() const = 0;
    double      temperature  (Temperature_unit const &v) const                  {return v.K();}

    void        set_length (Length_unit & result,   double v) const             {result.set_A (v);}
    void        set_energy (Energy_unit & result,   double v) const             {result.set_kcalImol (v);}
    void        set_mass   (Mass_unit   & result,   double v) const             {result.set_amu (v);}
    void        set_charge (Charge_unit & result,   double v) const             {result.set_electron (v);}
    void        set_time (Duration_unit & result, double v, double steps) const
    {
        result.set_AKMA (v); 
        double ps          = result.ps ();
        double step_length = ps / steps;
        result.set_step_length_ps (step_length);
        //result.set_steps (steps);
    }
    void        set_force  (Force_unit  & result,   double v) const             {result.set_kcalImolA (v);}
    void        set_pressure(Pressure_unit & result,double v) const             {result.set_kcalImolA3 (v);}
    void        set_temperature (Temperature_unit & result, double v) const     {result.set_K (v);}
};

}//MM

#endif //AKMA_SYSTEM_OF_UNITS_H
