#include <U8g2lib.h>

U8X8_SSD1306_128X64_NONAME_HW_I2C display(U8X8_PIN_NONE);

#include <Adafruit_BMP280.h> // Библиотека для работы с датчиком BMP280

// Для подключения по шине I2C
Adafruit_BMP280 bmp;

unsigned long vivod = 0;

uint32_t vivod1 = 0;
int r = 0;

int vivodvalue = 200;

#define M1 5
#define M2 6

#define D1 A0

#define PWR_PIN 7
bool Triger = 0;

#define CLK 2
#define DT 3
#define SW 4
#include "GyverEncoder.h"
Encoder enc1(CLK, DT, SW, TYPE2);  // для работы c кнопкой

int c = 0, a = 0;

uint8_t disp = 0;

// int KV[9] = {0, 500, 1000, 500, 1000};
int skvaj = 0, skvajold = 0;
int skvaj1 = 0, skvaj2 = 0;
int bar = 0;
int psi = 0;
int kanalItem = 0;

int kanal[10] = {0, 500, 800, 1500, 0, 0, 500, 1000, 500, 0};
//режим, нач.откр., полн. откр., задержка, (повтор 2 канала)
int dat[5] = {0, 1023, 0, 0, 0};
//знач.0, знач.5, расчет, текущее знач., ед. изм.
char buffer[20];

unsigned long skvajtime = 0;
int skvajtimevalue = 0;

#define skvajmaxProc 85//procent skvajinnosti maximalnogo znacheniya
int skvajmax = skvajmaxProc * 255 / 100; //raschet

const int NUM_ITEMS = 5; // number of items in the list and also the number of screenshots and screenshots with QR codes (other screens)
const int MAX_ITEM_LENGTH = 13; // maximum characters for the item name

char menu_items [NUM_ITEMS] [MAX_ITEM_LENGTH] = {  // array with item names
  { "Edinici izm." },
  { "Datchiki" },
  { "Karta #1" },
  { "Kanal PU" },
  { "Vihod" },
};

char menu_ed [NUM_ITEMS] [MAX_ITEM_LENGTH] = {  // array with item names
  { "kPa" },
  { "bar" },
  { "pri" },
  { "%" },
  { "Nazad" },
};

char menu_dat [NUM_ITEMS - 1] [MAX_ITEM_LENGTH] = { // array with item names
  { "0v" },
  { "5v" },
  { "izbitok" },
  { "Nazad" },
};

char menu_karta [NUM_ITEMS] [MAX_ITEM_LENGTH] = { // array with item names
  { "Nach.ot.Z" },
  { "Poln.ot.%" },
  { "Poln.ot.Z" },
  { "Zaderjka" },
  { "Nazad" },
};

char menu_kanal [NUM_ITEMS - 2] [MAX_ITEM_LENGTH] = { // array with item names
  { "Kanal 1" },
  { "Kanal 2" },
  { "Nazad" },
};

int item_selected = 0; // which item in the menu is selected
// int edizm = 0;
// int datitem = 0;

int item_sel_previous; // previous item - used in the menu screen to draw the item before the selected one
int item_sel_next; // next item - used in the menu screen to draw next item after the selected one

void setup() {
  Serial.begin(115200);
  // Serial.println("Test");

  display.begin();
  display.setPowerSave(0);
  display.setFont(u8x8_font_pxplusibmcgathin_f);


  if (!bmp.begin()) { // Если датчик BMP280 не найден
    // Serial.println("BMP280 SENSOR ERROR"); // Выводим сообщение об ошибке
    // while (1); // Переходим в бесконечный цикл
  }
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, // Режим работы
                  Adafruit_BMP280::SAMPLING_X2, // Точность изм. температуры
                  Adafruit_BMP280::SAMPLING_X16, // Точность изм. давления
                  Adafruit_BMP280::FILTER_X16, // Уровень фильтрации
                  Adafruit_BMP280::STANDBY_MS_500); // Период просыпания, мСек

  pinMode(M1, OUTPUT);
  pinMode(M2, OUTPUT);
  digitalWrite(M1, LOW);//Mosfet 1
  digitalWrite(M2, LOW);//Mosfet 2

  pinMode(D1, INPUT);

  pinMode(PWR_PIN, INPUT_PULLUP);
}

void loop() {
  if (digitalRead(PWR_PIN)) {
    Triger = 0;
    enc1.tick();

    if (enc1.isTurn()) {     // если был совершён поворот (индикатор поворота в любую сторону)
      // ваш код
    }

    if (enc1.isRight()) {
      Serial.println("Right");         // если был поворот
      if (disp == 1 || disp == 2)
      {
        if (item_selected < NUM_ITEMS - 1)
          item_selected++;
      }
      // display.clearDisplay();

    }
    if (enc1.isLeft()) {
      Serial.println("Left");
      if (disp == 1 || disp == 2)
      {
        if (item_selected > 0)
          item_selected--;
      }
      // display.clearDisplay();
    }

    if (enc1.isRightH()) Serial.println("Right holded"); // если было удержание + поворот
    if (enc1.isLeftH()) Serial.println("Left holded");

    //if (enc1.isPress()) Serial.println("Press");         // нажатие на кнопку (+ дебаунс)
    //if (enc1.isRelease()) Serial.println("Release");     // то же самое, что isClick

    if (enc1.isClick()) {
      Serial.println("Click");         // одиночный клик
      if (disp == 1) {
        if (item_selected == 0)
          disp = 2;
        else if (item_selected == 1)
          disp = 3;
        else if (item_selected == 2)
          disp = 4;
        else if (item_selected == 3)
          disp = 5;
        else if (item_selected == 4)
          disp = 0;
        item_selected = 0;
        display.clearDisplay();
      }
      else if (disp == 2)
      {
        if (item_selected == 0)
          dat[4] = 0;
        else if (item_selected == 1)
          dat[4] = 1;
        else if (item_selected == 2)
          dat[4] = 2;
        else if (item_selected == 3)
          dat[4] = 3;
        else if (item_selected == 4) {
          disp = 1;
          item_selected = 0;
        }
        display.clearDisplay();
      }

    }
    if (enc1.isSingle()) Serial.println("Single");       // одиночный клик (с таймаутом для двойного)
    if (enc1.isDouble()) Serial.println("Double");       // двойной клик

    if (enc1.isHolded()) {
      Serial.println("Holded");       // если была удержана и энк не поворачивался
      if (disp == 0)
        disp = 1;
      else
        disp = 0;
      display.clearDisplay();
    }
    //if (enc1.isHold()) Serial.println("Hold");         // возвращает состояние кнопки

    dat[3] = analogRead(D1);
    skvaj = constrain(map(dat[3], 0, 1023, dat[0], dat[1]), 0, dat[1]);
    if (dat[2] == 1) {
      float p = bmp.readPressure();
      p = p * 0.00750062; // Преобразуем Паскали в мм.рт.ст.
      skvaj = constrain(skvaj - p, 0, dat[1]);;
    }
    skvaj1 = skvaj;
    skvaj2 = skvaj;
    if (kanal[0] == 0) {
      if (skvaj1 < kanal[1]) {
        skvaj1 = 0;
        // r = 1;
        // t = 0;
        if (skvaj1 <= skvajold && millis() - skvajtime >= kanal[3]) {
          digitalWrite(M1, LOW);
          skvajold = skvaj1;
        }
      }
      else if (kanal[1] <= skvaj1 && skvaj1 < kanal[2])
      {
        // r = 2;
        if (skvaj1 >= skvajold) {
          analogWrite(M1, map(skvaj1, 0, 1023, 0, 255));
          skvajold = skvaj1;
          skvajtime = millis();
          // r = 4;
          // t = map(skvaj, 0, 1023, 0, 255);
        }
        else if (skvaj1 < skvajold && millis() - skvajtime >= kanal[3]) {
          analogWrite(M1, map(skvaj1, 0, 1023, 0, 255));
          skvajold = skvaj1;

          // r = 5;
          // t = map(skvaj, 0, 1023, 0, 255);
          // Serial.println(r);
          // skvajtime = millis();

        }
      }
      else if (skvaj1 >= kanal[2])
      {
        // r = 3;
        analogWrite(M1, map(kanal[2], 0, 1023, 0, 255));
        // t = map(kanal[2], 0, 1023, 0, 255);
        skvajold = kanal[2];
        skvajtime = millis();
      }
    }
    else if (kanal[0] == 1) {
      digitalWrite(M1, HIGH);
    }
    else if (kanal[0] == 2) {
      digitalWrite(M1, LOW);
    }

    if (kanal[5] == 0) {
      if (skvaj2 < kanal[6]) {
        skvaj2 = 0;
        // r = 1;
        // t = 0;
        if (skvaj2 <= skvajold && millis() - skvajtime >= kanal[8]) {
          digitalWrite(M2, LOW);
          skvajold = skvaj2;
        }
      }
      else if (kanal[6] <= skvaj2 && skvaj2 < kanal[7])
      {
        // r = 2;
        if (skvaj2 >= skvajold) {
          analogWrite(M2, map(skvaj2, 0, 1023, 0, 255));
          skvajold = skvaj2;
          skvajtime = millis();
          // r = 4;
          // t = map(skvaj, 0, 1023, 0, 255);
        }
        else if (skvaj2 < skvajold && millis() - skvajtime >= kanal[8]) {
          analogWrite(M2, map(skvaj2, 0, 1023, 0, 255));
          skvajold = skvaj2;

          // r = 5;
          // t = map(skvaj, 0, 1023, 0, 255);
          // Serial.println(r);
          // skvajtime = millis();

        }
      }
      else if (skvaj2 >= kanal[7])
      {
        // r = 3;
        analogWrite(M2, map(kanal[7], 0, 1023, 0, 255));
        // t = map(kanal[2], 0, 1023, 0, 255);
        skvajold = kanal[7];
        skvajtime = millis();
      }
    }
    else if (kanal[5] == 1) {
      digitalWrite(M2, HIGH);
    }
    else if (kanal[5] == 2) {
      digitalWrite(M2, LOW);
    }

    if (millis() - vivod >= vivodvalue)
    {
      if (disp == 0) {
        // display.setFont(u8x8_font_courB24_3x4_r);
        display.setFont(u8x8_font_courB18_2x3_r);
        if (dat[4] == 0) {
          display.setCursor(5, 1);
          sprintf (buffer, "%03d", map(skvaj, dat[0], dat[1], 0, 400));
          display.print(buffer);
          display.setCursor(5, 4);
          display.print("kPa");
        }
        else if (dat[4] == 1) {
          bar = map(skvaj, dat[0], dat[1], 0, 400);
          display.setCursor(4, 1);
          sprintf (buffer, "%01d.%02d", bar / 100, bar % 100);
          display.print(buffer);
          display.setCursor(5, 4);
          display.print("bar");
        }
        else if (dat[4] == 2) {
          psi = map(skvaj, dat[0], dat[1], 0, 6000);
          display.setCursor(3, 1);
          sprintf (buffer, "%02d.%02d", psi / 100, psi % 100);
          display.print(buffer);
          display.setCursor(5, 4);
          display.print("psi");
        }
        else if (dat[4] == 3) {
          display.setCursor(4, 2);
          sprintf (buffer, "%03d%%", constrain(map(skvaj, dat[0], dat[1], 0, 100), 0, 100));
          display.print(buffer);
        }
      }
      else if (disp == 1) {
        display.setFont(u8x8_font_pxplusibmcgathin_f);
        display.setCursor(6, 0);
        display.print("Menu");
        for (int i = 0; i < NUM_ITEMS; i++) {
          display.drawString(1, i + 1, menu_items[i]);
          display.setCursor(0, i + 1);
          if (i == item_selected)
            display.print(">");
          else
            display.print(" ");
        }
      }
      else if (disp == 2) {
        display.setCursor(4, 0);
        display.print("Ed. izm.");
        for (int i = 0; i < NUM_ITEMS; i++) {
          display.drawString(1, i + 1, menu_ed[i]);
          display.setCursor(0, i + 1);
          if (i == item_selected)
            display.print(">");
          else
            display.print(" ");
          display.setCursor(13, i + 1);
          if (i == dat[4])
            display.print("*");
          else
            display.print(" ");
        }
      }
      else if (disp == 3) {
        display.setCursor(4, 0);
        display.print("Datchik");
        for (int i = 0; i < NUM_ITEMS - 1; i++) {
          display.drawString(1, i + 1, menu_dat[i]);
          display.setCursor(0, i + 1);
          if (i == item_selected)
            display.print(">");
          else
            display.print(" ");
          // if (i == item_selected)
          {
            if (i == 0) {
              display.setCursor(6, i + 1);
              sprintf (buffer, "%4d", dat[0]);
              display.print(buffer);
              display.setCursor(11, i + 1);
              sprintf (buffer, "%4d", skvaj);
              display.print(buffer);
            }
            if (i == 1) {
              display.setCursor(6, i + 1);
              sprintf (buffer, "%4d", dat[1]);
              display.print(buffer);
              display.setCursor(11, i + 1);
              sprintf (buffer, "%4d", skvaj);
              display.print(buffer);
            }
            if (i == 2) {
              display.setCursor(9, i + 1);
              display.print("Da");
              display.setCursor(12, i + 1);
              display.print("Net");
            }
          }
        }
      }
      else if (disp == 4) {
        display.setCursor(4, 0);
        display.print("Karta #1");
        for (int i = 0; i < NUM_ITEMS; i++) {
          display.drawString(1, i + 1, menu_karta[i]);
          display.setCursor(0, i + 1);
          if (i == item_selected)
            display.print(">");
          else
            display.print(" ");
          // if (i == 0)
          //   kanalItem = 0;
          // else if (i == 1)
          //   kanalItem = 5;
          if (i < 4) {
            display.setCursor(9, i + 1);
            
            if (kanal[kanalItem] == 0)
              display.print("Karta 1");
            else if (kanal[kanalItem] == 1)
              display.print("Otkrit");
            else if (kanal[kanalItem] == 1)
              display.print("Zakrit");
          }
        }
      }
      else if (disp == 5) {
        display.setCursor(4, 0);
        display.print("Kanal PU");
        for (int i = 0; i < NUM_ITEMS - 2; i++) {
          display.drawString(1, i + 1, menu_kanal[i]);
          display.setCursor(0, i + 1);
          if (i == item_selected)
            display.print(">");
          else
            display.print(" ");
          if (i == 0)
            kanalItem = 0;
          else if (i == 1)
            kanalItem = 5;
          if (i < 2) {
            display.setCursor(9, i + 1);
            if (kanal[kanalItem] == 0)
              display.print("Karta 1");
            else if (kanal[kanalItem] == 1)
              display.print("Otkrit");
            else if (kanal[kanalItem] == 1)
              display.print("Zakrit");
          }
        }
      }
      vivod = millis();
    }
  }
  else if (!digitalRead(PWR_PIN) && Triger == 0)
  {
    // display.clearDisplay();
    // display.display();
    Triger = 1;
  }
}