#include <MIDIUSB.h>

int OctaveDown = A1;
int OctaveUp = A2;
int OctaveLed = A3;

int StartOctave = 4;
int CurrentOctave;
int PreviousOctave;

const int NoteButtons = 12;
const int BUTTON_PIN[NoteButtons] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 14, 15};

int buttonCState[NoteButtons] = {};
int buttonPState[NoteButtons] = {};


unsigned long lastDebounceTime[NoteButtons] = {0};
unsigned long debounceDelay = 80;

byte midiCh = 1;
byte note = 0;

int midiMapped = 0;
int lastmidiMapped = 0;

void noteOn(byte channel, byte pitch, byte midiMapped) {
  midiEventPacket_t noteOn = {0x09, 0x90 | channel, pitch, midiMapped};
  MidiUSB.sendMIDI(noteOn);
}

void noteOff(byte channel, byte pitch, byte velocity) {
  midiEventPacket_t noteOff = {0x08, 0x80 | channel, pitch, velocity};
  MidiUSB.sendMIDI(noteOff);
}

void setup() {
  Serial.begin(115200);

  pinMode(OctaveDown, INPUT_PULLUP);
  pinMode(OctaveUp, INPUT_PULLUP);
  pinMode(OctaveLed, OUTPUT);
  CurrentOctave = StartOctave;
  note = 48;

  for (int i = 0; i < NoteButtons; i++) {
    pinMode(BUTTON_PIN[i], INPUT_PULLUP);
  }
}


void loop() {
  Buttons();
  OctaveButtons();
}

void Buttons() {
  if (midiMapped > 5) {
    for (int i = 0; i < NoteButtons; i++) {
      buttonCState[i] = digitalRead(BUTTON_PIN[i]);
      if (buttonCState[i] == LOW) {
        noteOn(midiCh, note + i, midiMapped);
        MidiUSB.flush();
      }
      if (buttonCState[i] == HIGH || midiMapped <= 10) {
        noteOff(midiCh, note + i, 0);
        MidiUSB.flush();
      }
    }
  }
}

void OctaveButtons() {

  int sensorValue = analogRead(A0);
  midiMapped = map(sensorValue, 25, 100, 0, 127);

  int OctaveDownStatus = digitalRead(OctaveDown);
  int OctaveUpStatus = digitalRead(OctaveUp);

  //  Serial.print('\n');
  //  Serial.print(note);
  //  Serial.print('\n');
  //  Serial.print(CurrentOctave);

  if (OctaveDownStatus == LOW && OctaveUpStatus == HIGH) {
    delay(200);
    CurrentOctave = CurrentOctave - 1;
    PreviousOctave = CurrentOctave;
    note = note - 12;
    //    Serial.print('\n');
    //    Serial.print(CurrentOctave);
  }
  if (OctaveUpStatus == LOW && OctaveDownStatus == HIGH) {
    delay(200);
    CurrentOctave = CurrentOctave + 1;
    PreviousOctave = CurrentOctave;
    note = note + 12;
    //    Serial.print('\n');
    //    Serial.print(CurrentOctave);
  }

  if (OctaveDownStatus == LOW && OctaveUpStatus == LOW) {
    delay(200);

    CurrentOctave = 4;
    PreviousOctave = CurrentOctave;
    note = 48;
  }

  if (CurrentOctave == 4) {
    digitalWrite(A3, HIGH);
  }
  if (CurrentOctave != 4) {
    digitalWrite(A3, LOW);
  }
}
