//LABEL(History, EN) Contribution base, work time and earnings history

/* NOTE(History, EN)
	This module traces earnings, contributable earnings, time worked, and pensions and
	creates a history table by calendar year which is updated each end of the year.
*/

classification HISTORY_COLUMNS																//EN Columns of history table
{
	HC_AGE,																					//EN Age at end of year
	HC_YEAR,																				//EN Year	
	HC_TIME_WORKED,																			//EN Time worked
	HC_TIME_UNEMPLOYED,																		//EN Time unemployed
	HC_TOTAL_TIME_WORKED,																	//EN Total time worked
	HC_BC,																					//EN Contribution base
	HC_EARNINGS,																			//EN Earnings
	HC_CONTRIBUTION_GROUP,																	//EN Contribution group
	HC_PENSION,																				//EN Pension
	HC_NET_EDUCATION,                                                                       //EN Received from education programme
	HC_NET_PENSION,                                                                          //EN Received from pension programme
	HC_LIFECYCLE_INCOME                                                                    //EN Lifecycle income
};

actor Person
{
	// History table
	double	history[YEAR_HISTORY][HISTORY_COLUMNS];											//EN History of earnings etc.	
	void	InitHistory(); hook InitHistory, Start;											//EN Initialize history
	void	HistoryUpdate();																//EN Update of history each end of year and each midmonth

	// Tracking of time worked in current year
	logical	is_working = ( current_salary > 0 ) ? TRUE : FALSE;								//EN Person is working ( or unemployed with positive salary )
	
	// Tracking of time worked in current year
	logical	is_unemployed = ( last_wage_before_unemployed > 0 ) ? TRUE : FALSE;								//EN Person is unemployed with positive salary


	//EN Time worked this year
	double	time_worked_this_year = active_spell_weighted_duration(year_spell, TRUE, is_working);	

	//EN Time worked this year
	double	time_is_unemployed_this_year = active_spell_weighted_duration(year_spell, TRUE, is_unemployed);				

	// Tracking of contribution base this year
	double	total_contribution_base_this_year = active_spell_weighted_duration(year_spell, TRUE, current_contribution_base);

	// Tracking of salary this year
	double	total_salary_this_year = active_spell_weighted_duration(year_spell, TRUE, current_salary);												//EN Total salary this year	

	// Tracking of pension this year
	double	total_pension_this_year = active_spell_weighted_duration(year_spell, TRUE, current_pension);												//EN Total pension this year	

	// Tracking of ed this year
	double	total_lceducation_this_year = active_spell_weighted_duration(year_spell, TRUE, current_total_education);	

	// Tracking of pension this year
	double	total_lcpension_this_year = active_spell_weighted_duration(year_spell, TRUE, current_total_pensions);	

	// Tracking of income this year
	double	total_lcincome_this_year = active_spell_weighted_duration(year_spell, TRUE, current_total_income);	
};

void Person::InitHistory()
{
	integer nYear, nColumn;
	for (nYear = 0; nYear < SIZE(YEAR_HISTORY); nYear++) 
		for (nColumn = 0; nColumn < SIZE(HISTORY_COLUMNS); nColumn++) history[nYear][nColumn] = 0.0;
}

void Person::HistoryUpdate()
{
	if ( calendar_year >= MIN(YEAR_HISTORY) && calendar_year <= MAX(YEAR_HISTORY) )
	{
		// Trivial
		history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_YEAR] = calendar_year;
		history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_AGE] = integer_age;
		history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_CONTRIBUTION_GROUP] = contribution_group;
		history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_NET_EDUCATION]		= total_lceducation_this_year;
		history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_NET_PENSION]			= total_lcpension_this_year;
		history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_LIFECYCLE_INCOME]		= total_lcincome_this_year;
		
		// Historic data
		if ( calendar_year == 1992 ) history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TOTAL_TIME_WORKED] = past15_time_before;
		if ( calendar_year > 1992 && calendar_year < 2008 ) 
		{
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TIME_WORKED] = past15_time_worked[2007-calendar_year];
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TOTAL_TIME_WORKED] = history[RANGE_POS(YEAR_HISTORY,calendar_year) - 1][HC_TOTAL_TIME_WORKED] + history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TIME_WORKED];
		}
		// $$$ refining unemployemnt
		if ( calendar_year > 2001 && calendar_year < 2008 ) 
		{
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TIME_UNEMPLOYED] = past6_time_unemployed[2007-calendar_year];
		}
		if ( calendar_year >= 1988 && calendar_year < 2008 ) 
		{
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] = current_contribution_base;
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_EARNINGS]	= current_salary;
			if ( calendar_year == 2007 ) history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_PENSION] = pension_2007;
		}

		// Simulated data
		if ( calendar_year >= 2008 ) 
		{
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TIME_WORKED]			= time_worked_this_year         / time_lived_this_year;
			// $$$ refining unemployemnt
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TIME_UNEMPLOYED]		= time_is_unemployed_this_year  / time_lived_this_year;
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TOTAL_TIME_WORKED]	= history[RANGE_POS(YEAR_HISTORY,calendar_year) - 1][HC_TOTAL_TIME_WORKED] + history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TIME_WORKED];
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC]					= total_contribution_base_this_year / time_lived_this_year;
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_EARNINGS]				= total_salary_this_year;
			history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_PENSION]				= total_pension_this_year;
			//history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_NET_EDUCATION]		= total_lceducation_this_year;
			//history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_NET_PENSION]			= total_lcpension_this_year;
			//history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_LIFECYCLE_INCOME]		= total_lcincome_this_year;
		}
		
		// Replace low and/or zero contribution bases (by selected policy option)
		if ( history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_PENSION] == 0 )  //not retired yet
		{
			double dMinBase =  MinimumContributionBase[RANGE_POS(YEAR_HISTORY,calendar_year)];
			if ( OptionsMinBC == OM_MIN_INCL0 && history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] < dMinBase ) history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] = dMinBase;
			else if ( OptionsMinBC == OM_MIN_EXCL0 && history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] < dMinBase && history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] > 0 ) history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] = dMinBase;
			else if ( OptionsMinBC == OM_MIN_ONLY0 && history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] == 0 ) history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] = dMinBase;
		}
		
		// Expected contribitions in next 11 years
		if ( history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_PENSION] == 0 )  //not retired yet
		{
			int i;
			for ( i = 1; i <= 11; i++ )
			{
				history[RANGE_POS(YEAR_HISTORY,calendar_year + i )][HC_BC]	= history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_BC] 
				  * WageIndex[RANGE_POS(SIM_YEAR, calendar_year + i)] / WageIndex[RANGE_POS(SIM_YEAR, calendar_year)];
				history[RANGE_POS(YEAR_HISTORY,calendar_year + i)][HC_TIME_WORKED]	= history[RANGE_POS(YEAR_HISTORY,calendar_year)][HC_TIME_WORKED];
				history[RANGE_POS(YEAR_HISTORY,calendar_year + i)][HC_TOTAL_TIME_WORKED] = history[RANGE_POS(YEAR_HISTORY,calendar_year + i - 1)][HC_TOTAL_TIME_WORKED] + history[RANGE_POS(YEAR_HISTORY,calendar_year + i)][HC_TIME_WORKED];
				// TODO Note that if unemployed and is_working we should put 0 time and BC after the 1.5 years 
				// We can add a control in the future if necessary.
			}
		}
		
	}
}

