#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>

#define PIN 2
#define MAX_X 16
#define MAX_Y 16

// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
//   NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
//     Position of the FIRST LED in the matrix; pick two, e.g.
//     NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
//   NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
//     rows or in vertical columns, respectively; pick one or the other.
//   NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
//     in the same order, or alternate lines reverse direction; pick one.
//   See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_GRBW    Pixels are wired for GRBW bitstream (RGB+W NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)


// Example for NeoPixel Shield.  In this application we'd like to use it
// as a 5x8 tall matrix, with the USB port positioned at the top of the
// Arduino.  When held that way, the first pixel is at the top right, and
// lines are arranged in columns, progressive order.  The shield uses
// 800 KHz (v2) pixels that expect GRB color data.
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(MAX_X, MAX_Y, PIN,
  NEO_MATRIX_TOP     + NEO_MATRIX_RIGHT +
  NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB            + NEO_KHZ800);

// define the button pins and states
#define LEFT 18
#define RIGHT 19
#define UP 20
#define DOWN 21
#define STOP 0
#define PAUSE 1
#define OVER 2

// we start with a stopped snake
int direction = STOP;

// snake and apple have xy coordinates
struct COORDS{
  int x;
  int y;
};
COORDS snake[MAX_X * MAX_Y];
int snake_len = 0;
COORDS apple;

void setup() {
  matrix.begin();

  // we use INPUT_PULLUP instead of hardware resistors at the buttons
  pinMode(LEFT, INPUT_PULLUP);
  pinMode(RIGHT, INPUT_PULLUP);
  pinMode(UP, INPUT_PULLUP);
  pinMode(DOWN, INPUT_PULLUP);

  // Buttons are handled by interrupts, so no problems with delay()
  // if a button is pressed the ButtonPress funktion is called
  attachInterrupt(digitalPinToInterrupt(UP), ButtonPress, FALLING);
  attachInterrupt(digitalPinToInterrupt(DOWN), ButtonPress, FALLING);
  attachInterrupt(digitalPinToInterrupt(LEFT), ButtonPress, FALLING);
  attachInterrupt(digitalPinToInterrupt(RIGHT), ButtonPress, FALLING);

  // first snake position
  snake[0].x = random(0, MAX_X);
  snake[0].y = random(0, MAX_Y);
}

// the interrupt service for th buttons, gets called then a button is pressed
void ButtonPress() { 
  if(digitalRead(LEFT) == LOW){
    if(direction == RIGHT)
      direction = OVER;
    else
      direction = LEFT;
  }
  if(digitalRead(RIGHT) == LOW){
    if(direction == LEFT)
      direction = OVER;
    else
      direction = RIGHT;
  }
  if(digitalRead(UP) == LOW){
    if(direction == DOWN)
      direction = OVER;
    else
      direction = UP;
  }
  if(digitalRead(DOWN) == LOW){
    if(direction == UP)
      direction = OVER;
    else
      direction = DOWN;
  }
}

void loop() {
  matrix.fillScreen(0);
  delay(200);
  if(direction == LEFT){
    matrix.drawPixel(0, 7, matrix.Color(0, 0, 255));
  }
  if(direction == RIGHT){
    matrix.drawPixel(15, 8, matrix.Color(0, 0, 255));
  }
  if(direction == UP){
    matrix.drawPixel(7, 0, matrix.Color(0, 0, 255));
  }
  if(direction == DOWN){
    matrix.drawPixel(7, 15, matrix.Color(0, 0, 255));
  }
  if(direction == OVER){
    matrix.drawPixel(7, 7, matrix.Color(255, 0, 0));
  }
  matrix.show();
  delay(200);
}
uno:SCL
uno:SDA
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:14
uno:15
uno:16
uno:17
uno:18
uno:19
uno:20
uno:21
uno:5V.1
uno:5V.2
uno:22
uno:23
uno:24
uno:25
uno:26
uno:27
uno:28
uno:29
uno:30
uno:31
uno:32
uno:33
uno:34
uno:35
uno:36
uno:37
uno:38
uno:39
uno:40
uno:41
uno:42
uno:43
uno:44
uno:45
uno:46
uno:47
uno:48
uno:49
uno:50
uno:51
uno:52
uno:53
uno:GND.4
uno:GND.5
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
uno:A6
uno:A7
uno:A8
uno:A9
uno:A10
uno:A11
uno:A12
uno:A13
uno:A14
uno:A15
neopixels:DOUT
neopixels:VDD
neopixels:VSS
neopixels:DIN
btn0:1.l
btn0:2.l
btn0:1.r
btn0:2.r
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r