#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#include <EEPROM.h>
#include <WiFiUdp.h>
//#include <SimplePortal.h>
#include <NTPClient.h>
#include <FastLED.h>
#define GH_NO_MQTT  // убрать MQTT
#include <GyverHub.h>
#include <Stamp.h>
//#include <EEManager.h>
#include <Arduino.h>
#include <GyverHub.h>

#include "macros.h"            //Список макросов
#include "define.h"            //Настройки и переменные


void setup() {
  EEPROM.begin(110+col_alarms*10);
  Serial.begin(115200);
  irrecv.enableIRIn(); // запускаем прием
  Serial.println("Start IR");
#ifdef TYPE_LED_2811  
  FastLED.addLeds<WS2812, DI_PIN, BRG>(leds, NUM_LEDS);  // инициализация светодиодов (RGB,BRG - порядок цветов) для 12 вольтовых лент
#else
  FastLED.addLeds<WS2812, DI_PIN, RGB>(leds, NUM_LEDS);  // инициализация светодиодов (RGB,BRG - порядок цветов) для 5 вольтовых лент
#endif
  if (CURRENT_LIMIT > 0) FastLED.setMaxPowerInVoltsAndMilliamps(5, CURRENT_LIMIT);

  Serial.println("Start WiFi");
#if defined (IP_STATIC)
  WiFi.config(ip, gateway, subnet, gateway);
#endif
  WiFi.mode(WIFI_STA);
  WiFi.hostname("esp01-102");  
  WiFi.begin(AP_SSID, AP_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(50);
    Serial.print(".");
  }
  Serial.println(".");
  Serial.println(WiFi.localIP());
  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);

  HUE_START=0;

  hub.onBuild(build);     // подключаем билдер
  hub.begin();            // запускаем систему
 
  ntp_update_time = millis();

  if (EEPROM.read(70)!=57) {
//      EEPROM.write(0,0);     // Эффект
      EEPROM.write(71,15);    // шаг огня 15
      EEPROM.write(72,0);     // начальный цвет огня (0 красный, 80 зелёный, 140 молния, 190 розовый)
      EEPROM.write(73,70);    // Яркость автоматическая
      EEPROM.write(74,255);   // timer_power_on 
      EEPROM.write(75,10);    // Задержка в пламени
      EEPROM.write(76,1);     // OFFflag
      EEPROM.write(70,57);
      FOR_i(0,col_alarms) {
        EEPROM.put(100+i*10,0);
        EEPROM.put(101+i*10,0);
        EEPROM.put(105+i*10,0);
        EEPROM.put(107+i*10,127);
      }
      
      EEPROM.commit();
  }
  EFFECT     = 0;
  FIRE_STEP  = EEPROM.read(71);    // шаг огня 15
  HUE_START  = EEPROM.read(72);    // начальный цвет огня (0 красный, 80 зелёный)
  MIN_BRIGHT = EEPROM.read(73);    // мин. яркость огня 70
  MAX_BRIGHT = EEPROM.read(74);    // макс. яркость огня 255
  FIRE_DELAY = EEPROM.read(75);    // Задержка в пламени
  OFFflag =    EEPROM.read(76);     // OFFflag
      FOR_i(0,col_alarms) {
        EEPROM.get(100+i*10,alarms[i].on_off);
        EEPROM.get(101+i*10,alarms[i].alarm_time);
        EEPROM.get(105+i*10,alarms[i].alarm_action);
        EEPROM.get(107+i*10,alarms[i].flags.flags);
        if (alarms[i].alarm_action>3255) {
          alarms[i].on_off=false;
          alarms[i].alarm_time=0;
          alarms[i].alarm_action=0;
        }
      }
  timer_off=millis();
  timeClient.begin();
  Udp.begin(localPort);
  delay(500);
  timeClient.update(); 
  hour   = timeClient.getHours();
  minute = timeClient.getMinutes();
  Serial.println("End Setup");
}


uint32_t choice_select=0;

void loop() {
  hub.tick();  // обязательно тикаем тут
  if (EFFECT>0) SHOW_EFFECT=EFFECT;
  else
  if (millis()-choice_select>60000)
  {
     choice_select=millis();
     SHOW_EFFECT++;
     if (SHOW_EFFECT>MAX_EFFECT) SHOW_EFFECT=1;
//     Serial.println("choice_select "+String(choice_select));
  }
  if (ONflag) { 
    static uint32_t prevTime;
    if (millis() - prevTime > FIRE_DELAY) {
      prevTime = millis();
      switch (SHOW_EFFECT)
      {
        case 1:   ColorTick(HUE_START,0);    break;  // Цвет 
        case 2:   ColorTick(counter,0);      break;  // Смена цвета
        case 3:   madnessNoiseRoutine();              break;  // Бeзyмиe           
        case 4:   cloudsNoiseRoutine();               break;  // Oблaкa            
        case 5:   lavaNoiseRoutine();                 break;  // Лaвa              
        case 6:   plasmaNoiseRoutine();               break;  // Плaзмa            
        case 7:   rainbowNoiseRoutine();              break;  // Paдyгa 3D         
        case 8:   rainbowStripeNoiseRoutine();        break;  // Пaвлин            
        case 9:   zebraNoiseRoutine();                break;  // 3eбpa             
        case 10:  forestNoiseRoutine();               break;  // Лec               
        case 11:  oceanNoiseRoutine();                break;  // Oкeaн             
        case 12:  FireTick(1);                        break;  // Огненные искры
        case 13:  ColdSparkTick();                    break;  // Холодные искры
        case 14:  ColorTick(HUE_START,1);             break;  // Цвет и искры
        case 15:  RainbowTick(1);                     break;  // Радужный огонь и искры
        case 16:  Rainbow(1);                         break;  // Радужные искры
        case 17:  RainbowCenterTick(0);               break;  // Радуга из центра
        case 18:  FireTick(0);                        break;  // Пламя
        case 19:  fire2012again();                    break;  // Oгoнь 2012
        case 20:  Rainbow(0);                         break;  // Радуга
        case 21:  RainbowTick(0);                     break;  // Радужный огонь
        case 22:  ColorTick(counter,1);               break;  // Смена цвета и искры,
        case 23:  RainbowCenterTick(1);               break;  // Радуга из центра искры
        case 24:  RainRoutine(HUE_START);             break;  // Paзнoцвeтный дoждь
        case 25:  RainRoutine(255);                   break;  // Снег
        case 26:  RainRoutine(0);                     break;  // Радужный дoждь

      }
     } 
  }
  else LEDS.showColor(CRGB(0, 0, 0));
  
  if ( irrecv.decode( &results )) {   // если данные пришли
      if (results.value != -1) pressed=false;
      IR_press=results.value;
      if (pressed) IR_press=IR_last_press;
//      Serial.println(uint32_t(results.value),HEX);
      IR_str=String(uint32_t(results.value),HEX);
      hub_update();
      timer_off=millis();
      switch (IR_press)
      {
        case 0xFF0FF0:  // Power на длинном пульте
           ONflag=not ONflag;
           hub_update();
           break;
        case 0xFF8F70:  // СH+на длинном пульте
           EFFECT++;
           if (EFFECT>MAX_EFFECT) EFFECT=1;
           hub_update();
           break;
        case 0xFF4FB0:  // CH-на длинном пульте 
           if (EFFECT>1) EFFECT--; 
                    else EFFECT=MAX_EFFECT;
           hub_update();
           break;
        case 0xFFAF50: // AV
           EFFECT=0;
           break;
//ярче
        case 0xFFCF30:  //Vol+на длинном пульте
           pressed=true;
           IR_last_press=IR_press;
           if (MAX_BRIGHT<255) MAX_BRIGHT++;
           hub_update();
           eeprom_flag=true;
           break;
//темнее            
        case 0xFF2FD0:  //Vol-на длинном пульте
           pressed=true;
           IR_last_press=IR_press;
           if (MAX_BRIGHT>10) MAX_BRIGHT--;
           hub_update();
           eeprom_flag=true;
           break;
           
        case 0xFFFFFFFF:
           hub_update();
           break;
        default:            
           pressed=false;
      }
    irrecv.resume();  // принимаем следующую команду
  }

  // Разные таймеры
  usertimeClientupdate();
  userTimeRead();
  userWiFiReconect();
  userAutoSave();
  parseUDP();

  if (OFFflag)
    if (ONflag)
     if (millis()-timer_off>3600000)
     {
       timer_off=millis();
       ONflag=false;
       hub_update();
    }
}
