#include <Arduino.h>


#include <Wire.h>

#include <SPI.h>
#include <TFT_eSPI.h> 
#include "FT62XXTouchScreen.h"

TFT_eSPI tft = TFT_eSPI();
FT62XXTouchScreen touchScreen = FT62XXTouchScreen(TFT_WIDTH, PIN_SDA, PIN_SCL);

#include "lvgl.h"
#include "widgets/meter/lv_meter.h"
#include "esp_freertos_hooks.h"

static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];




lv_obj_t *screenMain;
lv_obj_t *tabview;
  lv_obj_t *tab_AQS;
    lv_obj_t *label;
    lv_obj_t *btn1;
    lv_obj_t *btn2;
    lv_obj_t *btn_calib;
  lv_obj_t *tab_SET;
  lv_obj_t *guage;
  lv_obj_t * lmeter;


static void event_handler_btn(lv_obj_t * obj, lv_event_t event){
    if(event == LV_EVENT_CLICKED) {
        if (obj == btn1)
          lv_label_set_text(label, "Hello");
        else if (obj == btn2){
          lv_label_set_text(label, "Goodbye");
        }
    }
}

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
    uint32_t w = (area->x2 - area->x1 + 1);
    uint32_t h = (area->y2 - area->y1 + 1);

    tft.startWrite();
    tft.setAddrWindow(area->x1, area->y1, w, h);
    tft.pushColors(&color_p->full, w * h, true);
    tft.endWrite();

    lv_disp_flush_ready(disp);
}

uint16_t lastx = 0;
uint16_t lasty = 0;

bool my_input_read2(lv_indev_drv_t * drv, lv_indev_data_t*data) {
  Serial.println("#");
  TouchPoint touchPos = touchScreen.read();
  if (touchPos.touched) {
    Serial.println(String(touchPos.xPos) + ": " + String(touchPos.yPos));
    data->state = LV_INDEV_STATE_PR;
    data->point.x = touchPos.xPos;
    data->point.y = touchPos.yPos;
    lastx = touchPos.xPos;
    lasty = touchPos.yPos;
  } else {
    data->state = LV_INDEV_STATE_REL;
     data->point.x = lastx;
     data->point.y = lasty;
     
  }
  return false;
}
static void lv_tick_task(void)
{
 lv_tick_inc(portTICK_RATE_MS);
}

void Create_PM_guage(lv_obj_t* par)
{
    /*Describe the color for the needles*/
    static lv_color_t needle_colors[] = {LV_COLOR_BLUE, LV_COLOR_RED, LV_COLOR_YELLOW};

    LV_IMG_DECLARE(img_hand);

    /*Create a gauge*/
    guage = lv_gauge_create(par, NULL);
    lv_gauge_set_needle_count(guage, 3, needle_colors);
    lv_obj_set_size(guage, 200, 200);
    lv_obj_align(guage, NULL, LV_ALIGN_CENTER, 100, 0);
    lv_gauge_set_needle_img(guage, &img_hand, 4, 4);
    /*Allow recoloring of the images according to the needles' color*/
    lv_obj_set_style_local_image_recolor_opa(guage, LV_GAUGE_PART_NEEDLE, LV_STATE_DEFAULT, LV_OPA_COVER);

    /*Set the values*/
    lv_gauge_set_value(guage, 0, 10);
}

void lv_ex_tabview(lv_obj_t* par)
{
    /*Create a Tab view object*/
    tabview = lv_tabview_create(par, NULL);

    /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/
    tab_AQS = lv_tabview_add_tab(tabview, "AirQuality");
    tab_SET = lv_tabview_add_tab(tabview, "Settings");
    lv_tabview_set_anim_time(tabview,2);
}

void lv_Create_text(lv_obj_t* par)
{
  label = lv_label_create(par, NULL);
  lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
  lv_label_set_text(label, "Press a button");
  lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
  lv_obj_set_size(label, 240, 40);
  lv_obj_set_pos(label, 0, 15);
}

void lv_Create_button1(lv_obj_t* par)
{
  btn1 = lv_btn_create(par, NULL);
  lv_obj_set_event_cb(btn1, event_handler_btn);
  lv_obj_set_width(btn1, 70);
  lv_obj_set_height(btn1, 32);
  lv_obj_set_pos(btn1, 32, 100);
  lv_obj_t * label1 = lv_label_create(btn1, NULL);
  lv_label_set_text(label1, "Hello");
}

void lv_Create_btnCalibrate(lv_obj_t* par)
{
  btn_calib = lv_btn_create(par, NULL);
  lv_obj_set_event_cb(btn_calib, event_handler_btn);
  lv_obj_set_width(btn_calib, 150);
  lv_obj_set_height(btn_calib, 32);
  lv_obj_set_pos(btn_calib, 32, 185);
  lv_obj_t * label1 = lv_label_create(btn_calib, NULL);
  lv_label_set_text(label1, "Calibrate");
}

void lv_Create_button2(lv_obj_t* par)
{
  btn2 = lv_btn_create(par, NULL);
  lv_obj_set_event_cb(btn2, event_handler_btn);
  lv_obj_set_width(btn2, 70);
  lv_obj_set_height(btn2, 32);
  lv_obj_set_pos(btn2, 142, 100);
  lv_obj_t * label2 = lv_label_create(btn2, NULL);
  lv_label_set_text(label2, "Goodbye");
}


void setup() {
  lv_disp_drv_t disp_drv;
  lv_indev_drv_t indev_drv;

  Serial.begin(115200);
  lv_init();
  // Setup tick hook for lv_tick_task
  /*esp_err_t err = */esp_register_freertos_tick_hook((esp_freertos_tick_cb_t)lv_tick_task);

  // Enable TFT
  tft.begin();
  tft.setRotation(1);

  // Enable Backlight
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL,1);

  // Start TouchScreen
  touchScreen.begin();


  // Display Buffer
  lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);

  // Init Display
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = 480;
  disp_drv.ver_res = 320;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.buffer = &disp_buf;
  lv_disp_drv_register(&disp_drv);

  // Init Touchscreen
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_input_read2;
  lv_indev_drv_register(&indev_drv);

  // Screen Object
  screenMain = lv_obj_create(NULL, NULL);

  lv_ex_tabview(screenMain);

  // Text
  lv_Create_text(tab_SET);

  // BUtton 1
  lv_Create_button1(tab_SET);

  lv_Create_btnCalibrate(tab_SET);

  // Button 2
  lv_Create_button2(tab_SET);

  Create_PM_guage(tab_AQS);

  // Screen load
  lv_scr_load(screenMain);
}

void loop() {
  lv_task_handler();
  delay(1);
}
