#pragma once
#include "mexCellItem.h"
#include "PartwiseLinFunc.h"

enum mexCommand {
	enum_unknown = 0,
	enum_foc_int = 1,
	enum_foc_int_terminal_nk = 2,
	enum_solve_loop_E1_0 = 3,
	enum_solve_loop_E1_1 = 4,
	enum_solve_loop_E1_0_nk = 5,
	enum_solve_loop_E1_1_nk = 6,
	enum_foc_calc_single = 99
};

enum printLevel {
	enum_printLevel_unknown = 0,
	enum_printLevel_numeric = 1,
	enum_printLevel_equation = 2
};

typedef struct param_index_mapping {
	int command;
	int A_grid;       //A_grid
	int lw_grid_1;    //lw_grid_1
	int lw_grid_2;    //lw_grid_2
	int u1_grid;      //u1_grid
	int u2_grid;      //u2_grid
	int param_struct; //parameters
	int tt;           //tt
	int wpoints;      //wpoints
	int upoints;      //upoints
	int i;            //i
	int kt;           //kt 
	int EUFUNC;       //EUFUNC
	int EVFUNC;       //EVFUNC
	int L1_star_f;    //L1_star_f
	int T1_star_f;    //T1_star_f
	int L2_star_f;    //L2_star_f
	int A_star_f;     //A_star_f

	int j;			  //L1_star_f
	int k;			  //T1_star_f
	int l;			  //L2_star_f
	int m;			  //A_star_f

	int printLevel;   //L1_star_f
} IndexMap;

class OptimizationParams
{
private:
	int itemCount;
	mexCellItem ** params;
	mexCommand command;
	printLevel print_level;
	IndexMap indexMap;

	void SetCommand(const char * commandString);

public:

	int GetCount();
	mexCellItem* GetParamCell(int i);
	void SetParamsWithMap(int nrhs, const mxArray * prhs[], IndexMap map);
	void SetParams(int nrhs, const mxArray * prhs[]);

	void SetParamsWithCommand(int nrhs, const mxArray * prhs[], int commandIndex = 0);
	//Getters:

	mexCommand GetCommand();

	//Grids:
	double Get_A_grid_val(int i);
	double Get_lw_grid_1_val(int j, int tt);
	double Get_lw_grid_2_val(int k, int tt);
	double Get_u1_grid_val(int l, int tt);
	double Get_u2_grid_val(int m, int tt); 

	double Get_L1_star_f_val(int j, int k, int l, int m);
	double Get_T1_star_f_val(int j, int k, int l, int m);
	double Get_L2_star_f_val(int j, int k, int l, int m);
	double Get_A_star_f_val(int j, int k, int l, int m);

	//From Param Struct.
	double GetStructParamDouble(const char* fieldName);
	mexCellItem * GetStructParamCell(const char * fieldName);
	int GetStructParamInt(const char* fieldName);

	//Other values:
	int Get_kt();
	int Get_tt();
	int Get_wpoints();
	int Get_upoints();
	int Get_i();
	int Get_j();
	int Get_k();
	int Get_l();
	int Get_m();
	printLevel Get_print_level();

	//Functions:
	
	PartwiseLinFunc * OptimizationParams::Get_EUfunc(int j, int k, bool nullIfUnset = false);
	PartwiseLinFunc * OptimizationParams::Get_EVfunc(int j, int k, bool nullIfUnset = false);

	OptimizationParams();
	~OptimizationParams();
};

