#include <FastLED.h>

// FASTLED
#define NUM_LEDS             256
#define DATA_PIN             13  

#define MAX_BRIGHTNESS      200
#define MIN_BRIGHTNESS       50
#define FRAMES_PER_SECOND    60

#define  ROWS 16
#define  COLS 16

uint16_t keys[ROWS][COLS];
uint16_t leds[ROWS][COLS];

uint8_t colPins[COLS] = { 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53 }; // Pins connected to R1, R2, R3, R4

CRGB led[NUM_LEDS];  
uint8_t hue = 0;


//-------------------------------------------------------------
void putLeds(){
  int pos = 0;
  for (int x=0; x < COLS; x++) {  
    for (int y=0; y < ROWS; y++) {  
      if(leds[x][y] == 1) {
        led[pos++] = CRGB::Red; 
      } else {
        led[pos++] = CRGB(238, 255, 0); 
      }
    } 
  }
  FastLED.show();
}

//------------------------------------------------------------
uint16_t getKey() {

  uint16_t k = -1;

  // Reset all
  for (uint8_t x=0; x < COLS; x++) {  digitalWrite(colPins[x], HIGH); }

  //Bit schreiben
  for (uint8_t x=0; x < COLS; x++) { 
    digitalWrite(colPins[x], LOW);  // Bit setzen

    //Bit lesen
    for (uint8_t y=0; y < ROWS; y++) { 
      uint16_t key = digitalRead(rowPins[y]);
      if (key == LOW) {
        k = keys[x][y];
        leds[x][y] = 1; 
      }
    }
    digitalWrite(colPins[x], HIGH);  // Bit rücksetzen 
  } 
  return k;
}



//----------------------------------------------------------------
void clearLeds() { 
   for (uint8_t x=0; x<COLS; x++) { 
    for (uint8_t y=0; y<ROWS; y++) {
       leds[x][y] = 0;
    }
  }
}


void rainbow() {
  for (int i = 0; i < NUM_LEDS; ++i) {
    led[i] = CHSV(hue + (i * 10), 255, 255);
  }
  //You can change the pattern speed here
  EVERY_N_MILLISECONDS(15){
    hue++;
  }
  FastLED.show();
}


//----------------------------------------------------------------
void setup() {
  Serial.begin(9600);

  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(led, NUM_LEDS);
  FastLED.setBrightness(MAX_BRIGHTNESS);
  
  // Init Array
  // 0 1 2 3 
  // 7 6 5 4
  // 8 9
 
  /*
  boolean sw = true;
  int value = 0;
  for (uint8_t x=0; x<COLS; x++) { 
    for (uint8_t y=0; y<ROWS; y++) { 
      if(sw == true) {
        sw = !sw;
        keys[x][y] = value++;
      } else {
        sw = !sw;
        keys[x][y] = pos;

      }
    }
  }
  */

  for (uint8_t i=0; i<COLS; i++) { pinMode(colPins[i] , OUTPUT); }
  for (uint8_t i=0; i<ROWS; i++) { pinMode(rowPins[i] , INPUT_PULLUP); }
  
  
  clearLeds();
}



void loop() {

  uint16_t key;
  key = getKey();
  if (key != -1) { 
    Serial.println(key); 

  }
  rainbow();
  //putLeds();
  delay(200);
  
}

mega:SCL
mega:SDA
mega:AREF
mega:GND.1
mega:13
mega:12
mega:11
mega:10
mega:9
mega:8
mega:7
mega:6
mega:5
mega:4
mega:3
mega:2
mega:1
mega:0
mega:14
mega:15
mega:16
mega:17
mega:18
mega:19
mega:20
mega:21
mega:5V.1
mega:5V.2
mega:22
mega:23
mega:24
mega:25
mega:26
mega:27
mega:28
mega:29
mega:30
mega:31
mega:32
mega:33
mega:34
mega:35
mega:36
mega:37
mega:38
mega:39
mega:40
mega:41
mega:42
mega:43
mega:44
mega:45
mega:46
mega:47
mega:48
mega:49
mega:50
mega:51
mega:52
mega:53
mega:GND.4
mega:GND.5
mega:IOREF
mega:RESET
mega:3.3V
mega:5V
mega:GND.2
mega:GND.3
mega:VIN
mega:A0
mega:A1
mega:A2
mega:A3
mega:A4
mega:A5
mega:A6
mega:A7
mega:A8
mega:A9
mega:A10
mega:A11
mega:A12
mega:A13
mega:A14
mega:A15
neopixels5:DOUT
neopixels5:VDD
neopixels5:VSS
neopixels5:DIN
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
btn4:1.l
btn4:2.l
btn4:1.r
btn4:2.r
btn5:1.l
btn5:2.l
btn5:1.r
btn5:2.r
btn6:1.l
btn6:2.l
btn6:1.r
btn6:2.r
neopixels1:DOUT
neopixels1:VDD
neopixels1:VSS
neopixels1:DIN
neopixels2:DOUT
neopixels2:VDD
neopixels2:VSS
neopixels2:DIN
neopixels3:DOUT
neopixels3:VDD
neopixels3:VSS
neopixels3:DIN
neopixels4:DOUT
neopixels4:VDD
neopixels4:VSS
neopixels4:DIN
neopixels6:DOUT
neopixels6:VDD
neopixels6:VSS
neopixels6:DIN
neopixels7:DOUT
neopixels7:VDD
neopixels7:VSS
neopixels7:DIN
neopixels8:DOUT
neopixels8:VDD
neopixels8:VSS
neopixels8:DIN
neopixels9:DOUT
neopixels9:VDD
neopixels9:VSS
neopixels9:DIN
neopixels10:DOUT
neopixels10:VDD
neopixels10:VSS
neopixels10:DIN
neopixels11:DOUT
neopixels11:VDD
neopixels11:VSS
neopixels11:DIN
neopixels12:DOUT
neopixels12:VDD
neopixels12:VSS
neopixels12:DIN
neopixels13:DOUT
neopixels13:VDD
neopixels13:VSS
neopixels13:DIN
neopixels14:DOUT
neopixels14:VDD
neopixels14:VSS
neopixels14:DIN
neopixels15:DOUT
neopixels15:VDD
neopixels15:VSS
neopixels15:DIN
neopixels16:DOUT
neopixels16:VDD
neopixels16:VSS
neopixels16:DIN