# define SEVEN   7    // puzzle size

# include <Adafruit_NeoPixel.h>

# define LED_PIN    A2
# define LED_COUNT  SEVEN

Adafruit_NeoPixel disaply(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);

unsigned char combo[SEVEN];

# define redLED   A1    // bad
# define greenLED A0    // good

# define NOKEY  99

const byte inputPin[SEVEN] = {2, 3, 4, 5, 6, 7, 8, };

void setup() {
  Serial.begin(115200); Serial.println("HE LL O!\n");

  for (unsigned char ii = 0; ii < SEVEN; ii++)
    pinMode(inputPin[ii], INPUT_PULLUP);
  
  pinMode(greenLED, OUTPUT);
  pinMode(redLED, OUTPUT);

  disaply.begin();
  disaply.show();

  reset();
  newCombo();
}

unsigned char nIn = 0;    // number of correct steps taken sofa

void loop() {
  unsigned char pKey = scanKeys();

  if (pKey == NOKEY)
    return;

// presst a key, all key are valid so

  if (pKey == combo[nIn]) {
    nIn++;
    displayDisplay();   
    goodFlash();


    if (nIn == SEVEN) {
      nIn = 0;
      reward();
      newCombo();
      reset();
      displayDisplay();
    }
  }
  else {
    badFlash();
    reset();
    displayDisplay();
  }
}

void goodFlash()
{
  digitalWrite(A1, HIGH);
  delay(100);
  digitalWrite(A1, LOW);

  displayDisplay();
}

void badFlash()
{
  digitalWrite(A0, HIGH);
  delay(50);
  digitalWrite(A0, LOW); 
  delay(50);
  digitalWrite(A0, HIGH);
  delay(50);
  digitalWrite(A0, LOW);
  delay(50);
  digitalWrite(A0, HIGH);
  delay(50);
  digitalWrite(A0, LOW); 

  displayDisplay();

  Serial.println("             BZZZT!");
}


//       "attrs": { "color": "green", "label" : "X" }


void reward()
{
  nIn = 0; displayDisplay();
  digitalWrite(A1, HIGH);
  delay(600);
  nIn = SEVEN; displayDisplay();
  digitalWrite(A1, LOW);
  delay(600);
  nIn = 0; displayDisplay();
  digitalWrite(A1, HIGH);
  delay(600);
  nIn = SEVEN; displayDisplay();
  digitalWrite(A1, LOW);
  delay(600);
  nIn = 0; displayDisplay();
  digitalWrite(A1, HIGH);
  delay(600);
  nIn = SEVEN; displayDisplay();
  digitalWrite(A1, LOW);
  delay(600);
  nIn = 0; displayDisplay();

  Serial.println("You are in!");
}

void reset()
{
  nIn = 0;
}

void displayDisplay()
{
  for (unsigned char tt = 0; tt < SEVEN; tt++)
    disaply.setPixelColor(tt, tt >= nIn ? 0x001010 : 0x00ff00);

  disaply.show();
}

unsigned char scanKeys()
{
// printf("scan keys ");
  unsigned char newKeyQ = NOKEY;

  static unsigned long lastTime;
  static unsigned char wasPressed = 0;

  char isPressed = 0;
  unsigned char currentKey = NOKEY;
  unsigned long now = millis();

  if (now - lastTime < 40)
    return currentKey;

  for (unsigned char ii = 0; ii < SEVEN; ii++) {
    if (!digitalRead(inputPin[ii])) {
      newKeyQ = ii;
      isPressed = 1;
    }
  }

  if (isPressed != wasPressed) {
    lastTime = now;
    if (isPressed)
      currentKey = newKeyQ;
    wasPressed = isPressed;
  }
  
  return currentKey;
}

void newCombo()
{
  for (unsigned char ii = 0; ii < SEVEN; ii++)
    combo[ii] = ii;

  for (int ii = 0; ii < 5000; ii++) {
    unsigned char tt = random(SEVEN);
    unsigned char ss = random(SEVEN);
    unsigned char temp;
        
    temp = combo[tt];
    combo[tt] = combo[ss];
    combo[ss] = temp;
  }
}