/*

    RGB Fill Lights
    Author: tobychui

    This is the firmware for tobychui's
    Programmable RGB Fill Light

    Recommend compiling with following board profiles
    - Wemos D1 Mini
    - CPU Speed: 160Mhz

    CopyRight tobychui, All Right Reserved
*/

/* WiFi and Discovery */
#include <ESP8266WiFi.h>
#include <WiFiManager.h>
#include <ESP8266mDNS.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include "LittleFS.h"

/* Hardware & Controls */
#include <Adafruit_NeoPixel.h>

// Hardware Configs
#define PIN D2
#define NUM_LEDS 50
#define BUTTON_MODE D7
#define BUTTON_ADD D0
#define BUTTON_COLOR D5
#define BUTTON_MINUS D6

#define BUTTON_AUTOINC_DELAY 500 //Delay before auto increments
#define BUTTON_HOLD_DELAY 70 //Auto-increment delays
#define BUTTON_DEBOUNCE 70 //Naive debounce delay in ms
#define MAX_BRIGHTNESS 256 //Make sure the battery you using can output the current required by LEDs
#define MAX_CTRLBRIGHTNESS 32 //Max brightness for signaling LED (the one above the button)
#define WHITE_MIN_TEMP 2500 //Min color temperature in white mode
#define WHITE_MAX_TEMP 10000 //Max color temperature in white mode

//Runtimes
/* Network Settings */
#define DEVICE_NAME "FL1010-RGB"
#define MDNS_NAME "fl1010-rgb"
#define LISTENING_PORT 80
WiFiManager wifiManager;
ESP8266WebServer server(LISTENING_PORT);
String deviceUUID = "";

/*
   Current Mode
   0 = White Mode (+/- Change the K value of the light)
   1 = RGB Mode (+/C/- Change the RGB values of the light)
   2 = Pure Color Mode (C Change the default color palletes, +- change brightness offset)
*/
int currentMode = 0;

/*
   Adjusting Catergory

   [White Mode]
   0 = Color Temperature (K)
   1 = Brightness

   [RGB Mode]
   0 = Red
   1 = Green
   2 = Blue

   [Pallete Mode]
   0 = Color Pallete
   1 = Brightness

*/
int adjustingCatergory = 0;

/*
   Color Values
   [White Mode]
   TEMP, Brightness, (un-used)

   [RGB Mode]
   R, G, B

   [Pallete Mode]
   PalleteID, Brightness, (unused)

*/
int values[] = {0, 0, 0};
int currentCtrlLedRgb[] = {0, 0, 0};

bool wifiControlMode = false;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

//Set the current control LED color
void setControlLEDColor(int r, int g, int b) {
  currentCtrlLedRgb[0] = r;
  currentCtrlLedRgb[1] = g;
  currentCtrlLedRgb[2] = b;
  strip.setPixelColor(0, strip.Color(r, g, b));
  strip.show();
}

//Set the current LED light color by given RGB values
void setLightColor(int r, int g, int b) {
  for (int i = 1; i < NUM_LEDS; i++) {
    strip.setPixelColor(i, strip.Color(r, g, b));
  }
  strip.show();
}
void setup() {
  //Start Serial
  Serial.begin(115200);

  //Set the buttons to input pin
  pinMode(BUTTON_MODE, INPUT);
  pinMode(BUTTON_ADD, INPUT);
  pinMode(BUTTON_COLOR, INPUT);
  pinMode(BUTTON_MINUS, INPUT);
  strip.begin();
  delay(300);
  setLightColor(0, 0, 0);

  //Check if mode button is hold. If yes, enter WiFi mode
  int tmp = digitalRead(BUTTON_MODE);
  if (tmp == LOW) {
    //Load device UUID
    deviceUUID = WiFi.macAddress();
    deviceUUID.replace(":", "-");

    //Setup WiFi
    setControlLEDColor(255, 255, 0); //Yellow
    Serial.println("Entering WiFi Mode");
    wifiManager.autoConnect(DEVICE_NAME);
    if (WiFi.status() == WL_CONNECTED) {
      Serial.println("WiFi Connected");
      setControlLEDColor(0, 32, 0); //Green
      wifiControlMode = true;

      //Start API service over WiFi
      registerAPI();
    } else {
      Serial.println("Network error. Running in offline mode");
      setControlLEDColor(255, 0, 0); //Red
    }
  } else {
    // Initialize all pixels to natural warm white light
    loadWhiteModeDefault();
  }


}

void loop() {
  if (wifiControlMode){
    server.handleClient();
    MDNS.update();
  }else{
    handleButtonLogic();
  }
}
