/****************************************************************************
 Offensive Coordinator State Machine Header

 ****************************************************************************/

#ifndef SMOffensiveCoordinator_H
#define SMOffensiveCoordinator_H

// Event Definitions
#include "SMEvents.h"

// typedefs

// State definitions
typedef enum {
	OC_Ready,
	OC_InProgress,
	OC_Pending
} OCState_t ;

//Command definitions
#define OC_DefaultCommand 0xAA
#define OC_QueryGameStatus 0x78
#define OC_Request3pt 0x4F
#define OC_Request2pt 0x48

#define OC_QueryCommandBase 			0b01110000
#define OC_RequestCommandBase   		0b01000000
#define OC_CommandDispenserMask 		0b00000011

//response definitions
#define OC_QueryResponseBase  		   	0b11000000
#define OC_ResponseDispenserMask  		0b00001100
#define OC_BallMask      	  			0b00000011

typedef enum
{
	OC_DispenserQueryPending0 =  0b10110000, //disp0
	OC_DispenserQueryPending1 =  0b10110100, //disp1
	OC_DispenserQueryPending2 =  0b10111000, //disp2
	OC_DispenserQueryPending3 =  0b10111100, //disp3
	OC_LastRequestPending = 0xD1,
	OC_LastRequestSucceeded = 0xDF,
	OC_LastRequestFailed = 0xD0,
	OC_GamePaused = 0xE0,
	OC_GameRunning = 0xE1,
	OC_GameWonRed = 0xE2,
	OC_GameWonGreen = 0xE4,
	OC_InvalidCommand = 0xFE
} OCResponse_t;



// Public Function Prototypes

//State machine Functions
Event_t RunOffensiveCoordinatorSM( Event_t CurrentEvent );
void StartOffensiveCoordinatorSM ( Event_t CurrentEvent );
OCState_t QueryOffensiveCoordinatorSM ( void );

/****************************************************************************
 Function
 QueryOCTimerFlag

 Returns
 1 if the OC timer has expired and a response has been received from the OC.
 0 otherwise

 Description
 Returns whether the OC timer has expired, masked by whether we have recevied
 a response from the OC.
 ****************************************************************************/
unsigned char QueryOCTimerFlag (void);

/****************************************************************************
 Function
 QueryOCReadFlag

 Returns
 1 if there is a new read from the SPI, 0 otherwise

 Description
 Checks for a new read on the SPI port.  If so, it stores the value.
 ****************************************************************************/
unsigned char QueryOCReadFlag (void);

/****************************************************************************
 Function
 QueryOCQueueLength

 Returns
 unsigned char length of queue

 Description
 Returns length of queue
 ****************************************************************************/
unsigned char QueryOCQueueLength (void);

/****************************************************************************
 Function
 QueryOCCommandCounter

 Returns
 1 if we have waited for a response to a command for more than the timeout limit.

 Description
 Checks timeout for waiting for a response for a single command.
 ****************************************************************************/
unsigned char QueryOCCommandCounter (void);

/****************************************************************************
 Function
 QueryOCNewResponseFlag

 Returns
 1 if the field has returned a response, 0 otherwise

 Description
 Checks whether the game master has responded to a command
 ****************************************************************************/
unsigned char QueryOCNewResponseFlag(void);

/****************************************************************************
 Function
 QueryOCResponse

 Returns
 unsigned char - the response from the field

 Description
 Returns what the most recent response from the field was.
 ****************************************************************************/
unsigned char QueryOCResponse (void);

/****************************************************************************
 Function
 QueryOCLastCommand

 Returns
 unsigned char - the command corresponding to the new response

 Description
 Returns the command corresponding to the most recent response.
 ****************************************************************************/
unsigned char QueryOCLastCommand (void);

/****************************************************************************
 Function
 OC_AddCommand

 Parameters
 unsigned char Command - 8bit command to add, unsigned char Priority

 Returns
 1 if command successfully added to queue, 0 otherwise

 Description
 Adds Command to the command queue.  If added with priority > 0, the command
 is added to at worst that spot.  If priority == 0, the command is added to
 the end of the queue, unless the queue is full in which case the command is
 NOT added, and the function returns 0 for failure.
 ****************************************************************************/
unsigned char OC_AddCommand (unsigned char Command, unsigned char Priority);

/****************************************************************************
 Function
 OC_QueryDispenser

 Parameters
 unsigned char Dispenser to query, unsigned char Priority of command

 Returns
 success of AddCommand call.

 Description
 Adds a query dispenser command with priority Priority
 ****************************************************************************/
unsigned char OC_QueryDispenser(unsigned char Dispenser, unsigned char Priority);

/****************************************************************************
 Function
 OC_RequestBall

 Parameters
 unsigned char Dispenser to get ball from, unsigned char Priority of command

 Returns
 success of AddCommand call.

 Description
 Adds a request ball command with priority Priority
 ****************************************************************************/
unsigned char OC_RequestBall(unsigned char Dispenser, unsigned char Priority);

#endif /*SMOffensiveCoordinator_H */