#include "GameBuzzer.h"
#include <Arduino.h>

GameBuzzer::GameBuzzer(const int pin)
  : m_pin(pin), m_lastUpdateMs(0xFFFF - GAMEBUZZ_DELAY_MS), m_currentSound(EGameSound::NONE), m_stepCounter(0) { }


bool GameBuzzer::hitRoutine(void) {
  if (m_stepCounter == 0) {
    digitalWrite(m_pin, HIGH);
    return true;
  }

  digitalWrite(m_pin, LOW);
  return false;
}

bool GameBuzzer::missRoutine(void) {
  if ((m_stepCounter % 2) == 0) {
    digitalWrite(m_pin, HIGH);
  } else {
    digitalWrite(m_pin, LOW);
  }

  if (m_stepCounter == 3) {
    return false;
  }
  
  return true;
}

bool GameBuzzer::gameOverRoutine(void) {
  if (m_stepCounter < 5) {
    if ((m_stepCounter % 2) == 0) {
      digitalWrite(m_pin, HIGH);
    } else {
      digitalWrite(m_pin, LOW);
    }
  }
  else if (m_stepCounter == 5) {
    digitalWrite(m_pin, HIGH);
  }
  else if (m_stepCounter == 8) {
    digitalWrite(m_pin, LOW);
    return false;
  }

  return true;
}

bool GameBuzzer::resetRoutine(void) {
  if ((m_stepCounter % 3) == 0) {
    if (((m_stepCounter / 3) % 2) == 0) {
      digitalWrite(m_pin, HIGH);
    } else {
      digitalWrite(m_pin, LOW);
    }
  }
  
  if (m_stepCounter == 9) {
    return false;
  }

  return true;
}


void GameBuzzer::init(void) {
  pinMode(m_pin, OUTPUT);
  digitalWrite(m_pin, LOW);
}

void GameBuzzer::update(void) {
  if ((m_currentSound != EGameSound::NONE) && ((millis() - m_lastUpdateMs) > GAMEBUZZ_DELAY_MS)) {
    switch (m_currentSound) {
      case EGameSound::HIT:
        if (!hitRoutine()) {
          m_currentSound = EGameSound::NONE;
        }
        break;

      case EGameSound::MISS:
        if (!missRoutine()) {
          m_currentSound = EGameSound::NONE;
        }
        break;

      case EGameSound::GAME_OVER:
        if (!gameOverRoutine()) {
          m_currentSound = EGameSound::NONE;
        }
        break;
        
      case EGameSound::RESET:
        if (!resetRoutine()) {
          m_currentSound = EGameSound::NONE;
        }
        break;
    }

    m_stepCounter++;
    m_lastUpdateMs = millis();
  }
}

void GameBuzzer::playSound(EGameSound sound) {
  m_stepCounter = 0;
  m_lastUpdateMs = (millis() - GAMEBUZZ_DELAY_MS);
  m_currentSound = sound;
}