#include <U8g2lib.h>

U8G2LOG u8g2log;
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0);

// Physical pixel dimensions are 128x64. The library starts at 0 instead of 1
#define OLED_WIDTH 127 
#define OLED_HEIGHT 63

// Character dimensions, not pixel dimensions
#define U8G2LOG_WIDTH 24
#define U8G2LOG_HEIGHT 4

#define MIDI_MIN_VALUE 0
#define MIDI_MAX_VALUE 127

#define PRESET_BUTTON_COUNT 4

u8g2_uint_t pixelsForTiles(uint8_t tileValue) {
  return tileValue * 8;
}

// Clear and (re)draw the static display components
void displayInit(bool clearBuffer = false) {
  if (clearBuffer) { u8g2.clearBuffer(); }

  // Preset headers
  u8g2.setFont(u8g2_font_6x12_tf);
  u8g2.drawStr(0, 10, "Active");
  u8g2.drawStr(48, 10, "Range");

  // Horizontal log divider
  u8g2.drawHLine(0, 31, 93);

  // Draw the expression pedal frame
  u8g2.setFont(u8g2_font_5x7_tf);
  u8g2.drawStr(109, 6, "EXP");
  u8g2.drawFrame(111, 7, 10, 50);

  u8g2.sendBuffer();
}

void drawGrid() {
  for (int i = 7; i <= 63; i = i + 8) {
    u8g2.drawHLine(0, i, 128);
  }

  for (int i = 7; i <= 127; i = i + 8) {
    u8g2.drawVLine(i, 0, 64);
  }

  u8g2.sendBuffer();
}

void drawActivePreset(int presetNum) {
  char buf[5];

  if (programNumber >= 0 && programNumber <= 127)
  {
    snprintf(buf, 5, "%d", programNumber);
  }
  else
  {
    snprintf(buf, 5, "-");
  }

  u8g2.clearBuffer();

  u8g2.setFont(u8g2_font_6x12_tf);
  u8g2.drawStr(0, 23, buf);
  u8g2.updateDisplayArea(0, 2, 3, 1);
}

void drawPresetRange(int multiplier) {
  u8g2.clearBuffer();

  u8g2.setFont(u8g2_font_6x12_tf);
  u8g2.drawStr(48, 23, "108-127");
  u8g2.updateDisplayArea(6, 2, 6, 1);
}

void drawExpressionPedalLevel() {
  u8g2.clearBuffer();

  u8g2.drawBox(112, 30, 8, OLED_HEIGHT - 7);
  u8g2.updateDisplayArea(14, 1, 1, 6);
}

void drawLogLine(char *message) {
  u8g2log.print(message);
  u8g2log.print("\n");

  u8g2.setFont(u8g2_font_tom_thumb_4x6_mf);		// set the font for the terminal window
  u8g2.drawLog(0, 41, u8g2log);
  u8g2.updateDisplayArea(0, 4, 12, 4);
}

uint8_t u8g2log_buffer[U8G2LOG_WIDTH * U8G2LOG_HEIGHT];

void setup() {
  pinMode(11, INPUT);
  pinMode(12, INPUT);

  u8g2.begin();
  u8g2.clearBuffer();

  u8g2log.begin(U8G2LOG_WIDTH, U8G2LOG_HEIGHT, u8g2log_buffer);
  u8g2log.setLineHeightOffset(1);
  u8g2log.setRedrawMode(0);

  // drawGrid();
  displayInit();
  drawActivePreset(0);
  drawPresetRange(1);
  drawExpressionPedalLevel();

  drawLogLine("MIDI controller ready");
} 

void loop() {
  bool upButtonValue = digitalRead(12);
  bool downButtonValue = digitalRead(11);

  if (upButtonValue == HIGH) {
    drawLogLine("Preset Range Up");
  }

    if (downButtonValue == HIGH) {
    drawLogLine("Preset Range Down");
  }

  // char buf[1];
  // for (int i = 0; i < 128; i++) {
  //   snprintf(buf, 12, "Channel %d", i);
  //   drawLogLine(buf);
  // }

  // delay(300);
  // drawLogLine("CC Out: 40 -> 0");
  // delay(1000);

  // drawLogLine("CC Out: 41 -> 127");
  // delay(2000);
}