/*! \file tra_subs.h
 *
 * \brief C++ porting of TRAPPING functions and subroutines.
 *
 * This library includes a collection of functions that are used to solve the
 * trapping problem. The functions that were generalized from the case of the
 * single sphere are imported the `sph_subs.h` library. As it occurs with the
 * single sphere case functions, in most cases, the results of calculations do
 * not fall back to fundamental data types. They are rather multi-component
 * structures. In order to manage access to such variety of return values, most
 * functions are declared as `void` and they operate on output arguments passed
 * by reference.
 */

#ifndef INCLUDE_TRA_SUBS_H_
#define INCLUDE_TRA_SUBS_H_
#endif

// Structures for TRAPPING
/*! \brief CIL data structure.
 *
 * A structure containing field expansion order configuration.
 */
struct CIL {
  //! Maximum L expansion of the electric field.
  int le;
  //! le * (le + 1).
  int nlem;
  //! 2 * nlem.
  int nlemt;
  //! Maximum field expansion order + 1.
  int mxmpo;
  //! 2 * mxmpo - 1.
  int mxim;
};

/*! \brief CCR data structure.
 *
 * A structure containing geometrical asymmetry parameter normalization coefficients.
 */
struct CCR {
  //! First coefficient.
  double cof;
  //! Second coefficient.
  double cimu;
};
//End of TRAPPING structures

/*! C++ porting of CAMP
 *
 * \param ac: Vector of complex. QUESTION: definition?
 * \param am0m: Matrix of complex. QUESTION: definition?
 * \param ws: Vector of complex. QUESTION: definition?
 * \param cil: `CIL *` Pointer to a CIL structure.
 *
 * This function builds the AC vector using AM0M and WS.
 */
void camp(
	  std::complex<double> *ac, std::complex<double> **am0m, std::complex<double> *ws,
	  CIL *cil
);

/*! C++ porting of CZAMP
 *
 * \param ac: Vector of complex. QUESTION: definition?
 * \param amd: Matrix of complex. QUESTION: definition?
 * \param indam: `int **`. QUESTION: definition?
 * \param ws: Vector of complex. QUESTION: definition?
 * \param cil: `CIL *` Pointer to a CIL structure.
 *
 * This function builds the AC vector using AMD, INDAM and WS.
 */
void czamp(
	   std::complex<double> *ac, std::complex<double> **amd, int **indam,
	   std::complex<double> *ws, CIL *cil
);

/*! C++ porting of FFRF
 *
 * \param zpv: `double ****`. QUESTION: definition?
 * \param ac: Vector of complex. QUESTION: definition?
 * \param ws: Vector of complex. QUESTION: definition?
 * \param fffe: `double *`. QUESTION: definition?
 * \param fffs: `double *`. QUESTION: definition?
 * \param cil: `CIL *` Pointer to a CIL structure.
 * \param ccr: `CCR *` Pointer to a CCR structure.
 */
void ffrf(
	  double ****zpv, std::complex<double> *ac, std::complex<double> *ws, double *fffe,
	  double *fffs, CIL *cil, CCR *ccr
);

/*! C++ porting of FFRT
 *
 * \param ac: Vector of complex. QUESTION: definition?
 * \param ws: Vector of complex. QUESTION: definition?
 * \param ffte: `double *`. QUESTION: definition?
 * \param ffts: `double *`. QUESTION: definition?
 * \param cil: `CIL *` Pointer to a CIL structure.
 * \param ccr: `CCR *` Pointer to a CCR structure.
 */
void ffrt(
	  std::complex<double> *ac, std::complex<double> *ws, double *ffte, double *ffts,
	  CIL *cil
);

/*! C++ porting of FRFMER
 *
 * \param nkv: `int` QUESTION: definition?
 * \param vkm: `double` QUESTION: definition?
 * \param vkv: `double *` QUESTION: definition?
 * \param vknmx: `double` QUESTION: definition?
 * \param apfafa: `double` QUESTION: definition?
 * \param tra: `double` QUESTION: definition?
 * \param spd: `double` QUESTION: definition?
 * \param rir: `double` QUESTION: definition?
 * \param ftcn: `double` QUESTION: definition?
 * \param le: `int` QUESTION: definition?
 * \param lmode: `int` QUESTION: definition?
 * \param pmf: `double` QUESTION: definition?
 * \param tt1: `fstream &` Handle to first temporary binary file.
 * \param tt2: `fstream &` Handle to second temporary binary file.
 */
void frfmer(
	    int nkv, double vkm, double *vkv, double vknmx, double apfafa, double tra,
	    double spd, double rir, double ftcn, int le, int lmode, double pmf,
	    std::fstream &tt1, std::fstream &tt2
);

/*! C++ porting of PWMALP
 *
 * \param w: Matrix of complex. QUESTION: definition?
 * \param up: `double *`
 * \param un: `double *`
 * \param ylm: Vector of complex
 * \param lw: `int`
 */
void pwmalp(std::complex<double> **w, double *up, double *un, std::complex<double> *ylm, int lw);

/*! C++ porting of SAMP
 *
 * \param ac: Vector of complex. QUESTION: definition?
 * \param tmsm: Vector of complex. QUESTION: definition?
 * \param tmse: Vector of complex. QUESTION: definition?
 * \param ws: Vector of complex. QUESTION: definition?
 * \param cil: `CIL *` Pointer to a CIL structure.
 *
 * This function builds the AC vector using TMSM, TMSE and WS.
 */
void samp(
	  std::complex<double> *ac, std::complex<double> *tmsm, std::complex<double> *tmse,
	  std::complex<double> *ws, CIL *cil
);

/*! C++ porting of SAMPOA
 *
 * \param ac: Vector of complex. QUESTION: definition?
 * \param tms: Matrix of complex. QUESTION: definition?
 * \param ws: Vector of complex. QUESTION: definition?
 * \param cil: `CIL *` Pointer to a CIL structure.
 *
 * This function builds the AC vector using TMS and WS.
 */
void sampoa(
	    std::complex<double> *ac, std::complex<double> **tms, std::complex<double> *ws,
	    CIL *cil
);

/*! C++ porting of WAMFF
 *
 * \param wk: Vector of complex. QUESTION: definition?
 * \param x: `double`
 * \param y: `double`
 * \param z: `double`
 * \param lm: `int`
 * \param apfafa: `double` QUESTION: definition?
 * \param tra: `double` QUESTION: definition?
 * \param spd: `double` QUESTION: definition?
 * \param rir: `double` QUESTION: definition?
 * \param ftcn: `double` QUESTION: definition?
 * \param lmode: `int` QUESTION: definition?
 * \param pmf: `double` QUESTION: definition?
 */
void wamff(
	   std::complex<double> *wk, double x, double y, double z, int lm, double apfafa,
	   double tra, double spd, double rir, double ftcn, int lmode, double pmf
);
