/*
    This file is part of the MolMeccano cross-platform C++ chemical library.

    Copyright (C) 2001,2002 Alexei Nikitin.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifndef AMBER_TORSION_ENERGY_H
#define AMBER_TORSION_ENERGY_H

#ifndef DIHEDRAL_ENERGY_H
#include "Dihedral_energy.h"
#endif

#ifndef FORCE_FIELD_H
#include "Force_field.h"
#endif

#ifndef TORSION_ANGLE_H
#include "Torsion_angle.h"
#endif

namespace MM
{

class Atom;

class AMBER_torsion_energy : public Dihedral_energy
{
public:
/*    AMBER_torsion_energy( const Atom & atom1,
                          const Atom & atom2,
                          const Atom & atom3,
                          const Atom & atom4,
                          double force_constant,
                          double equilibrium_value );//*/

    AMBER_torsion_energy (const Atom & atom1,
                          const Atom & atom2,
                          const Atom & atom3,
                          const Atom & atom4,
                          const Array <Force_field::Torsions> *parameters);

    bool    is_valid () const {return ref_ != 0;}

    int     fourier_terms   ()      const {return ref_->size();     }
    double  force_constant  (int i) const {return (*ref_)[i].half_V;}
    double  phase_angle     (int i) const {return (*ref_)[i].Fi0;   }
    int     n_fold_symmetry (int i) const {return (*ref_)[i].N;     }
    int     multiplicity    (int i) const {return (*ref_)[i].Mult;  }

    const Atom &    first_atom  () const {return torsion_angle_.first_atom ();}
    const Atom &    second_atom () const {return torsion_angle_.second_atom();}
    const Atom &    third_atom  () const {return torsion_angle_.third_atom ();}
    const Atom &    fourth_atom () const {return torsion_angle_.fourth_atom ();}

protected:
    virtual double handle_value () const ;

private:
    const Array <Force_field::Torsions> *ref_;

    Torsion_angle   torsion_angle_;     // radian

    //double          force_constant_;    // kcal / mol radian 2
    //double          phase_angle_;       // radian
    //int             n_fold_symmetry_;
};

}//MM

#endif //AMBER_TORSION_ENERGY_H




