/*
 *
 *    Copyright (c) 2020-2023 Project CHIP Authors
 *    Copyright (c) 2018 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
#include <string.h>

#include "driver/ledc.h"
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/timers.h"

#include "Display.h"

#if CONFIG_HAVE_DISPLAY

// Brightness picked such that it's easy for cameras to focus on
#define DEFAULT_BRIGHTNESS_PERCENT 10

// 8MHz is the recommended SPI speed to init the driver with
// It later gets set to the preconfigured defaults within the driver
#define TFT_SPI_CLOCK_INIT_HZ 8000000

// The frequency used by the ledc timer
// value chosen to eliminate flicker
#define LEDC_PWM_HZ 1000

// with a duty resolution of LEDC_TIMER_8_BIT
// the highest possible brightness value is 255
#define BRIGHTNESS_MAX 255
// The M5Stack's backlight is on Channel 7
#define BACKLIGHT_CHANNEL LEDC_CHANNEL_7

static const char * TAG = "Display";

uint16_t DisplayHeight = 0;
uint16_t DisplayWidth  = 0;

bool awake = false;

#if CONFIG_DISPLAY_AUTO_OFF
// FreeRTOS timer used to turn the display off after a short while
TimerHandle_t displayTimer = NULL;
#endif

#if CONFIG_DISPLAY_AUTO_OFF
static void TimerCallback(TimerHandle_t xTimer);
#endif
static void SetupBrightnessControl();
static void SetBrightness(uint16_t brightness_percent);

esp_err_t InitDisplay()
{
    esp_err_t err;
    spi_lobo_device_handle_t spi;

    // configured based on the display driver's examples
    spi_lobo_bus_config_t buscfg;
    memset((void *) &buscfg, 0, sizeof(buscfg));
    buscfg.miso_io_num   = PIN_NUM_MISO; // set SPI MISO pin
    buscfg.mosi_io_num   = PIN_NUM_MOSI; // set SPI MOSI pin
    buscfg.sclk_io_num   = PIN_NUM_CLK;  // set SPI CLK pin
    buscfg.quadwp_io_num = -1;
    buscfg.quadhd_io_num = -1;

    spi_lobo_device_interface_config_t devcfg;
    memset((void *) &devcfg, 0, sizeof(devcfg));
    devcfg.clock_speed_hz   = TFT_SPI_CLOCK_INIT_HZ;
    devcfg.mode             = 0;                        // SPI mode 0
    devcfg.spics_io_num     = -1;                       // we will use external CS pin
    devcfg.spics_ext_io_num = PIN_NUM_CS;               // external CS pin
    devcfg.flags            = LB_SPI_DEVICE_HALFDUPLEX; // ALWAYS SET  to HALF DUPLEX MODE!! for display spi
    tft_max_rdclock         = TFT_SPI_CLOCK_INIT_HZ;

    // Initialize all pins used by display driver.
    TFT_PinsInit();

    // Initialize SPI bus and add a device for the display.
    err = spi_lobo_bus_add_device(TFT_HSPI_HOST, &buscfg, &devcfg, &spi);
    if (err != ESP_OK)
        return err;

    // Configure the display to use the new SPI device.
    tft_disp_spi = spi;

    err = spi_lobo_device_select(spi, 1);
    if (err != ESP_OK)
        return err;
    err = spi_lobo_device_deselect(spi);
    if (err != ESP_OK)
        return err;

    // Initialize the display driver.
    TFT_display_init();

    // Detect maximum read speed and set it.
    tft_max_rdclock = find_rd_speed();

    // Set the SPI clock speed overriding the initialized 8MHz speed
    spi_lobo_set_speed(spi, DEFAULT_SPI_CLOCK);

    TFT_setGammaCurve(0);
    TFT_setRotation(LANDSCAPE);
    TFT_resetclipwin();

    DisplayWidth  = (uint16_t)(1 + tft_dispWin.x2 - tft_dispWin.x1);
    DisplayHeight = (uint16_t)(1 + tft_dispWin.y2 - tft_dispWin.y1);

    ESP_LOGI(TAG, "Display initialized (height %u, width %u)", DisplayHeight, DisplayWidth);

    TFT_invertDisplay(INVERT_DISPLAY);

    // prepare the display for brightness control
    SetupBrightnessControl();

#if CONFIG_DISPLAY_AUTO_OFF
    displayTimer = xTimerCreate("DisplayTimer", pdMS_TO_TICKS(DISPLAY_TIMEOUT_MS), false, NULL, TimerCallback);
#endif
    // lower the brightness of the screen
    WakeDisplay();

    return err;
}

void SetBrightness(uint16_t brightness_percent)
{
    uint16_t brightness = (brightness_percent * BRIGHTNESS_MAX) / 100;
    if (ledc_set_duty(LEDC_HIGH_SPEED_MODE, BACKLIGHT_CHANNEL, brightness) ||
        ledc_update_duty(LEDC_HIGH_SPEED_MODE, BACKLIGHT_CHANNEL))
    {
        ESP_LOGE(TAG, "Failed to set display brightness...");
    }
}

bool WakeDisplay()
{
    bool woken = !awake;
    awake      = true;
    SetBrightness(DEFAULT_BRIGHTNESS_PERCENT);
#if CONFIG_DISPLAY_AUTO_OFF
    xTimerStart(displayTimer, 0);
    ESP_LOGI(TAG, "Display awake but will switch off automatically in %d seconds", DISPLAY_TIMEOUT_MS / 1000);
#endif
    return woken;
}

void ClearDisplay()
{
    ClearRect();
}

void ClearRect(uint16_t x_percent_start, uint16_t y_percent_start, uint16_t x_percent_end, uint16_t y_percent_end)
{
    if (x_percent_end < x_percent_start)
    {
        x_percent_end = x_percent_start;
    }
    if (y_percent_end < y_percent_start)
    {
        y_percent_end = y_percent_start;
    }
    uint16_t start_x = (DisplayWidth * x_percent_start) / 100;
    uint16_t start_y = (DisplayHeight * y_percent_start) / 100;
    uint16_t end_x   = (DisplayWidth * x_percent_end) / 100;
    uint16_t end_y   = (DisplayHeight * y_percent_end) / 100;
    TFT_fillRect(start_x, start_y, end_x, end_y, TFT_BLACK);
}

void DisplayStatusMessage(char * msg, uint16_t vpos)
{
    TFT_setFont(SMALL_FONT, NULL);
    uint16_t msgX = 0;
    uint16_t msgY = (DisplayHeight * vpos) / 100;
    TFT_print(msg, msgX, msgY);
}

void TimerCallback(TimerHandle_t xTimer)
{
    ESP_LOGI(TAG, "Display going to sleep...");
    SetBrightness(0);
    awake = false;
}

void SetupBrightnessControl()
{
    ledc_timer_config_t ledc_timer;
    memset(&ledc_timer, 0, sizeof(ledc_timer));

    ledc_timer.duty_resolution = LEDC_TIMER_8_BIT;     // resolution of PWM duty
    ledc_timer.freq_hz         = LEDC_PWM_HZ;          // frequency of PWM signal
    ledc_timer.speed_mode      = LEDC_HIGH_SPEED_MODE; // timer mode
    ledc_timer.timer_num       = LEDC_TIMER_0;         // timer index
    ledc_timer_config(&ledc_timer);

    ledc_timer_set(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, LEDC_PWM_HZ, LEDC_TIMER_8_BIT, LEDC_REF_TICK);

    ledc_channel_config_t ledc_channel;
    memset(&ledc_channel, 0, sizeof(ledc_channel));
    ledc_channel.channel    = BACKLIGHT_CHANNEL;
    ledc_channel.duty       = BRIGHTNESS_MAX;
    ledc_channel.gpio_num   = PIN_NUM_BCKL;
    ledc_channel.speed_mode = LEDC_HIGH_SPEED_MODE;
    ledc_channel.timer_sel  = LEDC_TIMER_0;
    ledc_channel_config(&ledc_channel);
}

#endif // CONFIG_HAVE_DISPLAY
