/****************************************************************************
 Module
 SMShoot.c

 Description
 While at a dispenser near our hoop, aims and shoots balls.
 ****************************************************************************/
/*----------------------------- Include Files -----------------------------*/
#include "GlobalHeader.h"
#include "SMGamePlay.h"
#include "SMShoot.h"
#include "SMMaster.h"
#include "SMDrivetrain.h"
#include "SMOffensiveCoordinator.h"

/*----------------------------- Module Defines ----------------------------*/
#define RELEASE_PAUSE 2000
#define FIRE_PAUSE 1000
#define RESET_PAUSE 1000

/*---------------------------- Module Functions ---------------------------*/
static Event_t DuringAiming( Event_t Event);
static Event_t DuringWaiting( Event_t Event);
static Event_t DuringReleasing( Event_t Event);
static Event_t DuringFiring(Event_t Event);
static Event_t DuringResetting(Event_t Event);

/*---------------------------- Module Variables ---------------------------*/
static PlayState_t CurrentState;
static unsigned int StartTime;
static unsigned int PauseTime;

/*------------------------------ Module Code ------------------------------*/
/****************************************************************************
 Function
 QueryShootTimer

 Parameters
 none

 Returns
 1 if current state has expired. 0 otherwise

 Description
 Signals when it is time to transition to next state during shooting process.
 ****************************************************************************/
unsigned char QueryShootTimer(void)
{
	if ((CurrentState == Shoot_Releasing) || (CurrentState == Shoot_Firing) || (CurrentState == Shoot_Resetting))
	{ //if we are in a state with a timer, check it.
		if (TMRS12_GetTime() - StartTime > PauseTime)
			return 1;
	}
	return 0;
}


/****************************************************************************
 Function
 RunShootSM

 Parameters
 Event_t

 Returns
 Event_t

 Description
 Runs Shoot state machine.  First aims, then runs through waiting for a ball,
 releasing a ball, firing, and resetting states (the last three at timed
 intervals).  these last four states are repeated until the state machine is
 exited.
 ****************************************************************************/
Event_t RunShootSM( Event_t CurrentEvent )
{
	unsigned char MakeTransition = FALSE;/* are we making a state transition? */
	PlayState_t NextState = CurrentState;

	switch ( CurrentState )
	{
		case Shoot_Aiming :
			CurrentEvent = DuringAiming(CurrentEvent);
			//process any events
			if ( CurrentEvent != EV_NO_EVENT )        //If an event is active
			{
				switch (CurrentEvent)
				{
					case EV_Drive_Aimed: //if we are done aiming, ready to shoot.
						NextState = Shoot_Waiting;
						MakeTransition = TRUE;
						break;
				}
			}
			break;

		case Shoot_Waiting:
			CurrentEvent = DuringWaiting(CurrentEvent);
			//process any events
			if ( CurrentEvent != EV_NO_EVENT )        //If an event is active
			{
				switch (CurrentEvent)
				{
					case EV_Shoot_BallAtGate: //if there is a ball ready
						NextState = Shoot_Releasing; //release it
						MakeTransition = TRUE;
						break;
				}
			}
			break;
		case Shoot_Releasing:
			CurrentEvent = DuringReleasing(CurrentEvent);
			//process any events
			if ( CurrentEvent != EV_NO_EVENT )
			{
				switch (CurrentEvent)
				{
					case EV_Shoot_TimerExpired: //if timer expired
						NextState = Shoot_Firing; //proceed to firing state
						MakeTransition = TRUE;
						break;
				}
			}
			break;

		case Shoot_Firing:
			CurrentEvent = DuringFiring(CurrentEvent);
			//process any events
			if ( CurrentEvent != EV_NO_EVENT )        //If an event is active
			{
				switch (CurrentEvent)
				{
					case EV_Shoot_TimerExpired: //if timer expired
						NextState = Shoot_Resetting; //proceed to resetting state
						MakeTransition = TRUE;
						break;
				}
			}
			break;
		case Shoot_Resetting:
			CurrentEvent = DuringResetting(CurrentEvent);
			//process any events
			if ( CurrentEvent != EV_NO_EVENT )        //If an event is active
			{
				switch (CurrentEvent)
				{
					case EV_Shoot_TimerExpired: //if timer expired
						NextState = Shoot_Waiting; //proceed to waiting state
						MakeTransition = TRUE;
						break;
				}
			}
			break;
    }
    //   If we are making a state transition
    if (MakeTransition == TRUE)
    {
		//   Execute exit function for current state
		(void)RunShootSM(EV_EXIT);
		CurrentState = NextState; //Modify state variable
		//printf("Next Game State %d\r\n",NextState);
		//   Execute entry function for new state
		(void)RunShootSM(EV_ENTRY);
	}
	return(CurrentEvent);
}

/****************************************************************************
 Function
 StartShootSM

 Parameters
 Event_t

 Returns
 none

 Description
 Start state machine.
 ****************************************************************************/
void StartShootSM ( Event_t CurrentEvent )
{
	CurrentState = Shoot_Aiming;

	// call the entry function (if any) for the ENTRY_STATE
	(void)RunShootSM(EV_ENTRY);
}

/****************************************************************************
 Function
 QueryShootSM

 Parameters
 none

 Returns
 ShootState_t current machine state

 Description
 returns state of state machine
 ****************************************************************************/
ShootState_t QueryShootSM ( void )
{
	return(CurrentState);
}

/***************************************************************************
 private functions
 ***************************************************************************/

/****************************************************************************
 Function
 DuringAiming

 Parameters
 Event_t

 Returns
 Event_t

 Description
 On entry, set hoop to 3pt size, and aim at our hoop, getting the correct
 offset from the QueryShotAngle() function.
 ****************************************************************************/
static Event_t DuringAiming( Event_t Event)
{
    // process EV_ENTRY & EV_EXIT events
    if ( Event == EV_ENTRY)
    {
    	OC_AddCommand(OC_Request3pt,0);
		Drive_Aim(QueryMyHoop(),QueryShotAngle(QueryCurrentDispenserNumber()),50);

    }else if ( Event == EV_EXIT)
    {
    }else
		// do the 'during' function for this state
    {
    }
    return(Event);
}

/****************************************************************************
 Function
 DuringWaiting

 Parameters
 Event_t

 Returns
 Event_t

 Description
 On entry, reset shooter servo if it hasn't been.
 ****************************************************************************/
static Event_t DuringWaiting( Event_t Event)
{
    // process EV_ENTRY & EV_EXIT events
    if ( Event == EV_ENTRY)
    {
    	SetShooterServo(Shooter_Reset);
    }else if ( Event == EV_EXIT)
    {
    }else
		// do the 'during' function for this state
    {
    }
    return(Event);
}

/****************************************************************************
 Function
 DuringReleasing

 Parameters
 Event_t

 Returns
 Event_t

 Description
 Release a ball by turning the gate servo.  Get ready to fire by setting the
 shooter servo to Ready.
 ****************************************************************************/
static Event_t DuringReleasing( Event_t Event)
{
    // process EV_ENTRY & EV_EXIT events
    if ( Event == EV_ENTRY)
    {
        StartTime = TMRS12_GetTime();
        PauseTime = RELEASE_PAUSE;
        SetGateServo(Gate_Release);
        SetShooterServo(Shooter_Ready);
    }else if ( Event == EV_EXIT)
    {
    }else
		// do the 'during' function for this state
    {
    }
    return(Event);
}

/****************************************************************************
 Function
 DuringFiring

 Parameters
 Event_t

 Returns
 Event_t

 Description
 Fires ball by setting shooter servo to Fire.  Resets gate servo to get ready
 for new ball.
 ****************************************************************************/
static Event_t DuringFiring( Event_t Event)
{
    // process EV_ENTRY & EV_EXIT events
    if ( Event == EV_ENTRY)
    {
    	StartTime = TMRS12_GetTime();
    	PauseTime = FIRE_PAUSE;
    	SetShooterServo(Shooter_Fire);
    	SetGateServo(Gate_Reset);
    }else if ( Event == EV_EXIT)
    {
    }else
		// do the 'during' function for this state
    {
    }
    return(Event);
}

/****************************************************************************
 Function
 DuringResetting

 Parameters
 Event_t

 Returns
 Event_t

 Description
 Resets shooter servo
 ****************************************************************************/
static Event_t DuringResetting( Event_t Event)
{
    // process EV_ENTRY & EV_EXIT events
    if ( Event == EV_ENTRY)
    {
        StartTime = TMRS12_GetTime();
    	PauseTime = RESET_PAUSE;
    	SetShooterServo(Shooter_Reset);
    }else if ( Event == EV_EXIT)
    {
    }else
		// do the 'during' function for this state
    {
    }
    return(Event);
}