#include "Arduino.h"
#include "camera.h"
// WARNING!!! Make sure that you have either selected ESP32 Wrover Module, or another board which has PSRAM enabled
// Select camera model
//#define CAMERA_MODEL_WROVER_KIT
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER
#include "camera_pins.h"

//int a;

bool initCamera(){
    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;
	}

#if defined(CAMERA_MODEL_ESP_EYE)
	pinMode(13, INPUT_PULLUP);
	pinMode(14, INPUT_PULLUP);
#endif

	// camera init
	esp_err_t err = esp_camera_init(&config);
	if (err != ESP_OK)
	{
		Serial.printf("Camera init failed with error 0x%x", err);
		return false;
	}

	sensor_t *s = esp_camera_sensor_get();
	//initial sensors are flipped vertically and colors are a bit saturated
	if (s->id.PID == OV3660_PID)
	{
		s->set_vflip(s, 1);		  //flip it back
		s->set_brightness(s, 1);  //up the blightness just a bit
		s->set_saturation(s, -2); //lower the saturation
	}
	//drop down frame size for higher initial frame rate
	s->set_framesize(s, FRAMESIZE_QVGA);

#if defined(CAMERA_MODEL_M5STACK_WIDE)
	s->set_vflip(s, 1);
	s->set_hmirror(s, 1);
#endif
  return true;
}


//#define CAM_AI_THINKER initCamera2(32,-1,0,26,27,35,34,39,36,21,19,18,5,25,23,22)

/*EDU US*/ bool initCamera2(int _PWDN_GPIO_NUM,int _RESET_GPIO_NUM,int _XCLK_GPIO_NUM,int _SIOD_GPIO_NUM,int _SIOC_GPIO_NUM,int _Y9_GPIO_NUM,int _Y8_GPIO_NUM,int _Y7_GPIO_NUM,int _Y6_GPIO_NUM,int _Y5_GPIO_NUM,int _Y4_GPIO_NUM,int _Y3_GPIO_NUM,int _Y2_GPIO_NUM,int _VSYNC_GPIO_NUM,int _HREF_GPIO_NUM,int _PCLK_GPIO_NUM, bool _vflip, bool _hmirror,String _framesize){
    camera_config_t config;
	config.ledc_channel = LEDC_CHANNEL_0;
	config.ledc_timer = LEDC_TIMER_0;
	Serial.println();
	Serial.println("--------------------");
	Serial.print("EDU : You can choose your pins with:");
	Serial.println("initCamera2(PWDN,RESET,XCLK,SIOD,SIOC,Y9,Y8,Y7,Y6,Y5,Y4,Y3,Y2,VSYNC,HREF,PCLK)");  
	Serial.println("--------------------");
	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;
	}

#if defined(CAMERA_MODEL_ESP_EYE)
	pinMode(13, INPUT_PULLUP);
	pinMode(14, INPUT_PULLUP);
#endif

	// camera init
	esp_err_t err = esp_camera_init(&config);
	if (err != ESP_OK)
	{
		Serial.printf("Camera init failed with error 0x%x", err);
		return false;
	}

	sensor_t *s = esp_camera_sensor_get();
	//EDU
		if (_vflip){
			s->set_vflip(s, 1);
		}
		if (_hmirror){
			s->set_hmirror(s, 1);
		}
		
		
		// switch (_framesize) {
  // case "QVGA":
    // config.frame_size = FRAMESIZE_QVGA;
    // break;
  // case "CIF":
    // config.frame_size = FRAMESIZE_CIF;
    // break;
  // case "VGA":
    // config.frame_size = FRAMESIZE_VGA;
    // break;
  // case "SVGA":
    // config.frame_size = FRAMESIZE_SVGA;
    // break;
  // case "XGA":
    // config.frame_size = FRAMESIZE_XGA;
    // break;
  // case "SXGA":
    // config.frame_size = FRAMESIZE_SXGA;
    // break;
  // case "UXGA":
    // config.frame_size = FRAMESIZE_UXGA;
    // break;
// }
	Serial.println("cameraok");
if (_framesize=="QVGA") {
//config.frame_size = FRAMESIZE_QVGA;
s->set_framesize(s, FRAMESIZE_QVGA);
} else if (_framesize=="CIF") {
//config.frame_size = FRAMESIZE_CIF;
s->set_framesize(s, FRAMESIZE_CIF);
} else if (_framesize=="VGA") {
//config.frame_size = FRAMESIZE_VGA;
s->set_framesize(s, FRAMESIZE_VGA);
} else if (_framesize=="SVGA") {
//config.frame_size = FRAMESIZE_SVGA;
s->set_framesize(s, FRAMESIZE_SVGA);
} else if (_framesize=="XGA") {
//config.frame_size = FRAMESIZE_XGA;
s->set_framesize(s, FRAMESIZE_XGA);
} else if (_framesize=="SXGA") {
//config.frame_size = FRAMESIZE_SXGA;
s->set_framesize(s, FRAMESIZE_SXGA);
} else if (_framesize=="UXGA") {
//config.frame_size = FRAMESIZE_UXGA;
s->set_framesize(s, FRAMESIZE_UXGA);
}
	
		Serial.println("camera ok2");
		
		//config.frame_size = "FRAMESIZE_"+_framesize;
	// END EDU
	
	//initial sensors are flipped vertically and colors are a bit saturated
	if (s->id.PID == OV3660_PID)
	{
		s->set_vflip(s, 1);		  //flip it back
		s->set_brightness(s, 1);  //up the blightness just a bit
		s->set_saturation(s, -2); //lower the saturation
	}
	//drop down frame size for higher initial frame rate
//s->set_framesize(s, FRAMESIZE_QVGA);

#if defined(CAMERA_MODEL_M5STACK_WIDE)
	s->set_vflip(s, 1);
	s->set_hmirror(s, 1);
#endif
  return true;
}
//*/


/*
#include <WiFi.h>
#include "file.h"
#include "camera.h"
#include "lapse.h"

const char *ssid = "Duinoedu";
const char *password = "0712760712";

void startCameraServer();

void setup(){
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();
  initFileSystem();
  
  //---- Ancienne initialisation (utilisable mais plus utile)
  //initCamera(); 
  
  //---- Initialisation par étiquette
  //initCamera2(AI_THINKER_ESP32_CAM); 
  
  //---- Initialisation par série de broches
  initCamera2(32,-1,0,26,27,35,34,39,36,21,19,18,5,25,23,22); //(PWDN, RESET, XCLK, SIOD, SIOC, Y9, Y8, Y7, Y6, Y5, Y4, Y3, Y2, VSYNC, HREF, PCLK)
  
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
  startCameraServer();
  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");
}

void loop(){
  unsigned long t = millis();
  static unsigned long ot = 0;
  unsigned long dt = t - ot;
  ot = t;
  processLapse(dt);
}

*/