

#include "magicSwitchBoard.h"

#define CHANNELS 3
#define TIMEOUT 7000 //game timeout

typedef enum
{
  idle,
  learn,
  active,
  last
} states;

states state = last;
uint8_t sequence[CHANNELS] = {0xFF, 0xFF, 0xFF};
const uint8_t buttonIndex[CHANNELS] = {1, 2, 3};
const uint32_t leds[CHANNELS] = {LED1, LED2, LED3};

uint64_t lastTime = 0;

uint8_t learnIndex = 0;

void showLeds(void)
{
  //loop through the button list
  for (int i = 0; i < CHANNELS; i++)
  {
    //get the button pointer
    c_button *currentbutton = getButton(buttonIndex[sequence[i]]);

    //verify that the button pointer is not NULL
    if (currentbutton == NULL)
    {
      break;
    }

    //if the button is pressed, show LED or not
    if (currentbutton->isPressed() == true)
    {
      //check if the position is already programmed
      //write sequence led on
      digitalWrite(leds[i], 1);
    }
    else
    {
      //write sequence led off
      digitalWrite(leds[i], 0);
    }
  }
}

void resetMagicSwitchBoard(void)
{
  state = idle;
  lastTime = 0;
  learnIndex = 0;
  for (int i = 0; i < CHANNELS; i++)
  {
    sequence[i] = 0xff;
    digitalWrite(leds[i], 0);
  }
}

bool CheckTimeOut(void)
{
  uint64_t currentmillis = millis();
  if(!lastTime)
  {
    lastTime = currentmillis;
  }

  //check if lastTime is initialized or timeout expired
  if ((currentmillis - lastTime > TIMEOUT))
  {
    //handle timeout
    resetMagicSwitchBoard();
    return true;
  }
  else
  {
    if (anybutton())
    {
      //game in progress, update timer
      lastTime = currentmillis;
    }
  }
  return false;
}

void handleLearn(void)
{
  for (int i = 0; i < CHANNELS; i++)
  {
    c_button *currentbutton = getButton(buttonIndex[i]);
    if (currentbutton == NULL)
    {
      return;
    }

    if (currentbutton->isPressed())
    {
      bool duplicate = false;
      for (int n = 0; n < CHANNELS; n++)
      {
        if (i == sequence[n])
        {
          duplicate = true;
        }
      }

      if (!duplicate)
      {
        sequence[learnIndex] = i;
        learnIndex++;
      }
    }
  }
  if (learnIndex == CHANNELS)
  {
    state = active;
  }
}

void handleIdle(void)
{
  if (anybutton())
  {
    state = learn;
  }
  else
  {
    for (auto &&i : leds)
    {
      digitalWrite(i, 0);
    }
  }
}

void handleMagicSwitchBoard(void)
{
  switch (state)
  {
  case idle:
  {
    handleIdle();
  }
  break;

  case learn:
  {
    handleLearn();
  }
  break;

  case active:
  {
    CheckTimeOut();
  }
  break;

  default:
  {
    state = idle;
  }
  break;
  }
  showLeds();

  
}


