#include "U8g2lib.h" // Display Controls
//#include "HID-Project.h" // Nicohood HID - For Media Keys


// ------------------------------------------------------------------
// ENDCODER SETUP
// ------------------------------------------------------------------

// Used for generating interrupts using CLK signal
const int PinA = 7;

// Used for reading DT signal
const int PinB = 6;

// Used for the push button switch
const int PinSW = 5;

// Keep track of last rotary value
int lastCount = 50;

// Updated by the ISR (Interrupt Service Routine)
volatile int virtualPosition = 50;

// ------------------------------------------------------------------
// INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT     INTERRUPT
// ------------------------------------------------------------------
void isr ()  {
  static unsigned long lastInterruptTime = 0;
  unsigned long interruptTime = millis();

  // If interrupts come faster than 5ms, assume it's a bounce and ignore
  if (interruptTime - lastInterruptTime > 5) {
    if (digitalRead(PinB) == LOW)
    {
      virtualPosition-- ; // Could be -5 or -10
    }
    else {
      virtualPosition++ ; // Could be +5 or +10
    }

    // Restrict value from 0 to +100
    //virtualPosition = min(100, max(0, virtualPosition));

    // Keep track of when we were here last (no more than every 5ms)
    lastInterruptTime = interruptTime;

  }

}



U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0); // [page buffer, size = 128 bytes]
//U8GLIB_SSD1306_128X64 u8g(u8g2_I2C_OPT_DEV_0 | u8g2_I2C_OPT_NO_ACK | u8g2_I2C_OPT_FAST); // Fast I2C / TWI


//temp =============
int current_layer = 0;

const int NUM_LAYERS = 5;
//========================

/** DISPLAY **/

int potentiometer_value = 0;
int volume_bar = 0;
char buffer[20];
int string_width = 0;
int layer_0_string_width = 0;
int current_screen = 0;


// Delay for returning to Screen 0
unsigned long DELAY_TIME = 666; // wait for .666 sec
unsigned long delayStart = 0; // the time the delay started
bool delayRunning = false; // true if still waiting for delay to finish


char sliderNames[][20] = {

  "Master", //0
  //GROUPED
  "Media",  //1
  "Work",   //2
  "Talk",   //3
  "Play",    //4
  // MEDIA
  "Firefox",      //5
  "VLC",     //6
  "- - -",       //7
  "- - -",       //8
  // WORK
  "Vivaldi",     //9
  "AfterFX",      //10
  "Audacity",     //11
  "Unity",   //12
  //TALK
  "Discord",    //13
  "Skype",   //14
  "Teams",   //15
  "- - -",       //16
  //GAMES
  "StarB:FU",    //17
  "Factorio",    //18
  "- - -",       //19
  "- - -"       //20
  
  };


char sliderNameSet[][40] = {

  // Startvalues
  "MEDIA WORK TALK PLAY", //0
  "FF VLC - -",           //1
  "VIV AE AUD UNITY",     //2
  "DISC SKYPE TEAMS -",   //3
  "SB/FU FACT - -"        //4
  
  };

int sliderNameNumber; // used to store current slider name number

// ------------------------------------------------------------------
// SETUP    SETUP    SETUP    SETUP    SETUP    SETUP    SETUP
// ------------------------------------------------------------------
void setup() {

/** ENCODER **/

// Just whilst we debug, view output on serial monitor
  Serial.begin(115200);

  // Rotary pulses are INPUTs
  pinMode(PinA, INPUT);
  pinMode(PinB, INPUT);

  // Switch is floating so use the in-built PULLUP so we don't need a resistor
  pinMode(PinSW, INPUT_PULLUP);

  // Attach the routine to service the interrupts
  attachInterrupt(digitalPinToInterrupt(PinA), isr, LOW);

  // Ready to go!
  Serial.println("Start");
}


  /** DISPLAY **/ 

u8g2.setFont(u8g2_font_fub14_tf); // define font
u8g2.setColorIndex(1); // Set display color to white
u8g2.begin(); // Initialize Display


 Serial.begin(9600);

}



// ------------------------------------------------------------------
// MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP     MAIN LOOP
// ------------------------------------------------------------------
void loop() {

/** ENCODER **/

// Is someone pressing the rotary switch?
  if ((!digitalRead(PinSW))) {
    virtualPosition = 50;
    while (!digitalRead(PinSW))
      delay(10);
    Serial.println("Reset");
  }

  // If the current rotary switch position has changed then update everything
  if (virtualPosition != lastCount) {

    // Write out to serial monitor the value and direction
    Serial.print(virtualPosition > lastCount ? "Up  :" : "Down:");
    Serial.println(virtualPosition);

    // Keep track of this new value
    lastCount = virtualPosition ;
  }

  //delay(100);
}


/** DISPLAY **/

// set correct screen


if (delayRunning && ((millis() - delayStart) >= DELAY_TIME)) {
    delayRunning = false; // finished delay -- single shot, once only
    current_screen = 0; // Go back to current screen
  }


u8g2.firstPage();
      do {

        if (current_screen == 0) { // LAYER OVERVIEW

              int layer_0_box_width = 128; 
              int layer_0_box_height = 13;
              int layer_0_box_spacing = 4;
              int layer_0_box_x_pos = 0;
              int layer_0_box_y_pos = 1;
              int layer_0_corner_radius = 2;
              int layer_0_font_height = 10;
              int layer_0_font_x_pos = (128-(layer_0_string_width-1))/2;//31;
              int layer_0_font_y_pos = 14;//layer_0_box_y_pos + (layer_0_box_height-(layer_0_font_height/2));


          if (current_layer == 0) {
                     

              u8g2.setFont(u8g2_font_fub14_tf); // define font
              u8g2.setColorIndex(1); // set color to white
              u8g2.drawRBox(layer_0_box_x_pos, layer_0_box_y_pos, layer_0_box_width, layer_0_box_height, layer_0_corner_radius); //u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r#
              u8g2.setColorIndex(0); // set color to "black" or off
              //dtostrf("Master Control", 1, 0, buffer); // Write Current Layer number into string
              //string_width = u8g2.getStrWidth(buffer);

              u8g2.setColorIndex(0);// set color to black
              u8g2.drawBox(20, 0, 88, 14); // draw box to hide frame partially

              //Write Name of Layer
              u8g2.setColorIndex(1);
              //string_width = u8g2.getStrWidth(buffer);
              //u8g2.drawStr(layer_0_font_x_pos, layer_0_font_y_pos, "Master");
              layer_0_string_width = u8g2.getStrWidth(sliderNames[0]);
              u8g2.drawStr(layer_0_font_x_pos, layer_0_font_y_pos, sliderNames[0]);

              //Write Slider Set
              u8g2.setFont(u8g2_font_6x12_tf); // define font
              u8g2.setColorIndex(1);
              //sliderNameDisplay = sliderNameSet[j];  // assign correct Slidernameset
              //Serial.println(sliderNameSet[j]);                
              u8g2.drawStr(4, 64, sliderNameSet[0]); // use generated variable to draw string

            
            }

            else {

              u8g2.setFont(u8g2_font_fub14_tf); // define font
              u8g2.setColorIndex(1); // set color to white
              u8g2.drawRFrame(layer_0_box_x_pos, layer_0_box_y_pos, layer_0_box_width, layer_0_box_height, layer_0_corner_radius); //u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r#
              //dtostrf("Master Control", 1, 0, buffer); // Convert potentiometer value into str: Divide value by 10, max char width, number of decimals, write to [buffer]
              u8g2.setColorIndex(0);// set color to black
              u8g2.drawBox(20, 0, 88, 14); // draw box to hide frame partially
              
              u8g2.setColorIndex(1);
              //string_width = u8g2.getStrWidth(buffer);
              //u8g2.drawStr(layer_0_font_x_pos, layer_0_font_y_pos, "Master");
              layer_0_string_width = u8g2.getStrWidth(sliderNames[current_layer]);
              u8g2.drawStr(layer_0_font_x_pos, layer_0_font_y_pos, sliderNames[current_layer]);

            
            
            }
          

          for (int j = 1; j < NUM_LAYERS; j++) { // For each layer - change volume knob values
           
            int box_startvalue = j-1; // Used to position Layer 1 at x=0
            int box_width = 29; 
            int box_height = 29;
            int box_spacing = 4;
            int box_x_pos = (box_width*box_startvalue) + (box_spacing*box_startvalue);
            int box_y_pos = 21;//(64-box_height)/2;
            int corner_radius = 4;
            int font_height = 14;
            int font_x_pos = box_x_pos + ((box_width-(string_width-1))/2);
            int font_y_pos = box_y_pos + (box_height-(font_height/2));

            if (current_layer == j) { 
              

              u8g2.setFont(u8g2_font_fub14_tf); // define font
              u8g2.setColorIndex(1); // set color to white
              u8g2.drawRBox(box_x_pos, box_y_pos, box_width, box_height, corner_radius); //u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r#
              u8g2.setColorIndex(0); // set color to "black" or off
              dtostrf(j, 1, 0, buffer); // Write Current Layer number into string
              string_width = u8g2.getStrWidth(buffer);
              u8g2.drawStr(font_x_pos, font_y_pos, buffer);

              //Write Slider Set
              u8g2.setFont(u8g2_font_6x12_tf); // define font
              u8g2.setColorIndex(1);
              //sliderNameDisplay = sliderNameSet[j];  // assign correct Slidernameset
              //Serial.println(sliderNameSet[j]);                
              u8g2.drawStr(4, 64, sliderNameSet[j]); // use generated variable to draw string

            
            }

            else {

              u8g2.setFont(u8g2_font_fub14_tf); // define font
              u8g2.setColorIndex(1); // set color to white
              u8g2.drawRFrame(box_x_pos, box_y_pos, box_width, box_height, corner_radius); //u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r#
              dtostrf(j, 1, 0, buffer); // Convert potentiometer value into str: Divide value by 10, max char width, number of decimals, write to [buffer]
              string_width = u8g2.getStrWidth(buffer);
              u8g2.drawStr(font_x_pos, font_y_pos, buffer);

            }

          
          }


        }

        else if (current_screen == 1) { // VOLUME BAR

          //potentiometer_value = map(analogRead(analogInputs[0]), 0, 1023, 0, 100);
          //volume_bar = map(analogRead(analogInputs[0]), 0, 1023, 0, 128);

              int layer_0_box_width = 128; 
              int layer_0_box_height = 13;
              int layer_0_box_spacing = 4;
              int layer_0_box_x_pos = 0;
              int layer_0_box_y_pos = 1;
              int layer_0_corner_radius = 2;
              int layer_0_font_height = 10;
              int layer_0_font_x_pos = (128-(string_width-1))/2;//31;
              int layer_0_font_y_pos = 14;//layer_0_box_y_pos + (layer_0_box_height-(layer_0_font_height/2));       

           u8g2.setFont(u8g2_font_fub14_tf); // define font
           u8g2.setColorIndex(1); // set color to white
           u8g2.drawRBox(layer_0_box_x_pos, layer_0_box_y_pos, layer_0_box_width, layer_0_box_height, layer_0_corner_radius); //u8g2_uint_t x, u8g2_uint_t y, u8g2_uint_t w, u8g2_uint_t h, u8g2_uint_t r#
           u8g2.setColorIndex(0); // set color to "black" or off
           //dtostrf("Master Control", 1, 0, buffer); // Write Current Layer number into string
           //string_width = u8g2.getStrWidth(buffer);

           u8g2.setColorIndex(0);// set color to black
           u8g2.drawBox(20, 0, 88, 14); // draw box to hide frame partially

           //Write Name of Layer
           u8g2.setColorIndex(1);
           //dtostrf(sliderNameDisplay, 1, 0, buffer); // Write Current Layer number into string
           string_width = u8g2.getStrWidth(sliderNames[sliderNameNumber]);
           u8g2.drawStr(layer_0_font_x_pos, layer_0_font_y_pos, sliderNames[sliderNameNumber]);
          

          int volume_bar_x_pos = 0;
          int volume_bar_y_pos = 32; // 32
          int volume_bar_height = 32; // 32

          int volume_font_height = 14;
          int volume_font_x_pos = 8;
          int volume_font_y_pos = volume_bar_y_pos + (volume_bar_height - (volume_font_height/2));
          
          u8g2.setColorIndex(1); // set color to white
          u8g2.drawBox(volume_bar_x_pos,volume_bar_y_pos,volume_bar,volume_bar_height); //Draw a box (filled frame), starting at x/y position (upper left edge). The box has width "volume bar" and height 
          u8g2.setColorIndex(0); // set color to "black" or off
          dtostrf(potentiometer_value, 1, 0, buffer); // Convert potentiometer value into str: Divide value by 10, max char width, number of decimals, write to [buffer]
          u8g2.drawStr(volume_font_x_pos, volume_font_y_pos, buffer);

          
       
        }
        
        
      } while ( u8g2.nextPage() );


}