#ifndef MBASE_INCLUDED
#define MBASE_INCLUDED

#include <database.h>
#include <maximize.h>

enum
{   Y_VAR, X_VAR
};
enum
{   MS_NONE, MS_DATA, MS_PARAMS, MS_ESTIMATED, MS_EST_FAILED
};
enum
{	// NB: these are matched in dlgitems.h 
	CTL_LABEL,		CTL_GROUP,		CTL_SUBGROUP,
	CTL_CHECK,
	CTL_INT, 		CTL_INTRANGE,	CTL_RADIO, 	CTL_RADIOBOX,	CTL_SELECT,
	CTL_DOUBLE,		CTL_DATE,
	CTL_STRING,		CTL_EDITOR,		CTL_FILE,	CTL_FILESAVE,	CTL_FOLDER,
	CTL_MATRIX,		CTL_STRMAT,		CTL_CHECKLIST,
	CTL_SAMPLEINDEX,CTL_SAMPLERANGE,CTL_DATEINDEX,CTL_DATERANGE,
	CTL_ENABLER,	CTL_DISABLER,
	CTL_LISTBOX = 100	// not stored as an item, but in the item list
};

enum
{	STATUS_ENDOGENOUS 	=   1,	// default: apply to first var at lag0
	STATUS_SPECIAL		=   2,	// default: apply to special variables
	STATUS_MULTIVARIATE	=   4,	// default: apply to all non-special vars at lag0
	STATUS_TRANSFORM	=   8,	// is a transformation
	STATUS_GROUP		=  16,	// is a group (each var is in only one group)
	STATUS_ONEONLY		=  32,	// only one var can have this flag
	STATUS_GROUP2		=  64,	// is 2nd group (each var is in only in one of each group)
	STATUS_MULTIPLE		= 128, 	// multiple instances of a variable are allowed
	STATUS_DEFAULT		= 256,	// is default: no status letter displayed
	STATUS_GROUP3		= 512,	// is 3rd group (each var is in only in one of each group)
	STATUS_GROUP4		=1024,	// is 4th group (each var is in only in one of each group)
	STATUS_GROUP5		=2048   // is 5th group (each var is in only in one of each group)
}
enum
{	SPECIAL_CONSTANT	=  0,
	SPECIAL_TREND		=  1,
	SPECIAL_SEASONAL	=  2,
	SPECIAL_CSEASON		=  3
}

/*------------------------- Modelbase : Database ---------------------------*/
class Modelbase : Database
{
    decl m_iMethod;						     /* specifies estimation method */
    decl m_fPrint;               /* TRUE if output desired after estimation */
	decl m_cTforc;
	decl m_bRecursive, m_cTinit;/*	on/off and inits of recursive estimation */
	decl m_fMaxManual;		  /* FALSE (default): do automatic maximization */
	decl m_dForcCrit;	  /* default critical value for forecast error bars */

    decl m_cPar, m_cParFree; /* total number of parameters, no of free pars */
    decl m_vPar;			      				 /* parameter vector [q][1] */
    decl m_vIsFreePar;/* has a 1 for free and 0 for fixed parameters [q][1] */
    decl m_vFixedPar;	      /* has a the value of fixed parameters [q][1] */
	decl m_vIdxFreePar;		 /* has a the indices of free parameters [p][1] */

    decl m_iT1est, m_iT2est;                           /* estimation sample */
    decl m_cT;                                    /* number of observations */
    decl m_cY, m_cYlag;        /* number of dependent variables, lagged Y's */
    decl m_cX;                    /* number of additive regressors (if any) */
	decl m_mY;        /* data vector [cT][1], standardized after estimation */
    decl m_mX;                 /* additive regressor data vector [cT][m_cX] */

	decl m_iModelStatus;			            /* one of the MS_ constants */
    decl m_iResult;             /* >= 0: return code from MaxBFGS/MaxNewton */

	decl m_iDeterministic;  /* value used in ReceiveData to create det.vars */
	decl m_mCovar, m_mCovarRobust;  /* var-covar of estimated coeffs [p][p] */
    decl m_dLogLik;                                       /* log-likelihood */

	static decl sm_iOxCode;		  /* unique object identifier for GetOxCode */
	
    Modelbase();                                             /* constructor */
	Init();
	// database overrides
	Select(const iGroup, const aSel);
	DeSelect();
	SetSample(const iYear1, const iPeriod1, const iYear2, const iPeriod2);
	SetSelSample(const iYear1, const iPeriod1, const iYear2, const iPeriod2);
	SetSelDates(const iYear1, const iMonth1, const iDay1,
		const iYear2, const iMonth2, const iDay2);
	SetSelSampleByDates(const dDate1, const dDate2);
	Grow(const cTadd);
	// general
	virtual GetPackageName();		   			 /* returns name of package */
	virtual GetPackageVersion();			  /* returns version of package */
	virtual IsUnivariate();		  /* returns TRUE if only one Y_VAR allowed */
	GetModelStatus();					    /* returns MS_.... model status */
	SetModelStatus(const iModelStatus);
	virtual ClearModel();					/* sets model status to MS_NONE */
	virtual ClearEstimation();	 /* removes results fom previous estimation */ 
    SetPrint(fPrint);                             /* set value for m_fPrint */
	GetResult();						   /* returns the estimation result */
	SetResult(const iResult);			      /* sets the estimation result */
	virtual SetRecursive(const bSet, const cInit); /* sets recursive params */
												/* sets the no of forecasts */
	virtual SetForecasts(const cForc, const bIsLessForecasts);
	virtual SetMethod(const iMethod);		  /* sets the estimation method */
	GetMethod();							  /* gets the estimation method */
	virtual GetMethodLabel();
	virtual GetModelLabel();
	GetLogLik();							  /* returns the log-likelihood */
	virtual GetResiduals();				   /* returns T x n residual matrix */
	virtual GetResVar();					   /* returns residual variance */
	virtual GetcT();			     /* actual sample size to use in output */
	virtual GetcDfLoss();/* degrees of freedom lost (for tailt,AIC,progress)*/
	DbDrawTMatrix(const iArea, const mYt, const asY, const iT1, ...);
	
	// parameter related
	SetParCount(const cPar, ...);  /* sets no of params q (including fixed) */
	GetParCount();	    /* returns number of parameters q (including fixed) */
	GetFreeParCount();				 /* returns number of free parameters p */
	GetFreeParNames();				   /* gets names of free parameters [p] */
	FixPar(const iP, const dFix);  			  /* fixes parameter iP to dFix */
	FreePar(const iP);						  	 	  /* frees parameter iP */
	GetParStatus();           /* ret: { m_cPar, m_vIsFreePar, m_vFixedPar } */
	GetFreePar();				  /* gets the vector of free parameters [p] */
	MapParToFree(const vPar);
	SetFreePar(const vParFree);				    /* sets the free parameters */
	ResetFixedPar();		   /* copy fixed par from m_vFixedPar to m_vPar */
	GetPar();					   /* gets the vector of all parameters [q] */
	SetPar(const vPar);					  /* sets the full parameter vector */
	virtual GetParNames(); 			    /* gets names of all parameters [q] */
	virtual GetParTypes();/* gets par types (1 or 2 letters) [q], default 0 */
	virtual GetLongRunNames();			  /* returns 0 or names of long-run */
	virtual GetLongRunInfo();	  /* returns 0 or names/par/var of long-run */

	// covariance
	GetStdErr();		   /* returns the std.errors (0 for fixed pars) [q] */
	GetStdErrRobust();			    /* returns <> or robust standard errors */
	GetCovar();						     /* returns p x p covariance matrix */
	GetCovarRobust();	    /* returns <> or p x p robust covariance matrix */
	// move up in model status
	virtual SetStartPar(const vParFree);	    /* sets the starting values */
	virtual InitData();							  /* gets the data: Y,X,Z,W */
	virtual InitPar();					/* initializes the parameter values */
	virtual DoEstimation(vPar);
	virtual Estimate();
	// post estimation
	virtual Covar();									   /* sets m_mCovar */
	virtual Output();									   /* prints output */
	OutputHeader(const sTitle);				  /* returns TRUE to print rest */
	OutputPar();							  /* prints parameter estimates */
	OutputLogLik();							  /* prints loglik, aic, var(y) */
	OutputMax(const sMethod, const iResult, const vPstart, const bNumerical);
	GetForecastData(const iGroup, const mnLag, const mxLag, const cTforc, ...);
	// evaluation
	static PrintTestVal(const dTest, const cR, const cTdf, const sLabel);
	virtual TestRestrictions(mR, ...);

	// OxPack related
	ForceYlag(const iYgroup);
	virtual Buffering(const bBufferOn);
	virtual SendMenu(const sMenu);
	virtual SendVarStatus();
	virtual SendSpecials();
	virtual SendFunctions();
	virtual ReceiveData();
	virtual ReceiveModel();
	virtual ReceiveMenuChoice(const sDialog);
	virtual GetModelSettings();
	virtual SetModelSettings(const aValues);
	virtual LoadOptions();
	virtual SaveOptions();
	// actual oxpack dialogs
	virtual DoFormulateDlg(const iLagMode, ...);
	virtual DoSettingsDlg();
	virtual DoEstimateDlg(const iFirstMethod, const cMethods, const sMethods,
		const bForcAllowed, const bRecAllowed, const bMaxDlgAllowed);
	virtual DoOption(const sOpt, const val);
	virtual DoOptionsDlg(const aMoreOptions);
	// OxPack batch related:
	virtual BatchMethod(const sMethod);
	virtual Batch(const sBatch, ...);
	GetBatchEquation(const sY, const asX);
	virtual GetBatchModel();
	virtual GetBatchModelSettings();
	virtual GetBatchEstimate();
	virtual SendVarStatusLabels(); /* the ?_VAR constants as array of strings */
	virtual GetOxModel(const sObj);
	virtual GetOxModelSettings(const sObj);
	virtual GetOxEstimate(const sObj);
	virtual GetOxCode();
};
/*----------------------- END Modelbase : Database -------------------------*/

ResCompileParam(const sResCode, const cP, const asMsg, ...);
ResMapToUnConstrained(const vRes);
ResMapToConstrained(const vUnRes);
ResAnalyticalJacobian(const vRes);
ResIsRestricted();
ResCompileTest(const sResTestCode, const cP, const asMsg);
ResMapTestRestrictions(const vP);
ResTestAnalyticalJacobian(const vP);

#endif /* MBASE_INCLUDED */
