#include "ssc.h"
#include "config.h"
//#include "DJ_SpeedPiV.h"
#include "SeamlessBufferManagement.h"
#include "ssc_macro.h"
// SBM_GAME_MODE±¸°£°ú SBM_NORMAL_MODE±¸°£À» °ãÄ¡°Ô ÇÑ´Ù.


/*
#define SBM_NORMAL_MODE_LOW 7    // 140ms
#define SBM_NORMAL_MODE_BASE 15  // 300ms
#define SBM_NORMAL_MODE_HIGH 20  // 400ms

#define SBM_GAME_MODE_LOW  2   // 40ms
#define SBM_GAME_MODE_BASE 5   // 100ms  
#define SBM_GAME_MODE_HIGH 8   // 160ms
*/







#ifdef ENABLE_VSP
//extern float set_vsp_speed;
extern int set_vsp_speed;
#endif


short prev_mode_info;
short sbm_current_state;  // 0 : Á¤»ó ¼Óµµ, 1: ´À¸²¿¡¼­ ±âÁØÁ¡À¸·Î ¿À´ÂÁß, 2: ºü¸§¿¡¼­ ±âÁØÁ¡À¸·Î ¿À´ÂÁß. 
                    
#define GAME_MODE_TARGET_BUFFER_LEVEL 5
#define NORMAL_MODE_TARGET_BUFFER_LEVEL 15

#ifdef ENABLE_VSP
int ssc_SBM_speed_setPar(int speed)
{

	if(speed<55000 || speed>75000)
	{
		return -10;
	}



	if(set_vsp_speed != speed)
	{
		SBM_SetPar(speed);
		set_vsp_speed = speed;
	}

	return 1;
}


int ssc_SBM_speed_getPar()
{
	return set_vsp_speed;
}


int ssc_SBM_getstatus()
{
	return sbm_current_state;
}

#endif



#if 0
void set_sub_apply(int current_buffer_level,short th_a, short th_b)
{
	if(current_buffer_level<th_a)
	{
		// ´À¸®°Ô play
		ssc_SBM_speed_setPar( SBM_SLOW_SPEED );
		sbm_current_state = 1;
	}
	else if(current_buffer_level>th_b)
	{
		// ºü¸£°Ô play
		ssc_SBM_speed_setPar( SBM_FAST_SPEED );
		sbm_current_state = 2;
	}
	else
	{
		// Á¤¼ÓÀ¸·Î play
		ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
		sbm_current_state = 0;
	}
}



int ssc_set_SBM_apply(int current_buffer_level, short mode_info)   // mode_info : Normal_mode : 0,  Game_mode : 1
{

	if(mode_info != prev_mode_info)
	{
		sbm_current_state = 0;  // mode°¡ ¹Ù²î¸é state´Â ÀÏ´Ü ÃÊÃ¢±âÀÇ Á¤¼Ó ¼Óµµ °³³äÀ¸·Î µ¹¾Æ¿È.
	}


	if(sbm_current_state == 0)   // ÀÌÀü¿¡ Á¤¼ÓÀ¸·Î Play ÇßÀ»°æ¿ì
	{
		if(mode_info == 0)
		{
	    	set_sub_apply(current_buffer_level,SBM_NORMAL_MODE_LOW,SBM_NORMAL_MODE_HIGH);
		}
		else if(mode_info == 1)
		{
			set_sub_apply(current_buffer_level,SBM_GAME_MODE_LOW,SBM_GAME_MODE_HIGH);
		}
		else
		{
			return -1;
		}

	}
	else if(sbm_current_state == 1) 
	{
		if(mode_info == 0)
		{
			set_sub_apply(current_buffer_level,SBM_NORMAL_MODE_BASE,SBM_NORMAL_MODE_HIGH);
		}
		else if(mode_info == 1)
		{
			set_sub_apply(current_buffer_level,SBM_GAME_MODE_BASE,SBM_GAME_MODE_HIGH);
		}
		else
		{
			return -2;
		}
	}
	else if(sbm_current_state == 2)
	{
		if(mode_info == 0)
		{
	 	    set_sub_apply(current_buffer_level,SBM_NORMAL_MODE_LOW,SBM_NORMAL_MODE_BASE);
		}
		else if(mode_info == 1)
		{
		    set_sub_apply(current_buffer_level,SBM_GAME_MODE_LOW,SBM_GAME_MODE_BASE);
		}
		else
		{
			return -3;
		}
	}

	prev_mode_info = mode_info;

	
	return 1;
}
#endif


// short sbm_current_state;  // 0 : Á¤»ó ¼Óµµ, 1: ´À¸²¿¡¼­ ±âÁØÁ¡À¸·Î ¿À´ÂÁß, 2: ºü¸§¿¡¼­ ±âÁØÁ¡À¸·Î ¿À´ÂÁß. 


//#define SBM_APPLY_SLOW_NUM 100    // Game Mode¿¡¼­ Normal Mode°¥¶§ slowÇØ¾ß ÇÏ´Â ±âÁØ frame °¹¼ö.
//#define SBM_APPLY_FAST_NUM 105    // Normal Mode¿¡¼­ Game Mode°¥¶§ fastÇØ¾ß ÇÏ´Â ±âÁØ frame °¹¼ö.


//short sbm_start_idx;   // ¹è°¨¼Ó Àç»ýÀÇ ½ÃÀÛÁöÁ¡. sbm_current_state°¡ 1 È¤Àº 2ÀÏ¶§¸¸ À¯È¿.
//short sbm_end_idx;    // ¹è°¨¼Ó Àç»ýÀÇ ³¡ÁöÁ¡. sbm_current_state°¡ 1 È¤Àº 2ÀÏ¶§¸¸ À¯È¿.
//short sbm_carry_idx;   //  sbm_current_state°¡ 1 È¤Àº 2ÀÏ¶§¸¸ À¯È¿.


//short sbm_internal_count;   // ¹è°¨¼Ó Àç»ý frame count.   sbm_current_state°¡ 1 È¤Àº 2ÀÏ¶§¸¸ À¯È¿.
//short SBM_effect_num;   // offset¿¡ ÀÇÇØ, SBMÀ» ¸î¹ø µ¹·Á¾ß ÇÒÁö °è»ê.

int sbm_internal_count;   // ¹è°¨¼Ó Àç»ý frame count.   sbm_current_state°¡ 1 È¤Àº 2ÀÏ¶§¸¸ À¯È¿.
int SBM_effect_num;   // offset¿¡ ÀÇÇØ, SBMÀ» ¸î¹ø µ¹·Á¾ß ÇÒÁö °è»ê.
int SBM_normal_num;


// mode_info : Normal_mode : 0,  Game_mode : 1,  
// current_idx : packet index(0~255),   Null-packetÀÌ ¿Â °æ¿ì(PLC»óÈ²)¿¡¼­´Â À½¼ö·Î Ç¥ÇöÇÏÀÚ.


#if 0
void ssc_set_SBM_apply_modi_subfunction(short current_idx, int speed)
{
	if(sbm_end_idx>sbm_start_idx)
	{
		if(current_idx>=sbm_end_idx || current_idx<sbm_start_idx)
		{
			sbm_current_state = 0;
			ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
		}
		else
		{
			ssc_SBM_speed_setPar(speed);
		}
	}
	else
	{
		if(current_idx>=sbm_end_idx && current_idx<sbm_start_idx)
		{
			sbm_current_state = 0;
			ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
		}
		else
		{
			ssc_SBM_speed_setPar(speed);
		}

	}

	sbm_internal_count++;	
}


short SBM_overflow_flag;
short mode_change_point;    // the index when mode is changed.


int ssc_set_SBM_apply_modi(int minimum_buffer_level, short mode_info, short current_idx, short ref_time_stamp)   
{

//	short sbm__end_idx;
	if(current_idx<0 || current_idx>255)
	{
		return 2;  // PacketÀÌ Null·Î ¿Í¼­ ÀÇ¹Ì°¡ ¾ø´Â °æ¿ì, Çö »óÅÂ¸¦ ±×³É À¯Áö. ±×¸®°í Á¤»óÀÌ¹Ç·Î, ¾ç¼ö·Î return.
	}

	if(mode_info != prev_mode_info)
	{
	
		SBM_overflow_flag = 0;

		if(current_idx>ref_time_stamp)
		{
			SBM_overflow_flag = 1;
		}

		if(mode_info == 1)  // Normal Mode --> Game Mode, Áï 'Fast Play' ½ÃÀÛ.
		{
			short sbm_fast_num = (minimum_buffer_level - GAME_MODE_TARGET_BUFFER_LEVEL);
			sbm_fast_num = MAX16((sbm_fast_num*10),0);
			sbm_fast_num = MIN16(sbm_fast_num,255);

			sbm_current_state = 4;    //4

			mode_change_point = current_idx;
			sbm_start_idx = ref_time_stamp;

			sbm_end_idx = ref_time_stamp + sbm_fast_num;
			sbm_end_idx = (sbm_end_idx & 255);

			sbm_internal_count = 0;
		}
		else if(mode_info == 0) // Game Mode --> Normal Mode, Áï Buffer¸¦ Ã¤¿ì±â À§ÇØ 'slow speed'¸¦ ÇØ´Þ¶ó´Â°Í.
		{
			short sbm_slow_num = (NORMAL_MODE_TARGET_BUFFER_LEVEL - minimum_buffer_level);
			sbm_slow_num = MAX16((sbm_slow_num*10),0);
			sbm_slow_num = MIN16(sbm_slow_num,255);

			sbm_current_state = 3;   //3

			mode_change_point = current_idx;
			sbm_start_idx = ref_time_stamp;
			sbm_end_idx = ref_time_stamp + sbm_slow_num;
			sbm_end_idx = (sbm_end_idx & 255);
			
			sbm_internal_count = 0;
		}
		else
		{
			return -1;
		}
	}
/////////////////////////////////////////////////////
	prev_mode_info = mode_info;


	                                               // sbm_current_state == 4 :  Normal Mode --> Game Mode,   sbm_current_state == 3 :  Game Mode --> Normal Mode,
	if(sbm_current_state == 4 || sbm_current_state == 3)   //  Normal-->Game ¸ðµå ½ÅÈ£´Â ¹Þ¾ÒÁö¸¸, ¾ÆÁ÷ PE_SE_Communication_TimeÀÌ Áö³ªÁö ¾ÊÀº »óÅÂ.
	{
		if(SBM_overflow_flag == 0)
		{
			if(current_idx>=sbm_start_idx || current_idx<mode_change_point)
			{
				sbm_current_state = sbm_current_state-2;
			}
		}
		else if(SBM_overflow_flag == 1)
		{
			if(current_idx>=sbm_start_idx && current_idx<mode_change_point)
			{
				sbm_current_state = sbm_current_state-2;   
			}
		}
	}

	




/////////////////////////////////////////////////////////
	if(sbm_current_state == 0 || sbm_current_state == 3 || sbm_current_state == 4)
	{
		ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
	}
	else if(sbm_current_state == 1)
	{
		ssc_set_SBM_apply_modi_subfunction(current_idx,SBM_SLOW_SPEED);
	}
	else if(sbm_current_state == 2)
	{
		ssc_set_SBM_apply_modi_subfunction(current_idx,SBM_FAST_SPEED);
	}
	else
	{
		return -2;
	}

	return 1;
}

#endif








// apply_direction
// 0 : Normal speed (Á¤»ó¼Óµµ)  
// + : ºü¸¥ speed (ºü¸¥ ¼Óµµ)
// - : ´À¸° speed (´À¸° ¼Óµµ)


int SBM_FAST_SPEED;
int SBM_SLOW_SPEED;

int ssc_set_SBMspeed_test(int low_speed, int high_speed,int normal_num)
{

	SBM_FAST_SPEED = high_speed;
	SBM_SLOW_SPEED = low_speed;

	SBM_normal_num = normal_num;

	return 1;
}

#if 0
int ssc_sbm_interface(short apply_direction, short offsets)
{

	if(apply_direction>0)   // sbm_current_state
	{
//		if(sbm_current_state == 0 || sbm_current_state == 1 || sbm_current_state == 2)   // ÃßÈÄ¿¡ case º°·Î ºÐÈ­ÇÏÀÚ. ÇÕÃÄÁø°Ç ±âº»Format
		if(sbm_current_state == 0)
		{	
			sbm_current_state = 2;  // Normal --> Fast
			SBM_effect_num = MAX16(( (offsets*100)/ (((SBM_FAST_SPEED - SBM_NORMAL_SPEED)*100+32768)>>16) ),0);   // (SBM_FAST_SPEED - SBM_NORMAL_SPEED)
	//		SBM_effect_num = MIN16(SBM_effect_num,255);
			SBM_effect_num = MIN16(SBM_effect_num,1500);
		}
////////////////////////////////////////////////////////
//		sbm_debug_param[3] = 1;
///////////////////////////////////////////////////////////
	}
	else if(apply_direction<0)
	{
//		if(sbm_current_state == 0 || sbm_current_state == 1 || sbm_current_state == 2)   // ÃßÈÄ¿¡ case º°·Î ºÐÈ­ÇÏÀÚ. ÇÕÃÄÁø°Ç ±âº»Format
		if(sbm_current_state == 0)
		{
			sbm_current_state = 1;  // Normal --> slow
			SBM_effect_num = MAX16(( (offsets*100)/(((SBM_NORMAL_SPEED - SBM_SLOW_SPEED)*100+32768)>>16) ),0);   // (SBM_FAST_SPEED - SBM_NORMAL_SPEED)
	//		SBM_effect_num = MIN16(SBM_effect_num,255);
			SBM_effect_num = MIN16(SBM_effect_num,1500);
		}
////////////////////////////////////////////////////////
//		sbm_debug_param[3] = -1;
///////////////////////////////////////////////////////////
	}



//	prev_mode_info = apply_direction;

	if(sbm_current_state == 0)
	{
		ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
		SBM_effect_num = 0;
		sbm_internal_count = 0;

	//	sbm_debug_param[0] = 0;

	}
	else if(sbm_current_state == 1)  // slow
	{		
		sbm_internal_count++;
		ssc_SBM_speed_setPar( SBM_SLOW_SPEED ); 
		if(sbm_internal_count>=SBM_effect_num)
		{
			sbm_current_state = 0;
		}

	//	sbm_debug_param[0] = 1;

	}
	else if(sbm_current_state == 2)  // fast
	{
		sbm_internal_count++;
		ssc_SBM_speed_setPar( SBM_FAST_SPEED );
		if(sbm_internal_count>=SBM_effect_num)
		{
			sbm_current_state = 0;
		}
////////////////////////////////////////////////
	//	sbm_debug_param[0] = 2;
////////////////////////////////////////////////
	}
	else
	{
		return -2;
////////////////////////////////////////////////
	//	sbm_debug_param[0] = -2;
////////////////////////////////////////////////
	}


	//sbm_debug_param[1] = SBM_effect_num;
//	sbm_debug_param[2] = sbm_internal_count;


	return 1;

}
#else

/*
#define SBM_FAST_SPEED 67380   // 840        // 67350 ~67400  : 
#define SBM_SLOW_SPEED 63730   // 888        //  63700  ~ 63750
*/
/*
#define SBM_FAST_SPEED 66100   // 856   66080 ~ 66140
#define SBM_SLOW_SPEED 64920   // 872    64880  64920
*/

/////////////////////////  5.54%  /////////////////////////
//#define SBM_FAST_SPEED 69350    // 816   69310 69390
//#define SBM_SLOW_SPEED 62070    // 912     62020  62070
/////////////////////////////////////////////////////


#define SBM_EFFECT_NUM_Offset 0
int calc_SBM_effect_num(short apply_direction, short offsets)
{
	int SBM_effect_num = 0;

	if(apply_direction>0)
	{
		if(SBM_FAST_SPEED>=66700 && SBM_FAST_SPEED<=66760)                     
		{
			SBM_effect_num = (54*offsets);    // 1.87% case   //   (16*54)/44100  =  
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;   // 5´Â game mode ¿À°í, 5 frameÈÄ¿¡ ½ÇÁ¦ frame ÁÙ¾îµéÀ½
		}
		else if(SBM_FAST_SPEED>=67350 && SBM_FAST_SPEED<=67400)
		{
			SBM_effect_num = (36*offsets);    // 2.76% case   //  (24*36)/44100  =  
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_FAST_SPEED>=69310 && SBM_FAST_SPEED<=69390)
		{
			SBM_effect_num = (18*offsets);    // 5.52%    //   (48*18)/44100  =  0.196
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_FAST_SPEED>=66080 && SBM_FAST_SPEED<=66140)
		{
			SBM_effect_num = (108*offsets);    // 0.92% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_FAST_SPEED>=67980 && SBM_FAST_SPEED<=68050)   ////67980  ~ 68050   -32 sample
		{
			SBM_effect_num = (27*offsets);    // 3.68% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_FAST_SPEED>=68640 && SBM_FAST_SPEED<=68710)   ////68640     68710   -40 sample
		{
			SBM_effect_num = ((43*offsets)>>1);    // 4.6% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else
		{
			SBM_effect_num = MAX16(( (offsets*100)/ (((SBM_FAST_SPEED - SBM_NORMAL_SPEED)*100+32768)>>16) ),0);   // (SBM_FAST_SPEED - SBM_NORMAL_SPEED)
			SBM_effect_num = MIN16(SBM_effect_num,1500);
		}
	}
	else if(apply_direction<0)
	{
		if(SBM_SLOW_SPEED>=64280 && SBM_SLOW_SPEED<=64340)   // //64280 ~ 64340
		{
			SBM_effect_num = (54*offsets);    // 1.87% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_SLOW_SPEED>=63700 && SBM_SLOW_SPEED<=63750)   // ////  63700  ~ 63750
		{
			SBM_effect_num = (36*offsets);    // 2.76% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_SLOW_SPEED>=62020 && SBM_SLOW_SPEED<=62070)   // ////  63700  ~ 63750
		{
			SBM_effect_num = (18*offsets);    // 5.52%
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_SLOW_SPEED>=64880 && SBM_SLOW_SPEED<=64920)
		{
			SBM_effect_num = (108*offsets);    // 0.92% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_SLOW_SPEED>=63140 && SBM_SLOW_SPEED<=63190)   //  //  63140 63190
		{
			SBM_effect_num = (27*offsets);    // 3.68% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else if(SBM_SLOW_SPEED>=62570 && SBM_SLOW_SPEED<=62630)   //  //  62570     62630  +40 sample
		{
			SBM_effect_num = ((43*offsets)>>1);    // 4.6% case
			SBM_effect_num = SBM_effect_num + SBM_EFFECT_NUM_Offset;
		}
		else
		{
			SBM_effect_num = MAX16(( (offsets*100)/(((SBM_NORMAL_SPEED - SBM_SLOW_SPEED)*100+32768)>>16) ),0);   // (SBM_FAST_SPEED - SBM_NORMAL_SPEED)
			SBM_effect_num = MIN16(SBM_effect_num,1500);
		}
	}


	return SBM_effect_num;
}


int ssc_sbm_interface(short apply_direction, short offsets)
{


#ifdef ENABLE_VSP
	if(apply_direction>0)   // sbm_current_state  // ºü¸£°Ô Àç»ý ¿äÃ».
	{
		if(sbm_current_state == 0)
		{	
			sbm_current_state = 2;  // Normal --> Fast	
			SBM_effect_num = calc_SBM_effect_num(apply_direction,offsets);
			sbm_internal_count = 0;
		}
		else if(sbm_current_state == 1 || sbm_current_state == 4)  // Slow Àç»ýÇÏ°í ÀÖ´Âµ¥ ºü¸¥ Àç»ý ¿äÃ».....
		{
			sbm_current_state = 3;

			SBM_effect_num = calc_SBM_effect_num(apply_direction,offsets);
			SBM_effect_num = SBM_effect_num + SBM_normal_num;
			sbm_internal_count = 0;
		}
	}
	else if(apply_direction<0)    // ´À¸®°Ô Àç»ý ¿äÃ».
	{
		//		if(sbm_current_state == 0 || sbm_current_state == 1 || sbm_current_state == 2)   // ÃßÈÄ¿¡ case º°·Î ºÐÈ­ÇÏÀÚ. ÇÕÃÄÁø°Ç ±âº»Format
		//  64280 ~ 64340
		if(sbm_current_state == 0)
		{
			sbm_current_state = 1;  // Normal --> slow
			SBM_effect_num = calc_SBM_effect_num(apply_direction,offsets);
			sbm_internal_count = 0;
		}
		else if(sbm_current_state == 2 || sbm_current_state == 3)
		{
			sbm_current_state = 4;

			SBM_effect_num = calc_SBM_effect_num(apply_direction,offsets);
			SBM_effect_num = SBM_effect_num + SBM_normal_num;
			sbm_internal_count = 0;
		}
	}

	//	prev_mode_info = apply_direction;
	if(sbm_current_state == 0)
	{
		ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
		SBM_effect_num = 0;
		sbm_internal_count = 0;
		//	sbm_debug_param[0] = 0;
	}
	else if(sbm_current_state == 1)  // slow
	{		
		sbm_internal_count++;
		ssc_SBM_speed_setPar( SBM_SLOW_SPEED ); 
		if(sbm_internal_count>=SBM_effect_num)
		{
			sbm_current_state = 0;
		}
	}
	else if(sbm_current_state == 2)  // fast
	{
		sbm_internal_count++;
		ssc_SBM_speed_setPar( SBM_FAST_SPEED );
		if(sbm_internal_count>=SBM_effect_num)
		{
			sbm_current_state = 0;
		}
		////////////////////////////////////////////////
		//	sbm_debug_param[0] = 2;
		////////////////////////////////////////////////
	}
	else if(sbm_current_state == 3)  // fast
	{
		sbm_internal_count++;

		if(sbm_internal_count<SBM_normal_num)
		{
			ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
		}
		else if(sbm_internal_count<SBM_effect_num)
		{
			ssc_SBM_speed_setPar( SBM_FAST_SPEED );
		}
		else if(sbm_internal_count>=SBM_effect_num)
		{
			sbm_current_state = 0;
		}
	}
	else if(sbm_current_state == 4)  // fast
	{
		sbm_internal_count++;

		if(sbm_internal_count<SBM_normal_num)
		{
			ssc_SBM_speed_setPar( SBM_NORMAL_SPEED );
		}
		else if(sbm_internal_count<SBM_effect_num)
		{
			ssc_SBM_speed_setPar( SBM_SLOW_SPEED );
		}
		else if(sbm_internal_count>=SBM_effect_num)
		{
			sbm_current_state = 0;
		}

	}
	else
	{
		return -2;
		////////////////////////////////////////////////
		//	sbm_debug_param[0] = -2;
		////////////////////////////////////////////////
	}
#endif
	//sbm_debug_param[1] = SBM_effect_num;
	//	sbm_debug_param[2] = sbm_internal_count;
	return sbm_current_state;

}

#endif