/*
 * This code is created by Kristoffer marnø from dimsr.dk
 * Copying the code or in any other way using the code in your own way: contacting quizendesigns@gmail.com
 * We have the right to the code, and is specifically designed for the LoveLamps. 
 * Do not change the code in LoveLamp File
 * Only change code in config.
 * 
 * If you wish to remake the code, feel free to do that, right after contacting us. 
 * find us at:
 * quizendesigns@gmail.com
 * or https://cults3d.com/en/users/Quicen/creations
 * or https://www.dimsr.dk/
 */

#include <Adafruit_NeoPixel.h>
#include "config.h"
#ifdef __AVR__
#include <avr/power.h>
#endif
Adafruit_NeoPixel strip(LED_COUNT, PIN, NEO_GRB + NEO_KHZ800);

AdafruitIO_Feed *lamp = io.feed("lamp");

const int interval = 10; //10 sec. 
const int WatingInterval = 300; //5 min

boolean ourtap = false;
boolean othertap = false;
boolean LoveLight = false;

int ReciveVal = 0;
int SendVal = 0;
int BothTap = 0;

void setup() {
  //save 0 to IO
  lamp->save(0);
  Serial.begin(9600);

  //define the lamp sending value
  if (LampPart == 1) {
    Serial.println("Lamp Set to 1");
    Serial.println("Sending Value 2");
    ReciveVal = 2;
    SendVal = 1;
  }
  if (LampPart == 2) {
    ReciveVal = 1;
    SendVal = 2;
    Serial.println("Lamp Set to 1");
    Serial.println("Sending Value 1");
  }

  //Activate the Neopixels
  strip.begin();
  strip.setBrightness(255);
  strip.show(); // Initialize all pixels to 'off'

  //touch sensor or button
  pinMode(Button, INPUT);


  Serial.print("Connecting to Adafruit IO");
  io.connect();
  //get the status of the value in Adafruit IO
  lamp->onMessage(handleMessage);
  //connect to Adafruit IO and play the "spin" Neopixel animation to show it's connecting until and connection is established
  while (io.status() < AIO_CONNECTED) {
    Serial.print(".");
    spin(); //connection animation
    delay(500);
  }
  //when a connection to Adafruit IO is made write the status in the Serial monitor and flash the Neopixels white
  Serial.println();
  Serial.println(io.statusText());
  flash(); //connected animation
  //get the status of our value in Adafruit IO
  lamp->get();
}

void loop() {
  io.run(); //makes IO run
  touch();  //read the touch sensor
  turnon(); //turn lamp on
  timer();  //Timer. There are no delays funktion
}

//dont change this part:
int i = 0;
void timer() {
  i++;
  delay(1);
  if (i == 2) {
    i = 0;
  }
}

void touch() {
  //once the touch sensor isn't activated, send a 0 back to the Adafruit IO feed.
  if (digitalRead(Button) == 1) {
    Serial.println("  Value Sendt to Lamp = " + SendVal);
    lamp->save(SendVal);
    ourtap = true;
    Serial.println("We have tapped our lamp");
  }
}

//code that tells the ESP32 what to do when it recieves new data from the Adafruit IO feed
void handleMessage(AdafruitIO_Data *data) {
  Serial.println("received  Data ");
  //convert the recieved data to an INT
  int reading = data->toInt();
  Serial.println(reading);
  if (reading == ReciveVal) {
    Serial.println("Other part tapped");
    othertap = true;
  } else {
  }
}

//Adafruit neopixel part. No idear on how tf this works. But it does.
void colorWipe(uint32_t color, int wait) {
  for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    delay(wait);                           //  Pause for a moment
  }
}

//this part reads if both parts have tapped their lamps
//dont change the values below.
int ix = 0;
int iy = 0;
boolean LampOn = false;
void turnon() {
  //if both lamps tapped, and lamp issent on:
  if (ourtap == true || othertap == true && LampOn == false) {
    if (i == 1) {
      ix++;
      Serial.println(ix);
    }
    if (ix > WatingInterval) { //waits for 5 min for answere
      ix = 0;
      ourtap = false;
      othertap = false;
      lamp->save(0);
      Serial.println("tap was not payed back");
      off();
    }
  }

  //when this lamp is tapped.
  if (ourtap == true && ix < WatingInterval && othertap == false) {
    //Set our lamp to Violet pink something something
    //You can add your own animation here: Just DONT USE DELAY!!! Otherwise the timer part wont work!
    colorWipe(strip.Color(255,   0,   255), 50);
    strip.show();
  }

  //When the other part has tapped
  if (othertap == true && ix < WatingInterval) {//waits for 5 min for answere
    //Set our lamp to Red
    //You can add your own animation here: Just DONT USE DELAY!!! Otherwise the timer part wont work!
    colorWipe(strip.Color(255,   0,   0), 50);
    strip.show();
  }

  //When both have tapped
  if (ourtap == true && othertap == true) {
    LampOn = true;
    //You can add your own animation here: Just DONT USE DELAY!!! Otherwise the timer part wont work!
    colorWipe(strip.Color(  0, 0,   255), 50);
    if (LampOn == true) {
      if (i == 1) {
        iy++;
      }
      if (iy > interval) { //plays the animation for 10 sec.
        ix = 0;
        iy = 0;
        lamp->save(0);
        ourtap = false;
        othertap = false;
        LampOn = false;
        off();
        lamp->save(0);
        Serial.println("tap was not payed back");
      }
    }
  }
}
