#include "SPI.h"
#include <Adafruit_Sensor.h>
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <Fonts/FreeMonoBoldOblique12pt7b.h>
#include "frame.h"
#include <DHT.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include "driver/gpio.h"
#include <WiFi.h>
#include "time.h"

const char* ssid     = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

const char* ntpServer = "pool.ntp.org";
const long  gmtOffset_sec = 28800;  //Time in china or GMT+8
const int   daylightOffset_sec = 3600;
#define DHT_Pin 25
int frame1 = 0;
int frame2 = 0;
int frame3 = 0;
int frame4 = 0;
int frame5 = 0;
#define TFT_DC 4
#define TFT_CS 5
float nowTemp; 
float temperature ;
float  humidity;
float  nowHumid;
DHT dht(DHT_Pin, DHT22);  // Instantiate a dht element from the DHT object
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);

/*============ TAsk Handler==========================================*/
TaskHandle_t  tft_icons_anim = NULL;
// Fucntoin to be performed task 1 is called 
void TFT_Animation(void *pvParameters ){
 
  while (1){

    tft.fillRect(295,11,15,13,ILI9341_BLACK);
    tft.drawBitmap(290, 2, frames1[frame1], FRAME_WIDTH, FRAME_HEIGHT, ILI9341_WHITE);
    frame1 = (frame1 + 1) % FRAME_COUNT1;

    tft.fillRect(95,0,40,35,ILI9341_BLACK);
    if(nowTemp>0 && nowTemp<50)
    {
      tft.drawBitmap(100, 0, frames2[frame2], FRAME_WIDTH, FRAME_HEIGHT, ILI9341_YELLOW);
      frame2 = (frame2 + 1) % FRAME_COUNT2;
    }

    else if(nowTemp>=50)
    {
      tft.drawBitmap(100, 0, frames5[frame5], FRAME_WIDTH, FRAME_HEIGHT, ILI9341_RED);
      frame5 = (frame5 + 1) % FRAME_COUNT5;
    }
    else 
    {
      tft.drawBitmap(100, 0, frames4[frame4], FRAME_WIDTH, FRAME_HEIGHT, ILI9341_WHITE);
      frame4 = (frame4 + 1) % FRAME_COUNT4;
    }
    

    tft.fillRect(0,0,35,30,ILI9341_BLACK);
    tft.drawBitmap(1, 0, frames3[frame3], FRAME_WIDTH, FRAME_HEIGHT, ILI9341_WHITE);
    frame3 = (frame3 + 1) % FRAME_COUNT3; 
    vTaskDelay(250);
  }
  
};
/*============ TAsk Handler==========================================*/
TaskHandle_t  DHT_Task_handle = NULL;
// Fucntoin to be performed task 2 is called 
void DHT_Task(void *pvParameters ){

  while(1){
    nowTemp   = dht.readTemperature(false);                //temperature from the dht 
    nowHumid  = dht.readHumidity();                       //humidity from the dht
    if (temperature != nowTemp){
      tft.fillRect(0,60,300,40,ILI9341_BLACK);
      tft.setFont(&FreeMonoBoldOblique12pt7b); 
      
      if(nowTemp>=50)
      {
        tft.setTextColor(ILI9341_RED);
      }
      else if(nowTemp<=0)
      {
        tft.setTextColor(ILI9341_BLUE);
      }
      tft.setTextSize(0.8);
      tft.setCursor(0, 80); 
      tft.print("Temperature: "+ String(nowTemp)+"C");  //Draw new time
      temperature = nowTemp;
      Serial.println(nowTemp);
    }

    if (humidity != nowHumid){
      tft.fillRect(0, 100, 300, 40,ILI9341_BLACK);
      tft.setFont(&FreeMonoBoldOblique12pt7b); 
      
      if(nowHumid>=50)
      {
        tft.setTextColor(ILI9341_RED);
      }
      tft.setTextSize(0.8);
      tft.setCursor(0, 120); 
      tft.print("Humidity: "+ String(nowHumid)+"%");  //Draw new time
      humidity = nowHumid;
      Serial.println(nowHumid);
    }
    vTaskDelay(50);
  }
   
};
/*============ TAsk Handler==========================================*/
TaskHandle_t  NPT_Task_handle = NULL;
// Fucntoin to be performed task 3 is called 
void NPT_Task(void *pvParameters ){
  while(true)
  {
    struct tm timeinfo;
    if(!getLocalTime(&timeinfo)){
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo);
  }

  
};


void setup() {
  tft.begin();
  pinMode(DHT_Pin, INPUT);
  tft.invertDisplay(false);
  tft.setRotation(1);
  Serial.begin(115200);

   // Connect to Wi-Fi
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin("Wokwi-GUEST", "", 6);  // This funtion is used only for Wokwi
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected.");
  
  // Init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

void loop() {

 tft.setTextColor(ILI9341_WHITE);
 xTaskCreatePinnedToCore(TFT_Animation, "TFT_Animation", 4000, NULL, 5, &tft_icons_anim, 1);
 xTaskCreatePinnedToCore(DHT_Task, "DHT_Task", 4000, NULL, 3, &DHT_Task_handle, 0);
 xTaskCreatePinnedToCore(NPT_Task, "NPT_Task", 4000, NULL, 5, &NPT_Task_handle, 1);

}