#ifndef F77IMP_H
#define F77IMP_H

#include "fpreproc/f77name.h"
#include "preact/transperror.h"
#include "preact/transp_util.h"

//
// This is a set of routines for accessing the ImpReaction routines
// from fortran 77
//

extern "C" {

  //
  // currently these routines only provide support through the
  // ImpReactionTable singleton.  If you need distinct ImpReaction
  // objects then you should add to this interface or to the ImpReactionTable
  // interface or write your code in C++.
  //

  // 
  // ----- ImpReactionTable support ------
  //
  void F77NAME(imptable_def_option)(const int& opt) ;  // change the default ImpReaction::option for the table
                                                       // see ImpReaction::option for integer values
  void F77NAME(imptable_def_brem)(const int& ibrem) ;  // change the default brem... flag
                                                       // ibrem = 0 -> do not include brem... in radiation rate
                                                       //       = 1 -> include brem... in radiation rate
  void F77NAME(imptable_build)(const int& nucz, const int& opt, 
			       const int& ibrem) ;                 // explicity build an Element in the table,
                                                                   // this is NOT required before using the table

  void F77NAME(imptable_print)(const int& nucz) ;      // write information to stdout about this reaction

  // 
  // ------ Range Policies ------
  // set policies when the axis arguments exceed the bounds of the React objects.
  //   iaxis=0 -> Te
  //   iaxis=1 -> Ne
  // for policy integer values see Range::policy
  //
  void F77NAME(imptable_ioniz_policy)(const int& nucz, const int& iaxis, const int& pmin, const int& pmax) ;
  void F77NAME(imptable_recom_policy)(const int& nucz, const int& iaxis, const int& pmin, const int& pmax) ;
  void F77NAME(imptable_rad_policy)(const int& nucz, const int& iaxis, const int& pmin, const int& pmax) ;
  void F77NAME(imptable_brem_policy)(const int& nucz, const int& iaxis, const int& pmin, const int& pmax) ;
  void F77NAME(imptable_policy)(const int& nucz, const int& iaxis, const int& pmin, const int& pmax) ; // for all four Reactions

  //
  // ------- Rates --------
  // input:
  //   nucz    -> nuclear charge Z of element
  //   nvec    -> number of evaluations of the rates
  //   te(nmax)-> array containing electron temperature in keV  nvec<=nmax
  //   ne(nmax)-> array containing electron density in m-3      nvec<=nmax
  //   mmax    -> size of first dimension of result array       (nucz+1)<=mmax -- checked
  // output:
  //   result(mmax,nvec) -> contains the rate coefficients in the form
  //                       result(i,j) = rate for charge state (i-1) for te(j),ne(j)
  //
  const bool imptable_skip_check=true ;   // checking not needed and it might speed things up

  //
  // electron collision ionization (sec-1)
  //
  void F77NAME(imptable_ioniz_r8)(const int& nucz, const int& nvec, fp_64* te, fp_64* ne, const int& mmax, fp_64* result) ;

  //
  // radiative and dielectronic recombination (sec-1)
  //
  void F77NAME(imptable_recom_r8)(const int& nucz, const int& nvec, fp_64* te, fp_64* ne, const int& mmax, fp_64* result) ;

  //
  // radiation rate (joules/sec)
  //
  void F77NAME(imptable_rad_r8)(const int& nucz, const int& nvec, fp_64* te, fp_64* ne, const int& mmax, fp_64* result) ;

  //
  // brem... radiation rate (joules/sec) [if not included in imptable_rad]
  //
  void F77NAME(imptable_brem_r8)(const int& nucz, const int& nvec, fp_64* te, fp_64* ne, const int& mmax, fp_64* result) ;

  //
  // ---- coronal equilibrium ---
  //   nucz    -> nuclear charge Z of element
  //   nvec    -> number of evaluations of the rates
  //   ioniz(mmax,nvec)-> array containing ionization rate (sec-1)
  //   recom(mmax,nvec)-> array containing recombination rate (sec-1)
  //   rad(mmax,nvec)  -> array containing radiation rate (joules/sec)
  //   mmax    -> size of first dimension of arrays       (nucz+1)<=mmax -- checked
  // input/output:
  //   coron(mmax,nvec) -> contains the coronal equilibrium normalized for a sum of 1
  //                       coron(i,j) = fraction of particles in charge state (i-1) for 
  //                                     rates ioniz(*,j),recom(*,j)
  // output:
  //   result(nvec) -> contains the total radiation associated with the coronal equilibrium
  //                   coron(mmax,nvec) and radiation rate rad(mmax,nvec) in (joules/sec)
  //                   for the nvec sets of charge state data.
  //
  void F77NAME(impreaction_coronal)(const int& nucz, const int& nvec, fp_64* ioniz, fp_64* recom, const int& mmax, fp_64* coron) ;

  void F77NAME(impreaction_coronal_rad)(const int& nucz, const int& nvec, fp_64* coron, fp_64* rad, const int& mmax, fp_64* result) ;

  //
  // test/demo code
  // -- input --
  // fnucz = fortran integer for nuclear Z of impurity
  // fte   = fortran real*8 for electron temperature in keV
  // fne   = fortran real*8 for electron density in m-3
  // -- outputs --
  // fcoron     = fortran array of type real*8, dimension(nucz+1)
  //              which will contain the coronal equilibrium as a return value
  // fcoron_rad = fortran variable of type real*8
  //              which will contain the total radiation in (joules/sec) at
  //              the coronal equilibrium.
  //
  void F77NAME(preact_impurity_test)(const int* fnucz, const fp_64* fte, const fp_64* fne, 
				     fp_64* fcoron, fp_64* fcoron_rad) ;
} ;

#endif
