/*
   Project: Adun

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

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

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

#ifndef AD_FORCEFIELD_FUNCTIONS
#define AD_FORCEFIELD_FUNCTIONS

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "Base/AdVector.h"
#include "Base/AdLinkedList.h"

/**
\defgroup Functions Functions
\ingroup Base
*/

/**
\defgroup Types Types
\ingroup Base
*/

/**
These are the primitive functions used to calculate the energy and force
terms of a force field. The interface to these functions is unstable and
likely to change. Especially with regard to the use of the globally defined
coordinates and accelerations variables below.
\defgroup ForceFieldFunctions Force Field 
\ingroup Functions
*/

//extern declarations of the coordinates and accelerations the
//functions work on

extern double **coordinates, **accelerations;

//these variables must be set by the calling function for calc_NBD_accleration to work

extern double r_cutoff2, epsilon_r;
extern int cutoff;

/*
 * Harmonic Bond
 */

/** Calculates the energy of a bond using a harmonic bond function */
inline void AdHarmonicBondEnergy(double*, double*, double**);
/** Calculates the energy and force of a bond using a harmonic bond function */
inline void AdHarmonicBondForce(double*, double*);
/** Calculates the energy and acceleration of a bond using a harmonic bond function */
inline void AdHarmonicBondAcceleration(double*, double*);


/*
 * Harmonic Angle
 */

/** Calculates the energy of an angle using a harmonic angle function */
inline void AdHarmonicAngleEnergy(double*, double*, double**);
inline void AdHarmonicAngleForce(double*, double*);
inline void AdHarmonicAngleAcceleration(double*, double*);

/*
 * fourier torsion
 */

/** calculates the energy of a proper torsion using a fourier torsion function */
inline void AdFourierTorsionEnergy(double*, double*, double**);
inline void AdFourierTorsionAccleration(double*, double*);
inline void AdFourierTorsionForce(double*, double*);

/*
 * harmonic improper  torsion
 */

/** calculates the energy of an improper torsion using a harmonic function */
inline void AdHarmonicImproperTorsionEnergy(double* , double* , double** );
inline void AdHarmonicImproperTorsionForce(double*, double* );

/*
 * EnzymixNonbonded - TypeOneVdwInteraction + ColoumbElectrostatic
 */

/** Calculates the energy of a proper torsion using a combined coloumb electrostatic and TypeOneVdwInteraction */
inline void AdEnzymixNonbondedEnergyOld(int*, float*, double*, double*, double*, Vector3D*, double**);
inline void AdEnzymixNonbondedEnergy(ListElement*, double*, double*, 
			double, double**, double);
inline void AdEnzymixNonbondedForce(ListElement*, double*, double*, 
				double, double**, double**,
				double);
inline void AdEnzymixNonbondedAcceleration(int*, float*, double*, double*, double*);

inline void AdEnzymixShiftedNonbondedEnergy(ListElement*, double*, double*,  
			double, double**, double, float);
inline void AdEnzymixShiftedNonbondedForce(ListElement*, double*, double*, 
				double, double**, double**,
				double, float);

inline void AdEnzymixGRFNonbondedEnergy(ListElement *, double *, double *, double,  double **,
				double , double );
inline void AdEnzymixGRFNonbondedForce(ListElement* , double* , double* , 
				double , double** , double** ,
				double , double , double );

/*
 * Deprecated
 */


inline void calc_GRID_EST(ListElement *, double *, double, double **,
				double , int);
inline void grid_EST_switched(ListElement *Interaction, double *est_pot, double EPSILON_RP, double **coordinates,
				double cutoff_sq, double buffer_sq, int grid_point);

#endif
