#include "Behaviors/StateMachine.h"

$nodeclass SyncLEDBark : StateNode {
  // A node which flashes an LED specified by a bitmask.
  // Since the led needs to be on as long as its corresponding sound
  // the time for the flash is just set to be much longer than the sound.
  // The transition which is fired when the sound completes will also
  // deactivate this node which will stop the flash
  $nodeclass FlashLED(LEDBitMask_t bitmask) : LedNode : doStart {
    getMC()->flash(bitmask, 1.0, 100000);
  }

  // A sound node that stops playing its sound immediately when deactivated
  $nodeclass MySoundNode(string filename) : SoundNode(filename) : doStart {
    setAutoStop(true);
  }

  $setupmachine {
    startNode : StateNode
    startNode =N=> {flashPower, playHowl}

    // The first group of nodes. Sounds and LEDs are played together
    // in the following order:
    //   1. power LED and howl sound
    //   2. play LED and low bark sound
    //   3. advance LED and ping sound
    flashPower   : FlashLED(RobotInfo::PowerRedLEDMask)
    flashPlay    : FlashLED(RobotInfo::PlayLEDMask)
    flashAdvance : FlashLED(RobotInfo::AdvanceLEDMask)

    playHowl : MySoundNode("howl.wav")
    playBark : MySoundNode("barklow.wav")
    playPing : MySoundNode("ping.wav")

    // The transition loop for the first set of nodes.
    // =C(1)=> transitions are used because only the bark needs
    // to finish for the state machine to transition to the next
    // set of nodes.
    {flashPower, playHowl} =C(1)=> {flashPlay, playBark} =C(1)=>
      {flashAdvance, playPing} =C(1)=> {flashPower, playHowl}

    // Button transitions between the first and second group of nodes (second group described below)
    {flashPower, playHowl} =B(RobotInfo::BumpLeftButOffset, activateETID)=> {revFlashAdvance, revPlayPing}
    {flashPlay, playBark} =B(RobotInfo::BumpLeftButOffset, activateETID)=> {revFlashPower, revPlayHowl}
    {flashAdvance, playPing} =B(RobotInfo::BumpLeftButOffset, activateETID)=> {revFlashPlay, revPlayBark}

    // The first group of nodes which is the same as the first
    // group except that the sequence is reversed. Sounds and LEDs
    // are played together in the following order:
    //   1. power LED and howl sound
    //   2. advance LED and ping sound
    //   3. play LED and low bark sound
    revFlashPower   : FlashLED(RobotInfo::PowerRedLEDMask)
    revFlashPlay    : FlashLED(RobotInfo::PlayLEDMask)
    revFlashAdvance : FlashLED(RobotInfo::AdvanceLEDMask)

    revPlayHowl : MySoundNode("howl.wav")
    revPlayBark : MySoundNode("barklow.wav")
    revPlayPing : MySoundNode("ping.wav")

    // The transition loop for the second set of nodes.
    {revFlashPower, revPlayHowl} =C(1)=> {revFlashAdvance, revPlayPing} =C(1)=>
      {revFlashPlay, revPlayBark} =C(1)=> {revFlashPower, revPlayHowl}

    // Button transitions between the first and second group of nodes (first group described above)
    {revFlashPower, revPlayHowl} =B(RobotInfo::BumpLeftButOffset, activateETID)=> {flashPlay, playBark}
    {revFlashPlay, revPlayBark} =B(RobotInfo::BumpLeftButOffset, activateETID)=> {flashAdvance, playPing}
    {revFlashAdvance, revPlayPing} =B(RobotInfo::BumpLeftButOffset, activateETID)=> {flashPower, playHowl}
  }
}

REGISTER_BEHAVIOR(SyncLEDBark);
