//Inclusions and definitions - some appear throughout the code
#include <ArduinoHttpClient.h>

#define BLYNK_PRINT SerialUSB

#define BLYNK_TEMPLATE_ID "TMPLyReNy8v4"
#define BLYNK_DEVICE_NAME "CPX Final Project"
#define BLYNK_AUTH_TOKEN "ZZZ"

#include <ESP8266_Lib.h>
#include <BlynkSimpleShieldEsp8266.h>
#include <Adafruit_CircuitPlayground.h>


char auth[] = BLYNK_AUTH_TOKEN; //Token to connect with Blynk services

char ssid[] = "XXX"; //Change accordingly to your wifi network name
char pass[] = "YYY"; //Change accordingly to your wifi network password

#define EspSerial Serial1
#define ESP8266_BAUD 115200

ESP8266 wifi(&EspSerial);

void setup() {
  CircuitPlayground.begin();
  SerialUSB.begin(9600);
  EspSerial.begin(ESP8266_BAUD);
  delay(10);
  Blynk.begin(auth, wifi, ssid, pass);
}

int t = 0;
bool V0Flag = false;
bool V2Flag = true;

void loop(){
  Blynk.run();
}

//To build tension in certain parts of the machine run
void Delay() {
  delay(1200);
}

//The early loading lights at start of the run + the indication of is it cold nice or hot 
//For each type of weather we trigger a different event on Blynk
BLYNK_WRITE(V0){
  V0Flag = !V0Flag;
  if(V0Flag){
    for(int i = 0; i < 10; i++){
      CircuitPlayground.setPixelColor(i, 15, 15, 15);
      Delay();
      if(i == 9){
        if(CircuitPlayground.temperature() > 30){
          for(int j = 0; j < 10; j++){
            CircuitPlayground.setPixelColor(j, 50, 0, 0);
          }

          if(t < 1){
          //triger the event for too hot
          Blynk.virtualWrite(V1, "OMG IT IS SO HOT! TURNING ON THE AC!");
          t = t + 1;
          AC_chill();
          }
        }
        else if(CircuitPlayground.temperature() <= 30 && CircuitPlayground.temperature() > 25){
          for(int k = 0; k < 10; k++){
            CircuitPlayground.setPixelColor(k, 0, 50, 0);
          }
          if(t < 1){
            startParty();
            t = t + 1;
          }
        }
        else if(CircuitPlayground.temperature() <= 25){
          for(int k = 0; k < 10; k++){
            CircuitPlayground.setPixelColor(k, 0, 0, 50);
          }
          if(t < 1){
          //triger the event for too cold
          Blynk.virtualWrite(V1, "OMG IT IS FREEZING! TURNING ON THE HEAT!");
          t = t + 1;
          AC_warm();
          }
        }
      }
    }
  }
}

//turn off the leds, notify the party is starting, check the light sensor and start to party with light show and music
void startParty(){
  Delay();
  for(int k = 0; k < 10; k++){
    CircuitPlayground.setPixelColor(9-k, 0, 0, 0);
  }

  int light = CircuitPlayground.lightSensor();
  //using the light sensor to make sure the party lights will come at full effect
  if(light > 100){
    Blynk.virtualWrite(V1, "The temperature is perfect but it is a little to bright to start a party just yet. Try turning off the lights :)");
  }
  else{
    Blynk.virtualWrite(V1, "OHH YES EVERYTHING IS PERFECT");
  }
  
  //wait till light levels are below the threshold
  while(light > 100){
    Delay();
    light = CircuitPlayground.lightSensor();
  }

  //Notifies the party is starting
  Blynk.virtualWrite(V1, "The machine is feeling nice and comfortable! Hurry up you are late to the party");

  //Light show and techno music
  for(int i = 0; i < 30; i++){
    CircuitPlayground.playTone(44,100);
    lightUp();
    lightUp();
    delay(36);
    CircuitPlayground.playTone(196,100);
    lightUp();
    lightUp();
    delay(36);
    CircuitPlayground.playTone(82,100);
    lightUp();
    lightUp();
    delay(36);
    CircuitPlayground.playTone(62,100);
    lightUp();
    lightUp();
    delay(36);
  }
}

//lightshow func
void lightUp(){
  int NeoPixel = rand() % 10;
  int R = rand() % 256;
  int G = rand() % 256;
  int B = rand() % 256;
  CircuitPlayground.setPixelColor(NeoPixel, R, G, B);
}

//As if we are warming the room with the AC
void AC_warm(){
  for(int i = 0; i < 51; i++){
    for(int k = 0; k < 10; k++){
      CircuitPlayground.setPixelColor(k, 0, i, 50-i);
    }

    delay(50);
  }

  startParty();
}

//As if we are chlling the room with the AC
void AC_chill(){
  for(int i = 0; i < 51; i++){
    for(int k = 0; k < 10; k++){
      CircuitPlayground.setPixelColor(k, 50-i, i, 0);
    }

    delay(50);
  }

  startParty();
}

//Turn off the lights (if you want) when the party is done and over
BLYNK_WRITE(V2){
  int value = param.asInt();
  for(int k = 0; k < value + 1; k++){
    CircuitPlayground.setPixelColor(k, 0, 0, 0);
  }
}