#ifndef SYSTEM_OF_UNITS_H
#define SYSTEM_OF_UNITS_H

// http://goldbook.iupac.org

namespace MM
{
class Length_unit;
class Energy_unit;
class Mass_unit;
class Charge_unit;
class Duration_unit;
class Force_unit;
class Pressure_unit;
class Temperature_unit;

class System_of_Units
{
public:
    virtual            ~System_of_Units () ;
    static System_of_Units &    singleton ();

    virtual double      Boltzmann_constant () const =0;
    virtual double      gas_constant () const =0;
    double              Avogadro_constant () const                              {return 6.0221417930e23;} //mol-1

    virtual double      length  (Length_unit const &) const = 0;
    virtual double      energy  (Energy_unit const &) const = 0;
    virtual double      mass    (Mass_unit   const &) const = 0;
    virtual double      charge  (Charge_unit const &) const = 0;
    virtual double      time     (Duration_unit const & v,
                                  double * step_length = 0) const = 0;
    virtual double      force   (Force_unit const &) const = 0;
    virtual double      pressure(Pressure_unit const &) const = 0;
    //virtual double      electric_conversion_factor() const = 0;
    virtual double      temperature  (Temperature_unit const &) const = 0;

    virtual void        set_length (Length_unit & result,   double v) const = 0;
    virtual void        set_energy (Energy_unit & result,   double v) const = 0;
    virtual void        set_mass   (Mass_unit   & result,   double v) const = 0;
    virtual void        set_charge (Charge_unit & result,   double v) const = 0;
    virtual void        set_time (Duration_unit & result,
                                  double v, double steps) const = 0;
    virtual void        set_force  (Force_unit  & result,   double v) const = 0;
    virtual void        set_pressure(Pressure_unit & result,double v) const = 0;
    virtual void        set_temperature (Temperature_unit & result,
                                         double v) const = 0;
};

}//MM

#endif //SYSTEM_OF_UNITS_H
