/*
  LedControl Demo
  Arduino | coding-help
  change the LED lighting pattern using a button
  Inspired by
  IWASAN-jp(using GoogleTranslate) & Jordan Belfort
*/

#include <LedControl.h>

const int NUM_BTNS = 4;
const int DATA_PIN  = 2;
const int CS_PIN    = 3;
const int CLOCK_PIN = 4;
const int BTN_PINS[] = {23, 25, 27, 29};
const boolean patterns[NUM_BTNS + 1][8][8] = {
  // square, on start up
  {
    { 1, 1, 1, 1, 1, 1, 1, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 1, 1, 1, 1, 1, 1, 1 }
  },
  // circle
  {
    { 0, 0, 1, 1, 1, 1, 0, 0 },
    { 0, 1, 1, 0, 0, 1, 1, 0 },
    { 1, 1, 0, 0, 0, 0, 1, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 1, 0, 0, 0, 0, 1, 1 },
    { 0, 1, 1, 0, 0, 1, 1, 0 },
    { 0, 0, 1, 1, 1, 1, 0, 0 }
  },
  // sad
  {
    { 0, 1, 1, 1, 1, 1, 1, 0 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 1, 0, 0, 1, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 1, 1, 0, 0, 1 },
    { 1, 0, 1, 0, 0, 1, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 0, 1, 1, 1, 1, 1, 1, 0 }
  },
  // neutral
  {
    { 0, 0, 1, 1, 1, 1, 0, 0 },
    { 0, 1, 0, 0, 0, 0, 1, 0 },
    { 1, 0, 1, 0, 0, 1, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 1, 1, 1, 1, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 0, 1, 0, 0, 0, 0, 1, 0 },
    { 0, 0, 1, 1, 1, 1, 0, 0 }
  },
  // happy
  {
    { 0, 0, 1, 1, 1, 1, 0, 0 },
    { 0, 1, 0, 0, 0, 0, 1, 0 },
    { 1, 0, 1, 0, 0, 1, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 1, 0, 0, 1, 0, 1 },
    { 1, 0, 0, 1, 1, 0, 0, 1 },
    { 0, 1, 0, 0, 0, 0, 1, 0 },
    { 0, 0, 1, 1, 1, 1, 0, 0 }
  }
};

int btnState[NUM_BTNS];
int oldBtnState[NUM_BTNS];

LedControl lc = LedControl(DATA_PIN, CLOCK_PIN, CS_PIN, 1);

int checkButton(int number) {
  int mode = 0;
  btnState[number] = digitalRead(BTN_PINS[number]);
  if (btnState[number] != oldBtnState[number]) {
    oldBtnState[number] = btnState[number];
    if (btnState[number] == LOW)  {
      Serial.print("Button ");
      Serial.print(number + 1);
      Serial.println(" pressed.");
      mode = number + 1;
    }
    delay(20);  // debounce
  }
  return mode;
}

void showPattern(int number)  {
  for (int row = 0; row < 8; row++) {
    for (int col = 0; col < 8; col++) {
      lc.setLed(0, row, col, patterns[number][row][col]);
    }
  }
}

void setup() {
  Serial.begin(9600);
  lc.shutdown(0, false);
  lc.setIntensity(0, 8);
  lc.clearDisplay(0);
  for (int i = 0; i < NUM_BTNS; ++i) {
    pinMode(BTN_PINS[i], INPUT_PULLUP);
  }
  pinMode(DATA_PIN, OUTPUT);
  pinMode(CS_PIN, OUTPUT);
  pinMode(CLOCK_PIN, OUTPUT);
  Serial.println("Press a button!");
  showPattern(0);
}

void loop() {
  int mode = 0;
  for (int i = 0; i < NUM_BTNS; i++) {
    mode = checkButton(i);
    if (mode > 0)  {
      showPattern(mode);
    }
  }
}