#include <iostream>
#include <cstdlib>
#include <cmath>
#include "snaps.h"
#include "mcntl.h"
#include "mfile_open.h"
#include "mecon.h"

double round( double a , int n );

void econ()
{
	double buffer[100];
	int data_number;
	int nendo;
	int counter;
	int nenrei;
	int c_nendo;
	double shinsai_ruiseki_kaiteiritu[SAISHUNENDO - ECON_SHONENDO + 1];
	double previous_buffer;
	double max_cut_rate[SAISHUNENDO - ECON_SHONENDO + 1];
	double base_up_real[SAISHUNENDO - ECON_SHONENDO + 1];
	double y[SAISHUNENDO - ECON_SHONENDO + 1];
	
	previous_buffer = -1000.;
	
	while( ( read_data( buffer , fp_in[KEIZAI] , &data_number ) != EOF ) && ( buffer[0] > previous_buffer ) )
	{
		nendo = (int)(buffer[0]) + 2000;
		cpi_up[nendo - ECON_SHONENDO] = 1. + buffer[6] / 100.;
		interest_rate[nendo - ECON_SHONENDO] = 1. + buffer[2] / 100.;
		base_up[nendo - ECON_SHONENDO] = 1. + buffer[4] / 100.;
		previous_buffer = buffer[0];
	}
	
	for( counter = nendo + 1 ; counter <= SAISHUNENDO ; counter++ )
	{
		cpi_up[counter - ECON_SHONENDO] = cpi_up[nendo - ECON_SHONENDO];
		base_up[counter - ECON_SHONENDO] = base_up[nendo - ECON_SHONENDO];
		interest_rate[counter - ECON_SHONENDO] = interest_rate[nendo - ECON_SHONENDO];
	}
	
	for( nendo = ECON_SHONENDO ; nendo <= SAISHUNENDO ; nendo++ )
	{
		base_up_real[nendo - ECON_SHONENDO] = base_up[nendo - ECON_SHONENDO] / cpi_up[nendo - ECON_SHONENDO];
	}
	
	base_up_k[2005 - ECON_SHONENDO] = 1.;
	for( nendo = 2006 ; nendo <= 2007 ; nendo++ )
	{
		base_up_k[nendo - ECON_SHONENDO] = cpi_up[nendo - 2 - ECON_SHONENDO];
	}
	
	for( nendo = 2008 ; nendo <= MARUME_NENDO ; nendo++ )
	{
		if( nendo == 2018)
		{
			y[nendo - ECON_SHONENDO] = 0.992;
			base_up_k[nendo - ECON_SHONENDO] = round( cpi_up[nendo - 2 - ECON_SHONENDO] * y[nendo - ECON_SHONENDO] , 3 );
		}
		else
		{
			y[nendo - ECON_SHONENDO]
			 = round( pow( base_up_real[nendo - 5 - ECON_SHONENDO] * base_up_real[nendo - 4 - ECON_SHONENDO] * base_up_real[nendo - 3 - ECON_SHONENDO] , 1. / 3. ) , 3 );
			base_up_k[nendo - ECON_SHONENDO] = round( cpi_up[nendo - 2 - ECON_SHONENDO] * y[nendo - ECON_SHONENDO] , 3 );
		}
	}
	
	for( nendo = MARUME_NENDO + 1 ; nendo <= SAISHUNENDO ; nendo++ )
	{
		y[nendo - ECON_SHONENDO]
		 = pow( base_up_real[nendo - 5 - ECON_SHONENDO] * base_up_real[nendo - 4 - ECON_SHONENDO] * base_up_real[nendo - 3 - ECON_SHONENDO] , 1. / 3. );
		base_up_k[nendo - ECON_SHONENDO] = cpi_up[nendo - 2 - ECON_SHONENDO] * y[nendo - ECON_SHONENDO];
	}
	
	previous_buffer = -1000.;
	
	while( ( read_data( buffer, fp_in[KAITEI] , &data_number ) != EOF ) && ( buffer[0] > previous_buffer ) )
	{
		nendo = (int)(buffer[0]) + 2000;
		for( nenrei = 1 ; nenrei <= MAX_JUKYU - UNDER_67 + 1 ; nenrei++ )
		{
			kaiteiritu[nendo - ECON_SHONENDO][nenrei - 1] = buffer[nenrei];
		}
		previous_buffer = buffer[0];
	}
	
	if( kaiteiritu[2013 - ECON_SHONENDO][UNDER_67 - UNDER_67] > 0.990 )
	{
		printf( "2013(H25)年10月の特例解消幅が-1%より大きくないため、強制終了。( %f ) \n", kaiteiritu[2013 - ECON_SHONENDO][UNDER_67 - UNDER_67] );
		exit(1);
	}
	
	shinsai_ruiseki_kaiteiritu[KAKAKU_NENDO - ECON_SHONENDO] = 1.;
	
	for( nendo = KAKAKU_NENDO + 1 ; nendo <= MARUME_NENDO ; nendo++ )
	{
		shinsai_ruiseki_kaiteiritu[nendo - ECON_SHONENDO]
		 = round( shinsai_ruiseki_kaiteiritu[nendo - 1 - ECON_SHONENDO] * base_up_k[nendo - ECON_SHONENDO] , 3 );
	}
	
	for( nendo = MARUME_NENDO + 1 ; nendo <= SAISHUNENDO ; nendo++ )
	{
		shinsai_ruiseki_kaiteiritu[nendo - ECON_SHONENDO] = shinsai_ruiseki_kaiteiritu[nendo - 1 - ECON_SHONENDO] * base_up_k[nendo - ECON_SHONENDO];
	}
	
	for( nendo = KAKAKU_NENDO ; nendo <= SAISHUNENDO ; nendo++ )
	{
		kakaku[nendo - ECON_SHONENDO] = shinsai_ruiseki_kaiteiritu[nendo - ECON_SHONENDO] / shinsai_ruiseki_kaiteiritu[KAKAKU_NENDO - ECON_SHONENDO];
	}
	
	for( nendo = ECON_SHONENDO ; nendo < KAKAKU_NENDO ; nendo++ )
	{
		kakaku[nendo - ECON_SHONENDO] = 1.;
	}
	
		for( nendo = ECON_SHONENDO ; nendo <= SAISHUNENDO ; nendo++ )
		{
			max_cut_rate[nendo - ECON_SHONENDO] = 1.;
		}
		
		previous_buffer = -1000.;
		
		while( ( read_data( buffer , fp_in[TANNEN_CUT] , &data_number ) != EOF ) && ( buffer[0] > previous_buffer ) )
		{
			nendo = (int)(buffer[0]);
			if( nendo >= ECON_SHONENDO )
			{
				max_cut_rate[nendo - ECON_SHONENDO] = 1. + buffer[1];
			}
			previous_buffer = buffer[0];
		}
		for( counter = nendo ; counter <= SAISHUNENDO ; counter++ )
		{
			max_cut_rate[counter - ECON_SHONENDO] = max_cut_rate[nendo - ECON_SHONENDO];
		}
		
		if( Kurikoshim == 0 )
		{
			for( nendo = C_NENDO + 1 ; nendo <= SAISHUNENDO ; nendo++ )
			{
				for( nenrei = UNDER_67 ; nenrei <= MAX_JUKYU ; nenrei++ )
				{
					pre_cut[nendo - ECON_SHONENDO][nenrei - UNDER_67]
					= max( 1.0 , min( max_cut_rate[nendo - ECON_SHONENDO] , kaiteiritu[nendo - ECON_SHONENDO][nenrei - UNDER_67] ) );
				}
				for( nenrei = UNDER_67 ; nenrei <= MAX_JUKYU ; nenrei++ )
				{
					pre_cut[2015 - ECON_SHONENDO][nenrei - UNDER_67] = 1.;
					pre_cut[2019 - ECON_SHONENDO][nenrei - UNDER_67] = (1/0.995);
				}
	
			}
		}
		else if( Kurikoshim == 1 )
		{
			for( nendo = C_NENDO + 1 ; nendo <= SAISHUNENDO ; nendo++ )
			{
				if( nendo <= 2017 )
				{
					for( nenrei = UNDER_67 ; nenrei <= MAX_JUKYU ; nenrei++ )
					{
						pre_cut[nendo - ECON_SHONENDO][nenrei - UNDER_67]
						 = max( 1.0 , min( max_cut_rate[nendo - ECON_SHONENDO] , kaiteiritu[nendo - ECON_SHONENDO][nenrei - UNDER_67] ) );
					}
					for( nenrei = UNDER_67 ; nenrei <= MAX_JUKYU ; nenrei++ )
					{
						pre_cut[2015 - ECON_SHONENDO][nenrei - UNDER_67] = 1.;
					}
				}
				else if( nendo >= 2018 )
				{
					pre_cut[nendo - ECON_SHONENDO][UNDER_67 - UNDER_67]
					 = max( 1.0 , min( max_cut_rate[nendo - ECON_SHONENDO] / T[nendo - 1 - ECON_SHONENDO][UNDER_67 - UNDER_67]
					                 , kaiteiritu[nendo - ECON_SHONENDO][UNDER_67 - UNDER_67] ) );
					
					T[nendo - ECON_SHONENDO][UNDER_67 - UNDER_67]
					 = T[nendo - 1 - ECON_SHONENDO][UNDER_67 - UNDER_67] / max_cut_rate[nendo - ECON_SHONENDO]
					 * pre_cut[nendo - ECON_SHONENDO][UNDER_67 - UNDER_67] ;
						
					for( nenrei = UNDER_67 + 1 ; nenrei <= MAX_JUKYU ; nenrei++ )
					{
						pre_cut[nendo - ECON_SHONENDO][nenrei - UNDER_67]
						 = max( 1.0 , min( max_cut_rate[nendo - ECON_SHONENDO] / T[nendo - 1 - ECON_SHONENDO][nenrei - 1 - UNDER_67]
						                 , kaiteiritu[nendo - ECON_SHONENDO][nenrei - UNDER_67] ) );
							
						T[nendo - ECON_SHONENDO][nenrei - UNDER_67]
						 = T[nendo - 1 - ECON_SHONENDO][nenrei - 1 - UNDER_67] / max_cut_rate[nendo - ECON_SHONENDO]
						 * pre_cut[nendo - ECON_SHONENDO][nenrei - UNDER_67] ;
					}
					for( nenrei = UNDER_67 ; nenrei <= MAX_JUKYU ; nenrei++ )
					{
						pre_cut[2019 - ECON_SHONENDO][nenrei - UNDER_67] = (1/0.995);
						T[2019 - ECON_SHONENDO][nenrei - UNDER_67] = 1.0;
					}
				}
			}
		}
		
		if( D_MACRO == 1 )
		{
			for( nendo = D_M_NENDO ; nendo <= SAISHUNENDO ; nendo++ )
			{
					if(nendo == D_M_NENDO)
					{
					pre_cut[nendo - ECON_SHONENDO][UNDER_67 - UNDER_67] = max( 1.0 , max_cut_rate[nendo - ECON_SHONENDO] / T[nendo - 1 - ECON_SHONENDO][UNDER_67 - UNDER_67] );
					}
					else{
					pre_cut[nendo - ECON_SHONENDO][UNDER_67 - UNDER_67] = max( 1.0 , max_cut_rate[nendo - ECON_SHONENDO] );
					}

						for( nenrei = UNDER_67 + 1 ; nenrei <= MAX_JUKYU ; nenrei++ )
						{
							if( nendo == D_M_NENDO)
							{
							pre_cut[nendo - ECON_SHONENDO][nenrei - UNDER_67] = max( 1.0 , max_cut_rate[nendo - ECON_SHONENDO] / T[nendo - 1 - ECON_SHONENDO][nenrei - 1 - UNDER_67] );
							}
							else{
							pre_cut[nendo - ECON_SHONENDO][nenrei - UNDER_67] = max( 1.0 , max_cut_rate[nendo - ECON_SHONENDO] );
							}
						}
			}
		}
		
		for( counter = C_NENDO + 1 ; counter <= SAISHUNENDO ; counter++ )
		{
			for( nendo = counter ; nendo <= SAISHUNENDO ; nendo++ )
			{
				for( nenrei = UNDER_63 ; nenrei <= MAX_JUKYU ; nenrei++ )
				{
					for( c_nendo = counter ; c_nendo <= SAISHUNENDO ; c_nendo++ )
					{
						if( nenrei <= (int)( min( ( nendo + 67 - counter ) , MAX_JUKYU ) ) )
						{
							cut_ruiseki[c_nendo - ECON_SHONENDO][nendo - ECON_SHONENDO][nenrei - NENREI_SUM] /= pre_cut[counter - ECON_SHONENDO][UNDER_67 - UNDER_67];
						}
						else
						{
							cut_ruiseki[c_nendo - ECON_SHONENDO][nendo - ECON_SHONENDO][nenrei - NENREI_SUM]
							 /= pre_cut[counter - ECON_SHONENDO][nenrei - (int)min( ( nendo + 67 - counter ) , MAX_JUKYU ) ];
						}
					}
				}
			}
		}
	
}

double round( double a , int n )
{
 double  b;
 char    buf[256] = {'\0'};
 char    *p;
	
	sprintf( buf , "%.*f" , n , a );
	b = strtod( buf , &p );
	
	return b;
}

