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

 Module

   MasterService.c


 Revision

   1.0.1


 Description

   This is a template file for implementing a simple service under the

   Gen2 Events and Services Framework.


 Notes


 History

 When           Who     What/Why

 -------------- ---     --------

 01/16/12 09:58 jec      began conversion from TemplateFSM.c

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

/*----------------------------- Include Files -----------------------------*/

/* include header files for this state machine as well as any machines at the

   next lower level in the hierarchy that are sub-machines to this machine

*/

// This Module

#include "MasterService.h"


#include "ES_Configure.h"

#include "ES_Framework.h"

#include "dbprintf.h"

#include "CrewService.h"

#include "Servo.h"

#include "LEDService.h"

#include "string.h"

#include "PIC32_SPI_HAL.h"

#include "ButtonChecker.h"


/*----------------------------- Module Defines ----------------------------*/

#define ONE_SEC 1000

#define IDLE_SEC (ONE_SEC * 20)

#define GAMETIME_SEC (ONE_SEC * 42)

#define PROGRESS_SEC (ONE_SEC * 5)

#define RESULT_SEC (ONE_SEC * 10)

#define MESSAGE_SEC (ONE_SEC / 5)

/*---------------------------- Module Functions ---------------------------*/

/* prototypes for private functions for this service.They should be functions

   relevant to the behavior of this service

*/


/*---------------------------- Module Variables ---------------------------*/

// with the introduction of Gen2, we need a module level Priority variable

static uint8_t MyPriority;


MasterServiceState_t CurrentMasterState = Master_Idle;

MasterServiceState_t NextMasterState = Master_Idle;


static int progress_index = 0;

static char message[14];

static const char welcome_message[] = "2x COINs Plz ";

static const char welcome_message2[] = "1x MORE Plz! ";

static const char win_message[] = "YEAH YOU WIN ";

static const char lose_message[] = "OOPS YOU DIE ";

static const char user_left_message[] = "User Left  ";

static int string_length;

static int string_index;


/*------------------------------ Module Code ------------------------------*/

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

 Function

     InitMasterService


 Parameters

     uint8_t : the priorty of this service


 Returns

     bool, false if error in initialization, true otherwise


 Description

     Saves away the priority, and does any

     other required initialization for this service

 Notes


 Author

     J. Edward Carryer, 01/16/12, 10:00

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

bool InitMasterService(uint8_t Priority)

{

    Declare ThisEvent as ES_Event_t

    Set MyPriority to Priority


    Print compilation details time and date

    Print "Crew Commander ON"

    Print "Ready to Play"

    Print "Please Insert Two Chips"


    Call InitButtonChecker()

    Call InitProgressLED()


    Set message to welcome_message

    Set string_length to size of message

    Reset string_index to 0


    Clear the LED display buffer for that row


    Call ShowMessage(ThisEvent, message)


    Set ThisEvent.EventType to ES_INIT

    If ES_PostToService(MyPriority, ThisEvent) returns true:

        Return true

    Else:

        Return false

    EndIf

}


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

 Function

     PostMasterService


 Parameters

     EF_Event_t ThisEvent ,the event to post to the queue


 Returns

     bool false if the Enqueue operation failed, true otherwise


 Description

     Posts an event to this state machine's queue

 Notes


 Author

     J. Edward Carryer, 10/23/11, 19:25

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

bool PostMasterService(ES_Event_t ThisEvent)

{

  return ES_PostToService(MyPriority, ThisEvent);

}


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

 Function

    RunMasterService


 Parameters

   ES_Event_t : the event to process


 Returns

   ES_Event, ES_NO_EVENT if no error ES_ERROR otherwise


 Description

   add your description here

 Notes


 Author

   J. Edward Carryer, 01/15/12, 15:23

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

ES_Event_t RunMasterService(ES_Event_t ThisEvent)

{

    Initialize ReturnEvent to ES_NO_EVENT

    Initialize GameProgressEvent


    Switch CurrentMasterState:

        Case Master_Idle:

            If ThisEvent is COIN_INSERT:

                Set NextMasterState to One_Coin_In

                Initialize Progress LED

                Start MASTERSERVICE_TIMER with IDLE_SEC

                Set message to welcome_message2

                Reset string_length and string_index

                Clear 8 rows of display buffer

            EndIf

            Display message using ShowMessage(ThisEvent, message)


        Case One_Coin_In:

            If ThisEvent is COIN_INSERT:

                Set NextMasterState to Game_Running

                Set GameProgressEvent.EventType to GAME_START

                Reset progress_index

                Initialize Progress LED

                Post GameProgressEvent to all services

                Start MASTERSERVICE_TIMER, GAME_TIMER, and PROGRESS_TIMER

                Clear 8 rows of display buffer

                Print "GAME START"

            ElseIf ThisEvent is  ES_TIMEOUT and Timer is MASTERSERVICE_TIMER:

                Set NextMasterState to Master_Idle

                Set GameProgressEvent.EventType to USER_LEFT

                Print "User Left Game"

                Set message to user_left_message

                Reset string_length and string_index

                Post GameProgressEvent to all services

            EndIf

            Display message using ShowMessage(ThisEvent, message)


        Case Game_Running:

            If ThisEvent is PLAYING:

                Stay in Game_Running

                Reset MASTERSERVICE_TIMER

            ElseIf ThisEvent is LOSE:

                Set NextMasterState to Game_Complete

                Start MASTERSERVICE_TIMER and MESSAGE_TIMER with RESULT_SEC and MESSAGE_SEC

                Set message to lose_message

                Reset string_length and string_index

                Clear 8 rows of display buffer

                Print "YOU LOSE"

            ElseIf ThisEvent is ES_TIMEOUT and Timer is MASTERSERVICE_TIMER:

                Set NextMasterState to Game_Complete

                Set GameProgressEvent.EventType to USER_LEFT

                Post GameProgressEvent

                Start MASTERSERVICE_TIMER and MESSAGE_TIMER

                Set message to user_left_message

                Reset string_length and string_index

                Clear 8 rows of display buffer

                Print "User Left Game"

            ElseIf ThisEvent is ES_TIMEOUT and Timer is GAME_TIMER:

                Set NextMasterState to Game_Complete

                Set GameProgressEvent.EventType to WIN

                Post GameProgressEvent

                Start MASTERSERVICE_TIMER and MESSAGE_TIMER

                Set message to win_message

                Reset string_length and string_index

                Clear 8 rows of display buffer

                Print "YOU WIN"

            ElseIf ThisEvent is  ES_TIMEOUT and Timer is  PROGRESS_TIMER:

                Stay in Game_Running

                Restart PROGRESS_TIMER

                If progress_index < 8:

                    Activate next LED based on progress_index and increment progress_index

                EndIf

            EndIf


        Case Game_Complete:

            If ThisEvent is ES_TIMEOUT and Timer is MASTERSERVICE_TIMER:

                Set NextMasterState to Master_Idle

                Set GameProgressEvent.EventType to GAMERESULT_OVER

                Initialize Progress LED

                Post GameProgressEvent to LEDService and Servo

                Set message to welcome_message

                Reset string_length and string_index

                Clear 8 rows of display buffer

                Print "END OF CELEBRATION"

            EndIf

            Display message using ShowMessage(ThisEvent, message)


        Default:

            Do nothing


    Update CurrentMasterState to NextMasterState

    Return ReturnEvent

}



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

 private functions

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

void ShowMessage(ES_Event_t ThisEvent, char* message)

{

    If ThisEvent is ES_TIMEOUT AND Timer is not MASTERSERVICE_TIMER:

        Start MESSAGE_TIMER with MESSAGE_SEC

        If ThisEvent is ES_TIMEOUT AND Timer is MESSAGE_TIMER:

            If string_index less than string_length - 1:

                Set ThisEvent.EventType to ES_NEW_KEY

                Set ThisEvent.EventParam to ASCII value of message[string_index]

                Post ThisEvent to LEDService

                Increment string_index

            Else:

                Reset string_index to 0

            EndIf

        EndIf

    EndIf

}


void InitProgressLED(void)

{

  Set each pin as output individually, pins: RB4, 5, 6, 2, 8, 9, 10, 11

  Set each pin low initially, pins: RB4, 5, 6, 2, 8, 9, 10, 11

}

/*------------------------------- Footnotes -------------------------------*/

/*------------------------------ End of file ------------------------------*/