#define BTN_MENU 3
#define BTN_INC  4
#define BTN_DEC  5

#define CLK 12
#define DIO 13
#define CLK2 10
#define DIO2 11

#define LED_1 2
#define LED_2 6

#define DEFAULT_TIME 30

#include <OneButton.h>
#include <GyverTM1637.h>
#include <U8glib.h>

GyverTM1637 disp(CLK,DIO); 
GyverTM1637 disp2(CLK2,DIO2); 
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);

void draw(String text) { 
  u8g.setFont(u8g_font_unifont); 
  u8g.setPrintPos(0, 20); 

  u8g.print(text);
}

void drawText(String text){
      u8g.firstPage();  
      do {
        draw(text);
        // функции отрисовки
      } while( u8g.nextPage() );
}

class Settings {

  public:
    String textStatus;
    int workMode;
    int workStatus;
    unsigned long currentTime, currentTime2;
    unsigned long maxTime, maxTime2;
    unsigned long _startTime, _startTime2;
    unsigned long time;
    unsigned long time2;
    Settings(){
      workMode = 1;
      workStatus = 0;
      _startTime = DEFAULT_TIME;
      _startTime2 = DEFAULT_TIME;
      currentTime = _startTime;
      currentTime2 = 0;
      time = 0;
    }

    void changeMode(){
      int arr;
      if (workMode == 0){
        workMode = 1;
        arr = 2222;
        textStatus = "Flag";
      } else {
        workMode = 0;
        arr = 1111;
        textStatus = "Bomba";
      }
      disp.displayInt(arr);
      drawText(textStatus);
    }

    void changeMode(int _mode){
      int arr;
      workMode = _mode;
      if (workMode == 1){
        arr = 2222;
        textStatus = "Flag";
      } else {
        arr = 1111;
        textStatus = "Bomba";
      }
      disp.displayInt(arr);
      drawText(textStatus);
    }

    void selectMode(){
      printLog();
      digitalWrite(LED_2,LOW);
      digitalWrite(LED_1,LOW);
      disp.brightness(7);

      if (workStatus == 3) {
        workStatus = 4;
        if (workMode == 0){
          byte arr[]={8,8,8,8};
          disp.display(arr);
          drawText("!!! B A H !!!");
          //boom
        }
      }

      if (workStatus == 2) {
        workStatus = 3;
        if (workMode == 0){
          digitalWrite(LED_1, LOW);
          time = millis();
          _startTime = currentTime;
          drawText("Activated");
        }
        if (workMode == 1){
          digitalWrite(LED_1, LOW);
          digitalWrite(LED_2, LOW);

          _startTime = currentTime;
          _startTime2 = currentTime2;
          currentTime = 0;
          currentTime2 = 0;

          disp.brightness(7);
          disp2.brightness(7);
          disp.displayClock(currentTime/60,currentTime%60);
          disp2.displayClock(currentTime2/60,currentTime2%60);

          drawText("Starting");
        }
      }

      if (workStatus == 1) {
        workStatus = 2;
        if (workMode == 0){
          disp.displayClock(currentTime/60,currentTime%60);
          digitalWrite(LED_1, HIGH);
          drawText("Deactivated");
        } else {
          drawText("Ready");
        }
        
      }

      if (workStatus == 0) {
        workStatus = 1;
        if (workMode == 0){
          currentTime = _startTime;
          disp.displayClock(currentTime/60,currentTime%60);
          drawText("Set time");
        }
        if (workMode == 1){
          currentTime = _startTime;
          maxTime = 9999;
          disp.displayClock(currentTime/60,currentTime%60);
          currentTime2 = _startTime2;
          maxTime2 = 9999;
          disp2.displayClock(currentTime2/60,currentTime2%60);
          drawText("Set time");
        }
      }
    }

    void incrementTime(int delta){
      if (workMode==0) {
        currentTime = (currentTime + delta<0) ? 0 : (currentTime + delta>999) ? 999 : currentTime + delta;
        disp.displayClock(currentTime/60,currentTime%60);
        if (currentTime==0 && workStatus==3 && workMode==0 ) {
          //finish
          selectMode();
        }
      }
      if (workMode==1 && (workStatus==1 || workStatus==4)) {
        currentTime = (currentTime + delta<0) ? 0 : (currentTime + delta>999) ? 999 : currentTime + delta;
        disp.displayClock(currentTime/60,currentTime%60);
      }
      if (workMode==1 && (workStatus==2 || workStatus==5)) {
        currentTime2 = (currentTime2 + delta>maxTime2) ? currentTime2 : (currentTime2 + delta>999) ? 999 : currentTime2 + delta;
        disp2.displayClock(currentTime2/60,currentTime2%60);
      }
    }
    void printLog(){
      Serial.print("mode = ");
      Serial.print(workMode);
      Serial.print(", status = ");
      Serial.println(workStatus);
    }

  private:
    
};

Settings prop;

OneButton btn_Menu = OneButton(BTN_MENU, true, true);
OneButton btn_Inc  = OneButton(BTN_INC,  true, true);
OneButton btn_Dec  = OneButton(BTN_DEC,  true, true);

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
// Вложение события с одним щелчком 
  btn_Menu.attachClick(btnMenuOnClick);
  btn_Menu.attachLongPressStop(btnMenuOnLongPressStop);
  btn_Menu.attachLongPressStart(btnMenuOnLongPressStart);
  btn_Menu.setDebounceTicks(25);
  btn_Inc.attachClick(btnIncOnClick);
  btn_Inc.attachLongPressStart(btnIncOnLongPressStart);
  btn_Inc.attachDuringLongPress(btnIncOnDuringLongPress);
  btn_Inc.setDebounceTicks(25);
  btn_Dec.attachClick(btnDecOnClick);
  btn_Dec.attachLongPressStart(btnDecOnLongPressStart);
  btn_Dec.attachDuringLongPress(btnDecOnDuringLongPress);
  btn_Dec.setDebounceTicks(25);


  disp.clear();
  disp.brightness(7);
  
  disp2.clear();
  disp2.brightness(7);

  prop.changeMode();

  pinMode(LED_1, OUTPUT);
  pinMode(LED_2, OUTPUT);

}


void loop() {

  // put your main code here, to run repeatedly:
  btn_Menu.tick();
  btn_Inc.tick();
  btn_Dec.tick();

  if (prop.workStatus==3 && prop.workMode==0 && prop.currentTime>0) {
    //отсчет
    unsigned long currentTime = millis();
    int delta = (currentTime-prop.time);
    int deltaPoint = (prop.currentTime>10) ? 800:400;
    if (delta % deltaPoint > (deltaPoint >> 1)) {
      disp.point(true);
    } else {
      disp.point(false);
    }
    if (delta > 800) {
      prop.time = currentTime;
      prop.incrementTime(-delta/800);
    }
  }
  
  if (prop.workStatus==4  && prop.workMode==0 && prop.currentTime==0) {
    //отсчет
    unsigned long currentTime = millis();
    int delta = (currentTime-prop.time);
    if (delta > 800){
          prop.time = currentTime;
          digitalWrite(LED_2,!digitalRead(LED_2));
          digitalWrite(LED_1,!digitalRead(LED_1));
    } else {
      disp.brightness(delta/100);
    }
  }

  if (prop.workStatus==1  && prop.workMode==1) {
    //отсчет
    unsigned long currentTime = millis();
    int delta = (currentTime-prop.time);
    if (delta > 800){
          prop.time = currentTime;
    } else {
      disp.brightness(delta/100);
    }
  }
  if (prop.workStatus==2  && prop.workMode==1) {
    //отсчет
    unsigned long currentTime = millis();
    int delta = (currentTime-prop.time2);
    if (delta > 800){
          prop.time2 = currentTime;
    } else {
      disp2.brightness(delta/100);
    }
  }

  if (prop.workStatus==5 && prop.workMode==1 && prop.currentTime2 == prop.maxTime2) {
    prop.workStatus = 3;
    digitalWrite(LED_1, LOW);
  }
  if (prop.workStatus==4 && prop.workMode==1 && prop.currentTime == prop.maxTime) {
    prop.workStatus = 3;
    digitalWrite(LED_2, LOW);
  }

  if (prop.workStatus==5  && prop.workMode==1) {
    //отсчет
    unsigned long currentTime = millis();
    int delta = (currentTime-prop.time2);
    int deltaPoint = 800;
    if (delta % deltaPoint > (deltaPoint >> 1)) {
      disp2.point(true);
    } else {
      disp2.point(false);
    }
    if (delta > 800) {
      prop.time2 = currentTime;
      prop.incrementTime(delta/800);
    }
  }
  if (prop.workStatus==4  && prop.workMode==1) {
    //отсчет
    unsigned long currentTime = millis();
    int delta = (currentTime-prop.time);
    int deltaPoint = 800;
    if (delta % deltaPoint > (deltaPoint >> 1)) {
      disp.point(true);
    } else {
      disp.point(false);
    }
    if (delta > 800) {
      prop.time = currentTime;
      prop.incrementTime(delta/800);
    }
  }

}

void btnMenuOnClick(){
  //Переключение режимов
  if (prop.workStatus == 2 && prop.workMode==1){
      prop.workStatus = 1;
      disp2.brightness(7);
  } else {
    if (prop.workStatus == 1 && prop.workMode==1){
        prop.workStatus = 2;
        disp.brightness(7);
    }
  }
  if (prop.workStatus == 0) {
    prop.changeMode();
  }
}

void btnMenuOnLongPressStart(){
  //оповестим о длительном нажатии
  if ((prop.workStatus==3 || prop.workStatus==4) && prop.workMode==0){
    digitalWrite(LED_1, HIGH);  
    prop.workStatus=1;
    disp.clear();
    prop.currentTime = prop._startTime;
  } else {
    digitalWrite(LED_2, HIGH);
    if ((prop.workStatus>=2 && prop.workStatus<=5) && prop.workMode==1){
      digitalWrite(LED_1, HIGH);
    }
  }
}

void btnMenuOnLongPressStop(){
  //Выбор
  if (digitalRead(LED_2)){
    digitalWrite(LED_2, LOW);  
  } else {
    digitalWrite(LED_1, LOW);
  }
  if (prop.workMode==0) {
    if (prop.workStatus == 2) {
      prop.selectMode();
    }
    if (prop.workStatus == 1) {
      prop.selectMode();
    }
  } 
  if (prop.workMode==1) {
    if (prop.workStatus == 2 || prop.workStatus == 1) {
      prop.workStatus = 2;
      prop.selectMode();
    } else {
      if (prop.workStatus > 2) {
        digitalWrite(LED_1, LOW);  
        digitalWrite(LED_2, LOW);  
        prop.workStatus = 1;
      }
    }
  } 
  if (prop.workStatus == 0) {
    prop.selectMode();
  }
}

void btnIncOnClick(){
  //Переключение режимов
  if (prop.workStatus == 0) {
    prop.changeMode(1);
  }
  if (prop.workMode == 0 && prop.workStatus == 1) {
    prop.incrementTime(1);
  }
  if (prop.workMode == 1 && prop.workStatus == 1) {
    prop.incrementTime(1);
  }
  if (prop.workMode == 1 && prop.workStatus == 2) {
    prop.incrementTime(1);
  }
  if ((prop.workStatus==3 || prop.workStatus==4) && prop.workMode==1){
    digitalWrite(LED_1, HIGH);  
    digitalWrite(LED_2, LOW);  
    prop.maxTime2 = prop.currentTime2 + prop._startTime2;
    prop.workStatus=5;
    prop.time2 = millis();
    drawText("Activated - 2");
  }
}

void btnIncOnLongPressStart(){
  //оповестим о длительном нажатии
  
}
void btnIncOnDuringLongPress() {
  if (prop.workMode == 0 && prop.workStatus == 1) {
    prop.incrementTime(1);
  }
}

void btnDecOnClick(){
  //Переключение режимов
  if (prop.workStatus == 0) {
    prop.changeMode(0);
  }
  if (prop.workMode == 0 && prop.workStatus == 1) {
    prop.incrementTime(-1);
  }
  if (prop.workMode == 1 && prop.workStatus == 1) {
    prop.incrementTime(-1);
  }
  if (prop.workMode == 1 && prop.workStatus == 2) {
    prop.incrementTime(-1);
  }
  if ((prop.workStatus==3 || prop.workStatus==5)  && prop.workMode==1){
    digitalWrite(LED_1, LOW);  
    digitalWrite(LED_2, HIGH);  
    prop.maxTime = prop.currentTime + prop._startTime;
    prop.workStatus=4;
    prop.time = millis();
    drawText("Activated - 1");
  }

}
void btnDecOnLongPressStart(){
  //оповестим о длительном нажатии
}
void btnDecOnDuringLongPress() {
  if (prop.workMode == 0 && prop.workStatus == 1) {
    prop.incrementTime(-1);
  }
}

4-Digit Display
4-Digit Display