#include "generic.h"
#include "lfptypes.h"
#include "define.h"
#include "ml.h"
#include "ft.h"
#include "overgfx.h"

#include "audio.h"
#include "gamefx.h"
#include "cammodes.h"

#define AUTO_SHOOT_TIME (10*ONE_SEC)

extern u8
	*GameBank;

int free_throws;
int free_thrower;
global bool	ft_flag;

static int free_frame;
static int ready_to_throw;

int last_free_throw;

#ifdef PC
int freeThrowScore=1;
#endif


static s32
	AutoShoot;

static int lose_free_throw(void);


int lose_free_throw(void)
{
	playert	*plyr=&player[free_thrower];

	if (++AutoShoot < AUTO_SHOOT_TIME)
		return FALSE;

	// Player should have shot by now, penalize him
	Audio_SfxPlay( GameBank, SFX_WHISTLE, SfxVolume );
	plyr->plyrRAM->cl___pStatGame.uw___pFTA+=1;
	plyr->teamRAM->cl___tStatGame.uw___tFTA += 1;
	if (--free_throws)
	{
		freeThrowPlayer=NULL;
		SetFreeThrowVisible(lose_free_throw,0);
		FreeThrowStart((plyr->no<5)?1:-1,plyr);
		ready_to_throw=0;
		SetMain(loose_free_throw,plyr,free_throw_wait);
	}
	else
	{
		drop_ball(plyr);
		new_shot_clock();

		ball.target_x = 0x100000;
		ball.target_y = (ball.yco>0) ? BASE_LINE+EDGE: -BASE_LINE-EDGE;
		start_drop_bounce(&ball);

		//last_bx  = ball.xco;
		//last_by  = ball.yco;
		//last_bz  = ball.zco;
		//if (ball.zco<0x100000)	ball.zco = 0x100000;
		ball.xvel = ball.yvel = ball.zvel = 0;
		FreeThrowReturn();
		FreeThrowStop();
		FreeThrowStopMotion();
		ft_flag=0;
	}

	AutoShoot=0;
	OverGfx_UpdatePlayerCard();

	return TRUE;
}

void look_at_ball(void)
{
playert *plyr;
	
	for (plyr=player; plyr<&ball; plyr++)
	{
		if (plyr->basket_dist<0x500000)		plyr->look_at_ball_ctr = 3;
	}

}



void free_throw_pick_up(playert *plyr)
{
	FreeThrowStart(ball.yco>0?1:-1,plyr);
	ready_to_throw=0;

	if (end_animation_test(plyr))
	{
		start_next_anim(plyr);
		SetMain(free_throw_pick_up,plyr,free_throw_wait);
		plyr->ctr2 = 0;
	}
}


void free_throw_wait(playert *plyr)
{
	if (not_there_yet)
	{
		AutoShoot = 0;
		plyr->ctr2++;

		if (plyr->ctr2 > (ONE_SEC*2))
		{
			playert *p;
			int s;

			s = 15+((free_thrower%5)*2);
			if ((foul_flag==TECHNICAL) || (foul_flag==FLAGRANT) || foul_flag==ILLEGAL_DEFENSE)
				s += 10;

			if (plyr->no<5)
			{
				for (p=player; p<player+10; p++)
				{
					p->target_x = inbound[s][p->no][0]<<16;
					p->target_y = inbound[s][p->no][1]<<16;
				}
			}
			else
			{
				for (p=player; p<player+5; p++)
				{
					p->target_x =  inbound[s][p->no+5][0]<<16;
					p->target_y = -inbound[s][p->no+5][1]<<16;
				}

				for (; p<player+10; p++)
				{
					p->target_x =  inbound[s][p->no-5][0]<<16;
					p->target_y = -inbound[s][p->no-5][1]<<16;
				}
			}


			for (p=player; p<&ball; p++)
			{
				if ( (MANHATTAN(p->xco - p->target_x, p->yco-p->target_y)) > 0xa0000)
				{
					p->xco = p->target_x;
					p->yco = p->target_y;
					set_default(p);
				}
			}
			plyr->ctr2 = 0;
		}


		not_there_yet = FALSE;	//wait for other players to reach spot
	}
	else
	{
		ft_flag = TRUE;
		if (plyr->control==0)			// Computer player.
		{
			ready_to_throw=1;
			ShowFreeThrowHelp = FALSE;	// fixes bug # 630?!?
		}
		else
		{
			if (!ICCL_ROOKIE && !FreeThrowsShown[plyr->control-1])
			{
				ShowFreeThrowHelp = TRUE;
				FreeThrowsShown[plyr->control-1] = TRUE;
			}

			if (CTL_DOWN( current_ctrlr, CTRL_SHOOT ))
			{
				CTL_RMASK( current_ctrlr, CTRL_SHOOT );
				ready_to_throw=(camSpecialMode==CAM_SPECIAL_FREETHROW)? 0 : 1;
				AutoShoot = 0;
				ShowFreeThrowHelp = FALSE;
			}
		}

		if (ready_to_throw)
		{
			free_frame = lp_ctr;
			SetMain(free_throw_wait,plyr,free_throw_bounce);
			FreeThrowStartMotion();
		}
	}
}


void free_throw_bounce(playert *plyr)
{
	look_at_ball();

	FreeThrowProcess(0,0);

	if (plyr->control==0 || ICCL_ROOKIE)			// Computer player.
	{
		if (last_bounce-free_frame > (2*ONE_SEC))
		{
//		if (plyr->top_frame<0x400)
//		{
			start_next_anim(plyr);
			SetMain(free_throw_bounce,plyr,free_throw_shoot);
			FreeThrowStopMotion();
		}
	}
	else
	{
		if (lose_free_throw())
			return;

		if (CTL_DOWN( current_ctrlr, CTRL_SHOOT ) || AutoShoot >= AUTO_SHOOT_TIME)
		{
			CTL_RMASK( current_ctrlr, CTRL_SHOOT );
			start_next_anim(plyr);
			SetMain(free_throw_bounce,plyr,free_throw_shoot);

			FreeThrowStopMotion();
		}
	}
}







void free_throw_shoot(playert *plyr)
{
//	FreeThrowProcess(0,0);

	look_at_ball();

	if (end_animation_test(plyr))
	{
		free_throws -= 1;

		if (plyr->control && !ICCL_ROOKIE)
			shoot_ball(plyr, freeThrowScore*0xFF, (UB *)made_list);
		else
			shoot_ball(plyr, (plyr->plyrROM->ub___pAttrFT*256)/100, (UB *)made_list);

		SetPossession(free_throw_shoot,FALSE);
		start_next_anim(plyr);
		SetMain(free_throw_shoot,plyr,free_throw_recover);
		plyr->ctr2=0;
		if(!free_throws) FreeThrowReturn();
	}
}


void free_throw_recover(playert *plyr)
{
	int	dx,dy;

	AutoShoot = 0;
	look_at_ball();
	
	if (!blend_to_end(plyr, TOP_RDY, LEG_RDY, 4))
		return;

	if ((free_throws==0) || (plyr->no != free_thrower))
	{
		SetMain(free_throw_recover,plyr,deflt);
		plyr->top_routine  = top_deflt;
		plyr->leg_routine  = leg_deflt;
	}
	else if (ball.main_routine==drop_bounce)
	{
		dx=abs(ball.xco-ball.target_x);
		dy=abs(ball.yco-ball.target_y);
		if (dx<0x10000 && dy<0x10000 || plyr->ctr2++>2*ONE_SEC)
		{
			start_pick_up_ball(plyr);
			Crowd_FreeThrow( FALSE );
			return;
		}

		if (plyr->control)
		{
			if (test_and_mask(current_ctrlr ,CTRL_FIRE_A))
			{
				start_pick_up_ball(plyr);
				Crowd_FreeThrow( FALSE );
			}
		}
	}
}

