/*
    This file is part of the ChemCon molecular mechanics 
    and molecular graphics program.

    Copyright (C) 1997-2002  Alexei Nikitin 

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

    This program 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 General Public License for more details.

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

#ifndef AMBER_ENERGY_H
#define AMBER_ENERGY_H

#include <deque>

#ifndef ENERGY_H
#include "Energy.h"
#endif

#ifndef ELECTROSTATIC_ENERGY_H
#include "Electrostatic_energy.h"
#endif

#ifndef VAN_DER_WAALS_ENERGY_H
#include "Van_der_Waals_Energy.h"
#endif

#ifndef BOND_ENERGY_H
#include "Bond_energy.h"
#endif

#ifndef ANGLE_ENERGY_H
#include "Angle_energy.h"
#endif

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

#ifndef DBC_H
#include "DbC.h"
#endif

#ifndef ARRAY_H
#include "Array.h"
#endif

#ifndef AMBER_BOND_ENERGY_H
#include "AMBER_bond_energy.h"
#endif

#ifndef AMBER_ANGLE_ENERGY_H
#include "AMBER_angle_energy.h"
#endif

#ifndef AMBER_TORSION_ENERGY_H
#include "AMBER_torsion_energy.h"
#endif

#ifndef AMBER_VAN_DER_WAALS_ENERGY_H
#include "AMBER_Van_der_Waals_energy.h"
#endif

#ifndef AMBER_VAN_DER_WAALS_SCALED_ENERGY_H
#include "AMBER_Van_der_Waals_scaled_energy.h"
#endif


namespace MM
{

//template < class T > class Array_of;
class Atom;
class Atom_group;
class Bond;
class Bond_group;
class Force_field;

class AMBER_energy : public Energy, protected DbC
{
    const Force_field                           &force_field_;

    //Array <AMBER_bond_energy         >          bond_energy_;
    std::deque <AMBER_bond_energy         >          bond_energy_;
    std::deque <AMBER_angle_energy        >          angle_energy_;
    std::deque <AMBER_torsion_energy      >          torsion_energy_;
//    Array <Electrostatic_energy>              electrostatic_energy_;
    std::deque <AMBER_Van_der_Waals_energy>          Van_der_Waals_energy_;
    std::deque <AMBER_Van_der_Waals_scaled_energy>   Van_der_Waals_scaled_energy_;

    void    setup_bond_energy    (const Bond & bond);
    void    setup_torsion_energy (const Bond & bond);
    void    setup_angle_energy   (const Atom & atom_2);
    //void    setup_electrostatic_energy (int i, Array_of <Atom> & atoms );
    //void    setup_Van_der_Waals_energy (int i, Array_of <Atom> & atoms );
    void    setup_electrostatic_energy (int i, const Atom_group & atoms);
    void    setup_Van_der_Waals_energy (int i, const Atom_group & atoms);

public:
    //AMBER_energy (Array_of <Atom> & atoms, 
    //              Array_of <Bond> & bonds,
    //              Force_field     & force_field);

    AMBER_energy (const Atom_group  & atoms,
                  const Bond_group  & bonds,
                  const Force_field & force_field);

    double                  bond_energy          () const;
    double                  angle_energy         () const;
    double                  torsion_energy       () const;
    //double                electrostatic_energy () const;
    double                  van_der_Waals_energy () const;

    AMBER_bond_energy &     bond (int i)     {return bond_energy_[i];}
    int                     bond_count ()    {return bond_energy_.size();}

    AMBER_angle_energy &    angle (int i)    {return angle_energy_[i];}
    int                     angle_count ()   {return angle_energy_.size();}

    AMBER_torsion_energy &  torsion (int i)  {return torsion_energy_[i];}
    int                     torsion_count () {return torsion_energy_.size();}

protected:
    virtual double handle_value () const;
};

}//MM

#endif //AMBER_ENERGY_H
