// Header file containing the definition of the 'model' routines. The
// object 'model' stores all parameters for the model run defined in
// 'input.par'. Basic parameters and structures of the model space,
// such as emission and scattering regions, are defined here. The
// routines of the object 'model' read in the input data from the file
// 'input.par' and compute basic parameters of the specified run.
//
// STOKES, version 1.0, Nov 2004


#ifndef model_h
#define model_h


#include "mie-stokes-v1.0.h"


// maximum number of spectroscopic channels of the detectors
const int ResMax = 200;


// maximum number of detectors in the phi-direction
const int ScreenNumPhiMax = 80;


// maximum number of detectors in the theta-direction
const int ScreenNumThetaMax = 40;


// maximum number of scattering regions
const int ScattMax = 30;


// precision for the computation of the phase functions (in degrees)
const double PFPrecision = 1.0;


// precision for the sampling of the line photons (in Angstroem)
const double LinePrecision = 1.0;


// Thomson cross section in ccm/parsec
const double TCS = 3.08633e18*6.6524e-25;


// type of a scatterer (torus, cylinder, conical, sphere) - shape,
// pos, a, b, and theta describe the geometry of the region, vr
// denotes a radial velocity, if dust is set, then Density denotes a
// dust density otherwise an electron density.
struct scatterer
{
	int shape;
	bool dust;
	double pos[3];
	double R,a,b,theta;
	double vr;
	double Density;
};


// type of a continuum emission region (disk-shaped), spectral index
// alpha for the intensity spectrum I(nu) ~ nu^(-alpha)
struct CTRegion
{
	double R,a,b,alpha,vr;
};


// type of a broad line emission region (toroidal)
struct BLRegion
{
	double R,a,b,lambda,width,rli,vr,norm,low;
};


// type of a narrow line emission region (conical)
struct NLRegion
{
	double a,b,theta,lambda,width,rli,vr,norm,low;
};


// type definition of the object model
class Model
{


public:


  // initialize the Model parameters by setting them to the
  // default values
  Model();


  // read in model parameters from 'input.par', if the initialization
  // happens correctly return 'true'.
  bool Model::Initialize(Mie& Dust);


  // return the number of detectors in the phi-direction
  int ScreenNumPhi();


  // return the number of detectors in the theta-direction
  int ScreenNumTheta();


  // return the number of spectroscopic channels
  int res();


  // return the number of photons to sample
  long int PhotonNum();


  // return the number of scattering regions defined
  int GetScattNum();


  // return parameters of the scattering region with index i
  scatterer GetCloud(int i);


  // return the maximum expansion of all scattering regions
  double GetMaxExp();


  // return the maximum radial velocity of all scattering regions
  double GetVMax();


  // return the minimum photon wavelength defined
  double LambdaMin();


  // return the maximum photon wavelength defined
  double LambdaMax();


  // return the photon wavelength range covered
  double LambdaRange();


  // set the output file name to 'name'
  void GetOutputFile(char name[80]);


  // set the dust file name to 'name'
  void GetDustFile(char name[80]);


  // return the minimum grain radius defined
  double RadiusMin();


  // return the maximum grain radius defined
  double RadiusMax();


  // return the index of the grain size distribution
  double GetRadAlpha();


  // return the number of grain radii considered for calculating
  // the Mie data
  int GetRadNum();


  // return the number of wavelengths considered for calculating
  // the Mie data
  int GetLamNum();


  // set the percentages of all dust components to 'Components'
  void GetComp(double Components[SubNum]);


  // return the minimum gab between scattering clouds
  double GetGap();


  // return 'true' if the model space is defined symmetrically with
  // respect to the xy-plane and 'false' otherwise
  bool GetPlaneSymmetry();


  // return the parameters of the continuum emission region
  CTRegion GetCTR();


  // return the parameters of the broad line emission region
  BLRegion GetBLR();


  // return the parameters of the narrow line emission region
  NLRegion GetNLR();


private:


  // parameters of the continuum emission region
  CTRegion CTR;


  // parameters of the broad emission line region
  BLRegion BLR;


  // parameters of the narrow emission line region
  NLRegion NLR;


  // parameters of the scattering regions
  scatterer Cloud[ScattMax];


  // number of scattering regions
  int EndScattList;


  // number of detectors in the phi-direction
  int SNumPhi;


  // number of detectors in the theta direction
  int SNumTheta;


  // number of spectroscopic channels for the detectors
  int resolut;
 

  // minimum and maximum wavelength (in Angstroem) of photons sampled
  double LamMin,LamMax;
 

  // total number of photons sampled
  long int PNum;


  // maximum expansion among all scattering regions
  double MaxExp;


  // maximum radial velocity among all scattering regions
  double VMax;


  // minimum and maximum grain radii (in microns)
  double RadMin,RadMax;


  // index of the grain size distribution: n(a)~a^(RadAlpha) 
  double RadAlpha;


  // number of grain radii considered for calculating the Mie data
  int RadNum;


  // number of wavelengths considered for calculating the Mie data
  int LamNum;


  // abundance of the various dust components (in percent)
  double Comp[SubNum];


  // Minimum gap between scattering regions.This parameter
  // is required for computational reasons. The object Photon
  // distinguishes between photon positions inside and outside
  // scattering clouds. A photon that is leaving a scattering cloud is
  // re-located outside of it, at the distance GetGap to the (smoothly
  // defined) cloud surface. This is done to ensure that the photon is
  // safely recognized as being outside the cloud.
  double Gap;


  // Stem name of the output files
  char outputfile[80];

  // Stem name of the dust file
  char dustfile[80];

  // Parameter describing if the model space defined is symmetric with
  // respect to the xy-plane. If it is set to 'true' the results at the
  // inclinations i and 180 deg - i are combined.
  bool planesym;


};


#endif
