/*********
  Rui Santos
  Complete project details at https://randomnerdtutorials.com  
*********/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
int val;
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

byte Mf_p_Buttons(byte receivedData = 0, byte selectedButton = 0);
byte buttonArray[] = {5, 6, 7, 8, 9, 10, 11, 12, 13, 14};

void setup() {
  
  Serial.begin(115200);
  
  for (int i = 0; i < 12; i++) {
    pinMode(buttonArray[i], INPUT_PULLUP);
    Serial.println(i);
  }
  
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  display.setTextSize(1);
  display.setTextColor(WHITE);

}
    
    #define address_entered 21
    #define no_action 0
    
    #define animation_one 20
    #define animation_two 21
    #define animation_stope_one 22
    #define animation_stope_two 23

byte Md_addres = address_entered;


void loop() {
  
 display.clearDisplay();
  
 Mf_Buttons();
  
 display.display();

}

void Mf_Buttons() {
  
  //static unsigned long tmr;
  static byte currenState;
  static byte saveButton;
  static byte butFlag;
  
  Mf_p_Buttons();
  
  switch (Md_addres) {
    
    case no_action:
      
      break;
    
    case 1:
      
      if(!butFlag){
        
        for (int i = 0; i < 10; ++i) {
        
          if(!digitalRead(buttonArray[i])){
                  
            butFlag = 1;
            
            if(!saveButton){
              
              Mf_p_Buttons(animation_two, i);
              butFlag = 1;
              saveButton = buttonArray[i];
              break;
            
            }
            
            else {
              
              Mf_p_Buttons(animation_stope_one, i);
              buttonArray[i] = saveButton;
              //Md_addres = 0; 
              saveButton = 0;
              break;
            
            }
            
            break;
          
          }   
        }   
      }
      
      else if(butFlag){
        
        for (int i = 0; i < 10; ++i) {
        
          if(digitalRead(buttonArray[i])){
            
            break;
          
          }   
          
          butFlag = 0;
        
        }   
      }

      break;

    case address_entered:
      
      Md_addres = 1;
      
      if(Md_addres == 1){
       
       Mf_p_Buttons(animation_one);
       
      }
      
      if(saveButton){
          
        saveButton = 0;
      
      }
    
      break;
  
  }
  
}

byte Mf_p_Buttons(byte receivedData = 0, byte selectedButton = 0){
  
  static byte runningArrow;
  static byte questionMarkFlag;
  static byte animation;
  static byte buttonOne;
  static byte buttonTwo;
  static byte accumulationL;  
  static byte accumulationR;
  static unsigned long tmr;  

  const char *buttonNames[] = {
    "A",
    "B",
    "X",
    "Y",
    "LB",
    "RB",
    "LT",
    "RT",
    "LA",
    "RA",
  };
  
  
  if (selectedButton) {
     
   if (selectedButton == buttonOne) {
    
    buttonOne = selectedButton;
   
   }
   
   else{
    
    buttonTwo = selectedButton;
   
   }
  
  }
  
  if (receivedData) {
     
   animation = receivedData;
   
  }
  
  if (animation && tmr < millis()) {
    
    if (animation == animation_stope_two) {
      
     animation = 0;

    }
    
    else{
      
     tmr = millis()+400; 
    
    }
    
    if (runningArrow < 7) {
      
      runningArrow++;
    
    } 
    
    else{
     
     runningArrow = !runningArrow;
    
    }
    
    
    if ( questionMarkFlag < 2) { 
      
      questionMarkFlag++;
    
    } 
    
    else{
     
     questionMarkFlag = !questionMarkFlag;
    
    }
    
    if (animation == animation_one && accumulationL < 3) {
      
      accumulationL++;
    
    } 
    
    else if (accumulationL) {
     
     accumulationL = 0;
    
    }
    
    
    if (animation == animation_two && accumulationR < 3) {
      
      accumulationR++;
    
    } 
    
    else if (accumulationR) {
     
     accumulationR = 0;
    
    } 
    
  }

  //display.drawRect(0, 0, 127, 63, WHITE);// test ramka

  display.drawRect(6, 5, 31, 31, WHITE); // квадрат L
  display.drawRect(90, 5, 31, 31, WHITE);// квадрат R
  
 
  if (accumulationL) {
  
   display.setCursor(19, 13);
  
  }
  
  else if (accumulationR) {
   
   display.setCursor(103, 13);

  }
  
  if (questionMarkFlag) {
   
   display.println('?');
  
  }
  
  if (animation == animation_two) {
   
     display.setCursor(22-strlen(buttonNames[buttonOne])*3, 13);
     display.println(buttonNames[buttonOne]);
   
    for (int i = 0; i < 8; ++i) {
     
     display.setCursor(40+i*6, 13);
     display.write(62);
   
    }
   
    display.setCursor(40+runningArrow*6, 13);
    display.write(16);
  
  }
  
  else if (animation == animation_stope_one || animation == animation_stope_two) {
    
   
     if (animation == animation_stope_one) {
      
      accumulationL = accumulationR = questionMarkFlag = runningArrow = 0;

      animation = animation_stope_two;
      tmr = millis()+1000; 
     
     }
    
     display.setCursor(22-strlen(buttonNames[buttonOne])*3, 13);
     display.println(buttonNames[buttonOne]);
   
    
    display.setCursor(106-strlen(buttonNames[buttonTwo])*3, 13);
    display.println(buttonNames[buttonTwo]);
    
  }

  display.drawCircle(21, 16, 8, WHITE);//кружки над кнопками
  display.drawCircle(105, 16, 8, WHITE);
  
  display.drawRect(12, 26+accumulationL, 19, 5, WHITE);//ліва кнопка
  display.fillRect(9, 30, 25, 4, WHITE);
  
  display.drawRect(96, 26+accumulationR, 19, 5, WHITE);//права кнопка
  display.fillRect(93, 30, 25, 4, WHITE);

  byte Lines[] = {40, 48, 56};
  //Md_cursor(Lines, sizeof(Lines));
  display.setCursor(0, 40);
  display.println(" Move buttons");
  display.println(" Reset");      
  display.println(" Back");


  return 0; 

}