// Working

// #if defined(ESP32)
#include <WiFi.h>
#include <FirebaseESP32.h>
// #elif defined(ESP8266)
// #include <ESP8266WiFi.h>
// #include <FirebaseESP8266.h>
// #endif

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);


#define SectorNumber "sector1"

// main path
// String slot1mainpath = "kailparking/" + String(SectorNumber) + "/slot1"; // path : "kailparking/sector1/slot1"
// String slot2mainpath = "kailparking/" + String(SectorNumber) + "/slot2"; // path : "kailparking/sector1/slot1"
// String slot3mainpath = "kailparking/" + String(SectorNumber) + "/slot3"; // path : "kailparking/sector1/slot1"
// String slot4mainpath = "kailparking/" + String(SectorNumber) + "/slot4"; // path : "kailparking/sector1/slot1"
// String slot5mainpath = "kailparking/" + String(SectorNumber) + "/slot5"; // path : "kailparking/sector1/slot1"

int slot1cords = 16;
int slot2cords = 17;
int slot3cords = 18;
int slot4cords = 19;
int slot5cords = 20;


// status path
String slot1statuspath = "kailparking/" + String(SectorNumber) + "/slot1/status"; // path : "kailparking/sector1/slot1"
String slot2statuspath = "kailparking/" + String(SectorNumber) + "/slot2/status"; // path : "kailparking/sector1/slot1"
String slot3statuspath = "kailparking/" + String(SectorNumber) + "/slot3/status"; // path : "kailparking/sector1/slot1"
String slot4statuspath = "kailparking/" + String(SectorNumber) + "/slot4/status"; // path : "kailparking/sector1/slot1"
String slot5statuspath = "kailparking/" + String(SectorNumber) + "/slot5/status"; // path : "kailparking/sector1/slot1"

// cods path
String slot1cordspath = "kailparking/" + String(SectorNumber) + "/slot1/cords"; // path : "kailparking/sector1/slot1"
String slot2cordspath = "kailparking/" + String(SectorNumber) + "/slot2/cords"; // path : "kailparking/sector1/slot1"
String slot3cordspath = "kailparking/" + String(SectorNumber) + "/slot3/cords"; // path : "kailparking/sector1/slot1"
String slot4cordspath = "kailparking/" + String(SectorNumber) + "/slot4/cords"; // path : "kailparking/sector1/slot1"
String slot5cordspath = "kailparking/" + String(SectorNumber) + "/slot5/cords"; // path : "kailparking/sector1/slot1"




/*
paths:
kailparking/sector1/slot1
kailparking/sector1/slot2
kailparking/sector1/slot3
*/

//Provide the token generation process info.
#include <addons/TokenHelper.h>

//Provide the RTDB payload printing info and other helper functions.
#include <addons/RTDBHelper.h>

/* 1. Define the WiFi credentials */
#define WIFI_SSID "Wokwi-GUEST"
#define WIFI_PASSWORD ""

//For the following credentials, see examples/Authentications/SignInAsUser/EmailPassword/EmailPassword.ino

/* 2. Define the API Key */
#define API_KEY "AIzaSyDNkmRRBcDPfWCUNYdoaOQ08hyhmfQDzKM"

/* 3. Define the RTDB URL */
#define DATABASE_URL "https://smart-parking-system-5ed8b-default-rtdb.firebaseio.com/" 
//<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app

//Define Firebase Data object
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;

#define slot1 23
#define slot2 19
// #define slot3 18
#define slot4 4
#define slot5 13

// Variable Decleration
int a,b, x, y;
int mycount = 123;

int slot1var = 0;
int slot2var = 0;
int slot3var = 0;
int slot4var = 0;
int slot5var = 0;

//save requests
int prevslot1var = 0;
int prevslot2var = 0;
int prevslot3var = 0;
int prevslot4var = 0;
int prevslot5var = 0;


// Ultrasonic Part
const int trigPin = 5;
const int echoPin = 18;

//define sound speed in cm/uS
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701

long duration;
float distanceCm;
float distanceInch;

int ReadUltra(){
  // Clears the trigPin
  digitalWrite(trigPin, LOW);delayMicroseconds(2);
  // Sets the trigPin on HIGH state for 10 micro seconds
  digitalWrite(trigPin, HIGH);delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  // Reads the echoPin, returns the sound wave travel time in microseconds
  duration = pulseIn(echoPin, HIGH);
  
  // Calculate the distance
  distanceCm = duration * SOUND_SPEED/2;
  
  // Convert to inches
  distanceInch = distanceCm * CM_TO_INCH;
  
  // Prints the distance in the Serial Monitor
  Serial.print("Distance (cm): ");Serial.println(distanceCm);
  // Serial.print("Distance (inch): ");
  // Serial.println(distanceInch);
  delay(1000);
  
  if ( distanceCm <= 100){return 1;}
  else{return 0;}
}

void LcdStatus(int slo1,int slo2,int slo3,int slo4,int slo5){
  lcd.setCursor(1, 1);  lcd.print(slo1);
  lcd.setCursor(5, 1);  lcd.print(slo2);
  lcd.setCursor(8, 1);  lcd.print(slo3);
  lcd.setCursor(11, 1); lcd.print(slo4);
  lcd.setCursor(15, 1); lcd.print(slo5);
}

void updateCords(){
  if (Firebase.setInt(fbdo, slot1cordspath, slot1cords)){Serial.println("Slot1 cords uploaded " + String(slot1cords));}
  else{Serial.println("Error Slot1 cords uploading");}delay(200);

  if (Firebase.setInt(fbdo, slot2cordspath, slot2cords)){Serial.println("Slot2 cords uploaded " + String(slot2cords));}
  else{Serial.println("Error Slot2 cords uploading");}delay(200);

  if (Firebase.setInt(fbdo, slot3cordspath, slot3cords)){Serial.println("Slot3 cords uploaded " + String(slot3cords));}
  else{Serial.println("Error Slot3 cords uploading");}delay(200);
  
  if (Firebase.setInt(fbdo, slot4cordspath, slot4cords)){Serial.println("Slot4 cords uploaded " + String(slot4cords));}
  else{Serial.println("Error Slot4 cords uploading");}delay(200);

  if (Firebase.setInt(fbdo, slot5cordspath, slot5cords)){Serial.println("Slot5 cords uploaded " + String(slot5cords));}
  else{Serial.println("Error Slot5 cords uploading");}delay(200);

}



void setup()
{
  Serial.begin(115200);
  delay(2000);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");

  while (WiFi.status() != WL_CONNECTED){Serial.print(".");delay(300);}

  Serial.println();Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());Serial.println();

  Serial.printf("Firebase Client v%s\n\n", FIREBASE_CLIENT_VERSION);

  /* Assign the api key (required) */
  config.api_key = API_KEY;
  config.database_url = DATABASE_URL;
  Firebase.begin(DATABASE_URL, API_KEY);

 // Firebase.reconnectWiFi(true);

  Firebase.setDoubleDigits(5);

  pinMode(slot1, INPUT);
  pinMode(slot2, INPUT);
  // pinMode(slot3, INPUT);
  pinMode(slot4, INPUT);
  pinMode(slot5, INPUT);
  pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
  pinMode(echoPin, INPUT); // Sets the echoPin as an Input

  lcd.init();  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Kali_hackers");
  lcd.setCursor(0, 1);
  lcd.print("Smart Parking System");
  delay(1000);
  lcd.clear();
  lcd.setCursor(0, 0);  lcd.print("S1");
  lcd.setCursor(4, 0);  lcd.print("S2");
  lcd.setCursor(7, 0);  lcd.print("S3");
  lcd.setCursor(10, 0); lcd.print("S4");
  lcd.setCursor(14, 0); lcd.print("S5");
  updateCords();
}

void loop(){
  // x=random(0,9);// y=random(10,19);

  slot1var = digitalRead(slot1);delay(100);
  slot2var = digitalRead(slot2);delay(100);
  // slot3var = digitalRead(slot3);delay(100);
  slot3var = ReadUltra(); // read slot3
  slot4var = digitalRead(slot4);delay(100);
  slot5var = digitalRead(slot5);delay(100);

  // display all slot status on LCD Screen
  LcdStatus(slot1var,slot2var,slot3var,slot4var,slot5var);


  if (Firebase.ready()){
    //Firebase.setInt(fbdo, main, 5);// Firebase.setInt(fbdo, "/test/a", x);// Firebase.setInt(fbdo, "/test/b", y);
    delay(200);

    // Serial.printf("Get int a--  %s\n", Firebase.getInt(fbdo, "/test/a") ? String(fbdo.to<int>()).c_str() : fbdo.errorReason().c_str());
    //  a=fbdo.to<int>();
    // Serial.printf("Get int b--  %s\n", Firebase.getInt(fbdo, "/test/b") ? String(fbdo.to<int>()).c_str() : fbdo.errorReason().c_str());
    //  b=fbdo.to<int>();
    // Serial.printf("Get int a--  %s\n", Firebase.setInt(fbdo, "/test/b", mycount) ? String(fbdo.to<int>()).c_str() : fbdo.errorReason().c_str());

    if (prevslot1var == slot1var){Serial.println("Slot 1    same");}
    if (prevslot2var == slot2var){Serial.println("Slot 2    same");}
    if (prevslot3var == slot3var){Serial.println("Slot 3    same");}
    if (prevslot4var == slot4var){Serial.println("Slot 4    same");}
    if (prevslot5var == slot5var){Serial.println("Slot 5    same");}


    // Slot1 - data uploading
    if (prevslot1var != slot1var){
      if (Firebase.setInt(fbdo, slot1statuspath, slot1var)){Serial.println("Slot1 Data uploaded " + String(slot1var));}
      else{Serial.println("Error Slot1 data uploaded");}
      delay(200);prevslot1var = slot1var;}

    // Slot2 - data uploading
    if (prevslot2var != slot2var){
      if (Firebase.setInt(fbdo, slot2statuspath, slot2var)){Serial.println("Slot2 Data uploaded " + String(slot2var));}
      else{Serial.println("Error Slot2 data uploaded");}
      delay(200);prevslot2var = slot2var;}

    // Slot3 - data uploading
    if (prevslot3var != slot3var){
      if (Firebase.setInt(fbdo, slot3statuspath, slot3var)){Serial.println("Slot3 Data uploaded " + String(slot3var));}
      else{Serial.println("Error Slot3 data uploaded");}
      delay(200);prevslot3var = slot3var;}

    // Slot4 - data uploading
    if (prevslot4var != slot4var){
      if (Firebase.setInt(fbdo, slot4statuspath, slot4var)){Serial.println("Slot4 Data uploaded " + String(slot4var));}
      else{Serial.println("Error Slot4 data uploaded");}
      delay(200);prevslot4var = slot4var;}

    // Slot5 - data uploading
    if (prevslot5var != slot5var){
      if (Firebase.setInt(fbdo, slot5statuspath, slot5var)){Serial.println("Slot5 Data uploaded " + String(slot5var));}
      else{Serial.println("Error Slot5 data uploaded");}
      delay(200);prevslot5var = slot5var;}
    
    

    Serial.println();Serial.println("------------------------------------");Serial.println();
    delay(10000);
  }
}