#include "Arduino.h"                      //KNIHOVNY
#include <WiFi.h>
#include <WiFiClient.h> 
#include <ESP32_FTPClient.h>
#include "esp_camera.h"
#include "FS.h"
#include "SPI.h"
#include "SD.h"
#include "driver/rtc_io.h"
#include "ESP32_MailClient.h"
#include "time.h"
#include "camera_pins.h"
#ifdef ESP32
  #include <WiFi.h>
  #include <HTTPClient.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESP8266HTTPClient.h>
  #include <WiFiClient.h>
#endif

#define CAMERA_MODEL_AI_THINKER



const char* ntpServer = "pool.ntp.org";         //time
const long  gmtOffset_sec = 3600;
const int   daylightOffset_sec = 3600;

#define WIFI_SSID             "WifiName"
#define WIFI_PASSWORD         "WifiPswd"


char ftp_server[] = "files.000webhost.com";
char ftp_user[]   = "Name";
char ftp_pass[]   = "Password";
ESP32_FTPClient ftp (ftp_server,ftp_user,ftp_pass, 5000, 2);

const char* serverName = "http://home363.000webhostapp.com/post-esp-data.php"; // REPLACE with your Domain name and URL path or IP address with path
String key = "tPmAT5Ab3j7F9";
String location ="Chodba";
String type="camera";




void setup() 
{
  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting...");



  //connect to WiFi network
  Serial.print("Connecting to AP");
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");
    delay(200);
  }

  Serial.println("");
  Serial.println("WiFi connected.");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println();


   HTTPClient http;
    http.begin("http://home363.000webhostapp.com/on_of.php");
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");  // Specify content-type header
    String httpRequestData = "key=" + key + "&type=on_off";// Prepare your HTTP POST request data
    
    int httpResponseCode = http.POST(httpRequestData); // Send HTTP POST request
    if (httpResponseCode>0) {
      Serial.print("HTTP Response code: ");
      Serial.println(httpResponseCode);
      String payload= http.getString();
      payload.trim();
      http.end();
      if(payload=="on"){

              pinMode(4, INPUT);              //GPIO for LED flash
              digitalWrite(4, LOW);
              rtc_gpio_hold_dis(GPIO_NUM_4);  //diable pin hold if it was enabled before sleeping
                        
            camera_config_t config;
            config.ledc_channel = LEDC_CHANNEL_0;
            config.ledc_timer = LEDC_TIMER_0;
            config.pin_d0 = Y2_GPIO_NUM;
            config.pin_d1 = Y3_GPIO_NUM;
            config.pin_d2 = Y4_GPIO_NUM;
            config.pin_d3 = Y5_GPIO_NUM;
            config.pin_d4 = Y6_GPIO_NUM;
            config.pin_d5 = Y7_GPIO_NUM;
            config.pin_d6 = Y8_GPIO_NUM;
            config.pin_d7 = Y9_GPIO_NUM;
            config.pin_xclk = XCLK_GPIO_NUM;
            config.pin_pclk = PCLK_GPIO_NUM;
            config.pin_vsync = VSYNC_GPIO_NUM;
            config.pin_href = HREF_GPIO_NUM;
            config.pin_sscb_sda = SIOD_GPIO_NUM;
            config.pin_sscb_scl = SIOC_GPIO_NUM;
            config.pin_pwdn = PWDN_GPIO_NUM;
            config.pin_reset = RESET_GPIO_NUM;
            config.xclk_freq_hz = 20000000;
            config.pixel_format = PIXFORMAT_JPEG;
            
            //init with high specs to pre-allocate larger buffers
            if(psramFound())
            {
              config.frame_size = FRAMESIZE_UXGA;
              config.jpeg_quality = 10;
              config.fb_count = 2;
            } else 
            {
              config.frame_size = FRAMESIZE_SVGA;
              config.jpeg_quality = 12;
              config.fb_count = 1;
            }
          
          
          
            //initialize camera
            esp_err_t err = esp_camera_init(&config);
            if (err != ESP_OK) 
            {
              Serial.printf("Camera init failed with error 0x%x", err);
              return;
            }
          
            //set the camera parameters
            sensor_t * s = esp_camera_sensor_get();
            s->set_contrast(s, 2);    //min=-2, max=2
            s->set_brightness(s, 2);  //min=-2, max=2
            s->set_saturation(s, 2);  //min=-2, max=2
            delay(100);               //wait a little for settings to take effect
            
            //mount SD card
            Serial.println("Mounting SD Card...");
            
            MailClient.sdBegin(14,2,15,13);
            if(!SD.begin())
            {
              Serial.println("Card Mount Failed");
              return;
            }
          
           
          
            //take new image
            camera_fb_t * fb = NULL;
              
            //obtain camera frame buffer
            fb = esp_camera_fb_get();
            if (!fb) 
            {
              Serial.println("Camera capture failed");
              Serial.println("Exiting now"); 
              while(1);   //wait here as something is not right
            }
          
            //save to SD card
            //generate file path
          
          //TIME
            configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);     //time
            struct tm timeinfo;
            if(!getLocalTime(&timeinfo)){
              Serial.println("Failed to obtain time");
              return;
            }
            
            char get_cas[11];
            strftime(get_cas,11, "%Y%H%M%S", &timeinfo);
            const char* const_cas=get_cas;
            String cas= const_cas;
            String path = "/public_html/img/IMG" + cas + ".jpg";      //name
            
            
            fs::FS &fs = SD;
          
            
            File file = fs.open(path.c_str(), FILE_WRITE);    //CREATE NEW FILE
            if(!file)
            {
              Serial.println("Failed to create file");
              Serial.println("Exiting now"); 
              while(1);   //wait here as something is not right    
            } 
            else      
            {
              file.write(fb->buf, fb->len); 
           
             
            }
            file.close();
          
          
          
          
            ftp.OpenConnection();             //FTP START
          
            // Get directory content
          
            
            const char *f_name = path.c_str();
          
            ftp.ChangeWorkDir("/public_html/img/");
            ftp.InitFile("Type I");
            ftp.NewFile( f_name );
            ftp.WriteData(fb->buf, fb->len);
            ftp.CloseFile();
            ftp.CloseConnection(); //FTP END  
          
            HTTPClient http;                                                                                                                //HTTP START
              http.begin(serverName);// Your Domain name with URL path or IP address with path
              http.addHeader("Content-Type", "application/x-www-form-urlencoded");  // Specify content-type header
              String httpRequestData = "location=" + location + "&key=" + key + "&type=" + type + "&url=" + path;// Prepare your HTTP POST request data
              
              Serial.print("httpRequestData: ");
              Serial.println(httpRequestData);
              
              int httpResponseCode = http.POST(httpRequestData); // Send HTTP POST request
                  
              if (httpResponseCode>0) {
                Serial.print("HTTP Response code: ");
                Serial.println(httpResponseCode);
                String payload = http.getString();
                Serial.println(payload); 
              }
              else {
                Serial.print("Error code: ");
                Serial.println(httpResponseCode);
              }
              // Free resources
              http.end();                                                                                                                 //HTTP END
          
            //return camera frame buffer
            esp_camera_fb_return(fb);
            Serial.printf("Image saved: %s\n", path.c_str());

       
      }else{
        Serial.println("off");
      }
    }
    else {
      Serial.print("Error code: ");
      Serial.println(httpResponseCode);
    }
    // Free resources
    




       
 
  
  pinMode(4, OUTPUT);              //GPIO for LED flash
  digitalWrite(4, LOW);            //turn OFF flash LED
  rtc_gpio_hold_en(GPIO_NUM_4);    //make sure flash is held LOW in sleep
  Serial.println("Entering deep sleep mode");
  Serial.flush(); 
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 1);   //wake up when pin 13 goes HIGH
  delay(10000);                                   //wait for 10 seconds to let PIR sensor settle
  esp_deep_sleep_start();
}

void loop() 
{


}
