#include "esp_camera.h"
#include "cameraPins.h"

class Camera
{
public:
    bool init(framesize_t frameSize, uint8_t quantizer)
    {
        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;
        config.frame_size = frameSize;
        config.jpeg_quality = quantizer;
        config.fb_count = 2;
        bool result = esp_camera_init(&config) == ESP_OK;
        _sensor = esp_camera_sensor_get();
        return result;
    }
    void setWindow(int startX, int startY, int endX, int endY, int offsetX, int offsetY, int totalX, int totalY, int outputX, int outputY, bool scale, bool binning)
    {
        _sensor->set_res_raw(_sensor, startX, startY, endX, endY, offsetX, offsetY, totalX, totalY, outputX, outputY, scale, binning);
    }
    void set_denoise(int amt) {
        _sensor->set_denoise(_sensor, amt);
    }
    void set_ae_level(int amt) {
        _sensor->set_ae_level(_sensor, amt);
    }
    uint8_t *run(void) {
        if(_frameBuffer != NULL)
            esp_camera_fb_return(_frameBuffer);
        _frameBuffer = esp_camera_fb_get();
        return _frameBuffer->buf;
    }
    void clearBuffer() {
        if(_frameBuffer != NULL)
            esp_camera_fb_return(_frameBuffer);
    }
    size_t getBufferLen(void) {
        return _frameBuffer->len;
    }
    

protected:
    camera_fb_t *_frameBuffer;
    sensor_t *_sensor;
};