#ifndef CANTERA_DEF
#define CANTERA_DEF
#include <cantera/IdealGasMix.h>
#include <cantera/transport.h>
#endif

#include "gridRoutines.h"
#include <string>

#ifndef USER_DEF
#define USER_DEF
typedef struct UserDataTag{
	/*An ideal gas object from Cantera. Contains thermodynamic and kinetic
	 * info of all species.*/
	Cantera::IdealGasMix* gas;
	/*A Transport object from Cantera. Contains all transport info of all
	 * species.*/
	Cantera::Transport* trmix;
	/* Droplet species composition */
	//char dropSpec[MAXBUFLEN];
    char dropSpec[2][10];
    /* Droplet species mole fractions */
    double dropMole[2];
    /* Droplet species density at given initialTemperature*/
    double dropDens[2];
    /* Droplet species mass fractions*/
    double dropMassFrac[2];
    double dropRho; 
	/*Length of the domain (in meters):*/			  
	double domainLength;	  
	/*Initial Droplet Radius (in meters)*/
	double Rd;
	/*Droplet Mass*/
	double massDrop;
	/*Mass of gas in domain (in kg):*/			  
	double mass;		  
	/*Parameter that indicates the symmetry of the problem;*/			  
	/*metric=0:Planar*/			  
	/*metric=1:Cylindrical*/			  
	/*metric=2:Spherical*/			  
	int metric;		  
	/*No: of species:*/
	size_t nsp;	  
	/*No: of equations:*/
	size_t neq;
	/*No: of variables:*/
	size_t nvar;
	/*Pointer indices (see "macros.h" for aliases that use these):*/
	/*Pointer index for temperature:*/
	size_t nt;	  
	/*Pointer index for species:*/
	size_t ny;
	/*Pointer index for spatial coordinate:*/
	size_t nr;
	/*Pointer index for pressure:*/
	size_t np;
	/*Pointer index for mass flow rate:*/
	size_t nm;
	/*Species index of bath gas:*/			  
	size_t k_bath;		  
	/*Species index of oxidizer:*/			  
	size_t k_oxidizer;		  
	size_t k_OH;
	size_t k_HO2;
	/*Species index of droplet composition*/
    /*Index starts with 1 instead of 0*/
	size_t k_drop[2];
	/*User-defined mass flux (kg/m^2/s):*/			  
	double mdot;
	/*Flag to solve isobaric/isochoric problem;*/
	/*constantPressure=1: isobaric*/
	/*constantPressure=0: isochoric*/
	int constantPressure;
	/*User-defined dPdt (Pa/s), activates when problem is "isobaric":*/			  
	double dPdt;	
	/*Initial temperature of the gas (K):*/
	double initialTemperature;
	/*Initial Pressure of the gas (atm):*/
	double initialPressure;
	/*Classification of problem type;*/
	/*problemType=0: Mixture is premixed and spatially uniform initially.
	 * In order for mixture to ignite, an external heat source (finite
	 * maxQDot) must be used.*/
	/*problemType=1: Mixture is premixed but spatially non-uniform
	 * initially. Equilibrium products are contained within a hot kernel of
	 * size given by "shift" and a mixing length scale given by
	 * "mixingWidth".*/
	/*problemType=2: User specified initial condition. Use file
	 * "initialCondition.dat".*/
	int problemType;
	/*Quasi-Steady Assumption:
	 *quasiSteady=0: The droplet surface recedes and the droplet losses mass.
	 *quasiSteady=1: The droplet surface does not move and the droplet mass is constant.*/
	int quasiSteady;
	/*Maximum External heat source (K/s):*/
	double maxQDot;
	/*Ignition kernel size:*/
	double kernelSize;

	double maxTemperature;
	/*Maximum time for which the external heat source is applied (s):*/
	double ignTime;
	/*Vector of Mass Fractions used to impose Robin Boundary Condition for
	 * species at the domain origin:*/
	double* innerMassFractions;
	/*Value of temperature to be used if Dirichlet Boundary Conditions are
	 * imposed for temperature:*/
	double innerTemperature;
	double wallTemperature;
	/*Isotherm chosen to find the location of a "burning" front (K):*/
	double isotherm;
	/*Interval of time integration:*/
	double finalTime;
	/*Current time:*/
	double tNow;
	/*Flag to reflect initial conditions across center of the domain:*/
	int reflectProblem;
	/*Parameters for initial conditions in setting up profiles:
	increasing function of x: g=0.5*(erf(x-3*w-shift)/w)+1)
	decreasing function of x: f=1-g*/
	double mixingWidth;
	double shift;
	double firstRadius;
	/*Flag to run program without time-integration i.e. simply layout the
	 * initial conditions and quit:*/
	int dryRun;
	/*Relative Tolerance:*/
	double relativeTolerance;
	/*Absolute Tolerance for spatial coordinate:*/
	double radiusTolerance;
	/*Absolute Tolerance for Temperature:*/
	double temperatureTolerance;
	/*Absolute Tolerance for Pressure:*/
	double pressureTolerance;
	/*Absolute Tolerance for Mass Fractions:*/
	double massFractionTolerance;
	/*Absolute Tolerance for bath gas mass fraction:*/
	double bathGasTolerance;
	/*Absolute Tolerance for Mdot:*/
	double MdotTolerance;
	/*Flag to set constraints on Mass fractions so they don't acquire
	 * negative values:*/
	int setConstraints;
	/*Flag to suppress error checking on algebraic variables:*/
	int suppressAlg;
	/*Number of time-steps elapsed before saving the solution:*/
	int nSaves;		  
	/*Flag to set write for every regrid:*/
	int writeEveryRegrid;
	/*Solution output file:*/
	FILE* output;
	/*Flag to write the rates (ydot) of solution components into the
	 * "ratesOutput" file:*/
	int writeRates;
	/*Grid output file:*/
	FILE* gridOutput;
	///*Rate of change (ydot) output file (see "writeRates"):*/
	//FILE* ratesOutput;
	/*Global properties (mdot, radius of flame, etc.) output file:*/
	FILE* globalOutput;

	/*Flag to adapt grid:*/
	int adaptiveGrid;
	/*Flag to move grid:*/
	int moveGrid;
	/*Flag to initiate regrid:*/
	int regrid;
	/*Integer that specifies grid movement direction:
	 * gridDirection = -1: Move Left
	 * gridDirection = +1: Move Right*/ 
	int gridDirection;
	
	/*Grid Ratio: This replaces the uniform grid. dX0 and dXf are the grid
	spacing at the droplet surface and right boundary, respectivly. The Grid
	Ratio is equal to dXf/dX0. A Rg>1 focuses grid points on the droplet
	surface while a Rg<1 focuses grid points at the right boundary. A Rg of 1
	is a uniform grid.*/ 
	double Rg;
	/*Total number of points for grid:*/
	size_t npts;

	double gridOffset;

	UserGrid grid;
	double* uniformGrid;

	int dirichletInner,dirichletOuter;

	int nThreads;
	double clockStart;
	
	/*These arrays are used to compute dr/dt, which in turn is used to
	 * compute the flame speed S_u:*/
	double flamePosition[2];
	double flameTime[2];
	size_t nTimeSteps;

	/*Following arrays are used to compute the characteristic time scale of
	species*/
	//double* wdot_mole ; 
	//double* wdot_mass ; 
	double* time_scale ; 
	//double* MW;
	FILE* timescaleOutput;

    /*Following parameters are used for REGRID function*/
    double PCAD;
    double RGTC;
    int JJRG;
    double deltaT;

    FILE* rxnROPOutput;
    FILE* spROPOutput;


} *UserData;
UserData allocateUserData(FILE *input);
void setSaneDefaults(UserData data);
void freeUserData(UserData data);
#endif

