#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>


//put additional include files here
#include <ocStats.h>
#include <stats_utils.h>
#include <ReportTree.h>
#include <GetNBox.h>
#include <report_utils.h>
#include <event_utils.h>
#include <control.h>
#include <o8dlg.h>
//put your own support static functions here

#define IDST_SA_ANASTATS  0x00000010
#define	IDE_WBL_PLOT	0x11100010		

/*
static void get_summary_stats(SASummary psSASummary, vector &vStats)
{
	vStats.SetSize(4);
	vStats[0] = psSASummary.Total;
	vStats[1] = psSASummary.Events;
	vStats[2] = psSASummary.NumCen;
	vStats[3] = round(psSASummary.PerCen,4);

}
*/

static void get_analysis_stats(SAParaEstim *psSAParaEstim, int ii, vector &vStats)
{
	vStats.SetSize(5);
	vStats[0] = (psSAParaEstim[ii].DOF == 0) ? NANUM : psSAParaEstim[ii].DOF;
	vStats[1] = round(psSAParaEstim[ii].ParaEst,4);
	vStats[2] = round(psSAParaEstim[ii].SE,4);
	vStats[3] = round(psSAParaEstim[ii].LCL,4);
	vStats[4] = round(psSAParaEstim[ii].UCL,4);

}

static void	wb_update_report_tree(ReportTree& outRT, double dCriterion, SAParaEstim *psSAParaEstim, double dConfLev, int nErr)
{
	
		
	int ii;
	
	//////////////////////////////////////////////////////////////////
	// Analysis Statistics
	//////////////////////////////////////////////////////////////////
    
	ReportTable rtAnalysis = outRT.CreateTable("Analysis", _L("Analysis of parameter estimates"), IDST_SA_ANASTATS);
	
	vector<string> vstrParamColLabels(5);
	string strConf = ftoa(dConfLev);
	
	//vstrParamColLabels[0] = _L("Parameter");
	vstrParamColLabels[0] = _L("DF");
	vstrParamColLabels[1] = _L("Estimate");
	vstrParamColLabels[2] = _L("Standard Error");
	vstrParamColLabels[3] = strConf + "% LCL";
	vstrParamColLabels[4] = strConf + "% UCL";

	vector<string> vstrParamRowLabels(4);
	vstrParamRowLabels[0] = _L("Intercept");
	vstrParamRowLabels[1] = _L("Scale");
	vstrParamRowLabels[2] = _L("Weibull Scale");
	vstrParamRowLabels[3] = _L("Weibull Shape");
	
	vector vANAStats;
	
	vector<string> vstrColTagName, vstrRowTagName;
	string strColTagName = WEIBULL_PARAM_ESTIM;
	strColTagName.GetTokens(vstrColTagName, '|');
	string strRowTagName =  WEIBULL_PARAMS;
	strRowTagName.GetTokens(vstrRowTagName, '|');
	
	for(ii = 0; ii < 4; ii++)
	{
	    get_analysis_stats(psSAParaEstim, ii, vANAStats);
	    rtAnalysis.AddRow(vstrRowTagName[ii], vANAStats, vstrParamRowLabels[ii], vstrParamColLabels, vstrColTagName, make_one_set_ID(IDST_SA_ANASTATS, ii));		
		///Sophy 3/30/2009 QA80-13352 SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
		TreeNode trRow = rtAnalysis.GetNode(vstrRowTagName[ii]);
		if ( trRow )
		{
			tree_set_attribute_to_all_nodes(trRow, STR_COL_DESIGNATION_ATTRIB, (string)OKDATAOBJ_DESIGNATION_Y);
			if ( trRow.SE )
				trRow.SE.SetAttribute(STR_COL_DESIGNATION_ATTRIB, OKDATAOBJ_DESIGNATION_ERROR);
		}
		///end SUPPORT_SPECIFY_COLUMN_DESIGNATIONS_IN_REPORT_TABLES
	}
	
	string strFootNote2;
	string strErr;
	if (nErr == 2051 || nErr == 2004)
		strErr = _L("Fit did not converage");
	if (nErr == 2049)
		strErr = _L("Unable to calculate initial values");
	if (nErr == 2053)
		strErr = _L("All observations are censored, there are no exact observations");

	strFootNote2 = (nErr == STATS_NO_ERROR) ? _L("\\+(1)Log-Likelihood=") + ftoa(dCriterion) : strErr;
	TreeNode trFooter2 = tree_check_get_node(rtAnalysis, "Footer", IDE_FOOTNOTE_BEGIN, TREE_Footnote, "1"); // just need the TREE_Footnote attribute, value does not matter, so 1 is good
	trFooter2.strVal = strFootNote2;
}

static int wblfit_check_input(TreeNode& trGetN)
{
	int nErr = sa_check_data(trGetN.irng, SA_NONE);
	if (nErr == CER_NO_ERROR)
		nErr = check_valid_censoring(trGetN);
	
	if (!check_conf_level(trGetN.conf) && CER_NO_ERROR == nErr)
	{
		nErr = CER_INVALID_CONF_LEV;		
	}
	
	return nErr;
}


void weibullfit(const Range& irng, const vector& censor, const double& conf, ReportTree& rt)
{
	
	int nRet = sa_check_data(irng, SA_NONE);
	if (CER_NO_ERROR != nRet)
		XF_THROW(nRet);
	
	 int nMissing = 0;
	 SASummary psSASummary;	
	 SAParaEstim psSAParaEstim[4];	 
	 double dCriterion;
	 int  nSizeParaEstim=4;
	
	 vector vTime, vCensor;
	 irng.GetData(vTime, 0);
	 irng.GetData(vCensor, 1);
	 		
	 nRet = trim_nanum_sa(&nMissing, vTime, vCensor, NULL, NULL, true);
	 if(nRet != OE_NOERROR)
	      XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
	 
	 int nTime=vTime.GetSize();
	 int nCensor=vCensor.GetSize();
	 int nCensored=censor.GetSize();
	 
	double dConfLevel = conf / 100;	  
	 nRet = ocmath_surviv_weibull_simple(vTime,
		                                 nTime,
								         vCensor,
							             nCensor, 
								         censor, 
								         nCensored, 
								         dConfLevel,
								         &dCriterion,
								         &psSASummary,
								         psSAParaEstim,
								         nSizeParaEstim);
								     
	 if(nRet != OE_NOERROR && nRet != 2051 && nRet != 2049 && nRet != 2053 && nRet != 2004)
	 	XF_THROW_EX(CER_UNKNOWN_ERROR_EX, nRet);
	 
	 //construct the report tree
	 LPCSTR lpsczLabel = _L("WeiBull");
	 report_tree_create(rt, lpsczLabel, "irng");
	 rt_add_sa_summary(rt, psSASummary, censor);
	     
	 wb_update_report_tree(rt, dCriterion, psSAParaEstim, conf, nRet);
	 
	 
}

//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int weibullfit_event1(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	if( xf_is_extended_event(nEventID) )
		return weibullfit_event1_ex(trGetN, nRow, nEventID, dwEnables, lpcszNodeName, DynaCntrlContainer, strAux, strErrMsg);
	DECLARE_BUTTON_ENABLES
	
	TreeNode trRange = trGetN.irng;
	TreeNode trCensor = trGetN.censor;
	if (trRange && trCensor)
		set_censor_list(trRange, trCensor);
			
	int nErr = wblfit_check_input(trGetN);	
	if (CER_NO_ERROR != nErr)
	{
		bOKEnable = false;
		strErrMsg = nErr;
	}
	
	return true;
	

}

int weibullfit_make_tree(TreeNode& tr, LPCSTR lpcszVarName)
{
	
	return false;
	
}
//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void weibullfit_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{
	
	//------ fisher 11/16/07 ADD_MAP_ID_TO_CHM
	if(is_use_origin_chm())
		trGetN.SetAttribute(STR_HELPID_ATTRIB, IDD_XF_weibullfit);
	
	if ( (dwCntrl&LTXF_THEME_USED) && nGetNDialog <= 0 )
	{
		if ( CER_NO_ERROR != wblfit_check_input(trGetN) )
			nRet = XFEVT_PROCEED_WITH_DLG;
	}
	
}
//nEventID < 0 on event, like GETNE_ON_INIT, GETNE_ON_OK etc, >0 on change from control
//return 0 to do nothing, return PEVENT_GETN_RET_TO_CLOSE to close dialog
//dwEnables = bOKEnable, bBTN1Enable, bBTN2Enable, bBTN3Enable, , can set to false to disable OK/Apply buttons
//lpcszNodeName = the trGetN TreeNode tag name that generates the event, or is  if GETNE_ON_OK etc
//strAux = optional string for XF Wizard Bar, like DLG_NEED_CHANGE_GRID etc, it will be invalid if from internal node value change event
//strErrMsg = allowing messages to be shown
int weibullfit_event1_ex(TreeNode& trGetN, int nRow, int nEventID, DWORD& dwEnables, LPCSTR lpcszNodeName, WndContainer& DynaCntrlContainer, string& strAux, string& strErrMsg)
{
	return false;
}
