<<<<<<< HEAD
#include <Keyboard.h>

// TODO: LED Config
//#include <Adafruit_NeoPixel.h>

// Keys
//
#define KEY_KEYPAD_0        48
#define KEY_KEYPAD_1        49
#define KEY_KEYPAD_2        50
#define KEY_KEYPAD_3        51
#define KEY_KEYPAD_4        52
#define KEY_KEYPAD_5        53
#define KEY_KEYPAD_6        54
#define KEY_KEYPAD_7        55
#define KEY_KEYPAD_8        56
#define KEY_KEYPAD_9        57
#define KEY_KEYPAD_DECIMAL  60  // 46
#define KEY_KEYPAD_PLUS     223 // no
#define KEY_KEYPAD_MINUS    222 // 45
#define KEY_KEYPAD_MULTIPLY 221 // 42  // no
#define KEY_KEYPAD_DIVIDE   220 // 47
#define KEY_KEYPAD_NUMLOCK  -1
#define KEY_KEYPAD_EQUALS   10
#define DO_NOTHING          00

// IO
byte cols[] = {9, 8, 7, 6};         // Entradas
byte rows[] = {18, 15, 14, 16, 10}; // Salidas

// TODO: LED Config
//
//byte ledPin = 5;
//byte ledCount = 17;

const int colCount = sizeof(cols) / sizeof(cols[0]);
const int rowCount = sizeof(rows) / sizeof(rows[0]);

// TODO: LED Config
//
//Adafruit_NeoPixel pixels(ledCount, ledPin, NEO_GRB + NEO_KHZ800);

// Layouts
int layout[5][4] = {
  {KEY_KEYPAD_NUMLOCK, KEY_KEYPAD_DIVIDE, KEY_KEYPAD_MULTIPLY, KEY_KEYPAD_MINUS},
  {KEY_KEYPAD_7, KEY_KEYPAD_8, KEY_KEYPAD_9, KEY_KEYPAD_0},
  {KEY_KEYPAD_4, KEY_KEYPAD_5, KEY_KEYPAD_6, KEY_KEYPAD_PLUS},
  {KEY_KEYPAD_1, KEY_KEYPAD_2, KEY_KEYPAD_3, KEY_KEYPAD_0},
  {KEY_KEYPAD_0, KEY_KEYPAD_DECIMAL, KEY_RETURN, KEY_KEYPAD_0}
};

int shiftedLayout[5][4] = {
  {KEY_KEYPAD_NUMLOCK, KEY_KEYPAD_DIVIDE, KEY_KEYPAD_MULTIPLY, KEY_KEYPAD_MINUS},
  {KEY_HOME, KEY_UP_ARROW, KEY_PAGE_UP, DO_NOTHING},
  {KEY_LEFT_ARROW, DO_NOTHING, KEY_RIGHT_ARROW, KEY_KEYPAD_PLUS},
  {KEY_END, KEY_DOWN_ARROW, KEY_PAGE_DOWN, DO_NOTHING},
  {KEY_INSERT, KEY_DELETE, KEY_RETURN, KEY_KEYPAD_0}
};

int currentLayout[5][4];

int longPressDelay = 350;
int spamSpeed = 15;

int keyDown[5][4];
bool keyLong[5][4];

bool shifted = false;

void setup() {
  memcpy(currentLayout, layout, sizeof(layout));
  
  for (int i = 0; i < colCount; i++) {
    pinMode(cols[i], INPUT_PULLUP);
  }
  for (int i = 0; i < rowCount; i++) {
    pinMode(rows[i], OUTPUT);
    digitalWrite(rows[i], HIGH);
  }
  
  Keyboard.begin();

  //
  // TODO: LED Config
  //
  //pinMode(ledPin, OUTPUT);
  //pixels.begin();
  //
  //for (int i = 0; i < ledCount; i++) {
  //  pixels.setPixelColor(i, 50, 50, 50);
  //}
  //pixels.show();
  
}

void loop() {
  for (int i = 0; i < rowCount; i++) {
    digitalWrite(rows[i], LOW);
    delayMicroseconds(5);
  
    for (int j = 0; j < colCount; j++) {
      if (digitalRead(cols[j]) == LOW) {
        keyPressed(i, j);
      } else if (keyDown[i][j] != 0) {
        resetKey(i, j);
      }
    }

    digitalWrite(rows[i], HIGH);
    delayMicroseconds(500);
  }
  
}

void keyPressed(int row, int col) {
  if (keyDown[row][col] == 0) {
    if (currentLayout[row][col] == KEY_KEYPAD_NUMLOCK) {
      if (shifted){
        shifted = false;
        memcpy(currentLayout, layout, sizeof(layout));
      } else {
        shifted = true;
        memcpy(currentLayout, shiftedLayout, sizeof(shiftedLayout));
      }
    } else {
      Keyboard.write(currentLayout[row][col]); 
    }
  } else if (keyLong[row][col] && keyDown[row][col] > spamSpeed) {
    if (currentLayout[row][col] == KEY_KEYPAD_NUMLOCK) {
      if (shifted){
        shifted = false;
        memcpy(currentLayout, layout, sizeof(layout));
      } else {
        shifted = true;
        memcpy(currentLayout, shiftedLayout, sizeof(shiftedLayout));
      }
    } else {
      Keyboard.write(currentLayout[row][col]);
      keyDown[row][col] = 1;
    }
  } else if (keyDown[row][col] > longPressDelay) {
    keyLong[row][col] = true;
  }

  keyDown[row][col]++;
}

void resetKey(int row, int col) {
  keyDown[row][col] = 0;
  keyLong[row][col] = false;
=======
>>>>>>> 6d38bb4a8060dbb25b823b341264b72dd73cebf1
}
