// Grafik Routinen
#define GRAFIK

// #include "handlebme280.h"
#include "main.h"
#include "grafik.h"

// Definition der diversen Farben
#define TEXTCOLOTR_TFAUSSEN 0x57d3F7
#define BACKGROUND_COLOR 0xD3F0FF
#define TEXTCOLOR 0x0000FF
#define TEXTCOLOR_FEUCHTE 0xFF0000
#define TEXTCOLOR_XACHSE 0x0000FF
#define TEXTCOLOR_INFO 0x404040

#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];

static lv_obj_t *chart;
static lv_coord_t bmewert[MAXREADINGS];
static lv_coord_t bmewert_hum[MAXREADINGS];

void setup_grafik(void)
{
  lv_init();
  lv_display_t *disp;
  disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));

  for (int i = 0; i < MAXREADINGS; i++)
  {
    bmewert[i] = 0;
    bmewert_hum[i] = 30;
  }
}


void buildarc(ARC arc)
{
  lv_obj_set_size(arc.arc, arc.size, arc.size);
  lv_arc_set_rotation(arc.arc, 180);
  lv_arc_set_bg_angles(arc.arc, 0, 180);
  lv_arc_set_value(arc.arc, arc.value+arc.value_offset);
  lv_obj_align(arc.arc, LV_ALIGN_LEFT_MID, arc.x, arc.y);
  lv_obj_remove_style(arc.arc, NULL, LV_PART_KNOB);

  // Style this arc
  static lv_style_t style_arc;
  lv_style_init(&style_arc);
  lv_style_set_arc_width(&style_arc, 20);
  lv_style_set_arc_rounded(&style_arc, false);
  lv_obj_add_style(arc.arc, &style_arc, LV_PART_MAIN);
  lv_obj_add_style(arc.arc, &style_arc, LV_PART_INDICATOR);

  lv_obj_t *low_label = lv_label_create(arc.arc);
  char valuelow[10];
  sprintf(valuelow, "%d", arc.lowvalue);
  lv_label_set_text(low_label, valuelow);
  lv_obj_align(low_label, LV_ALIGN_LEFT_MID, 5, 8);
  static lv_style_t style_low_label;
  lv_style_init(&style_low_label);
  lv_style_set_text_font(&style_low_label, &lv_font_montserrat_10);
  lv_obj_add_style(low_label, &style_low_label, 0);

  lv_obj_t *value_label = lv_label_create(arc.arc);
  char value[10];
  sprintf(value, arc.valformat, arc.value + arc.value_offset);
  // Serial.println(value);
  lv_label_set_text(value_label, value);
  lv_obj_align(value_label, LV_ALIGN_LEFT_MID, 38 + arc.value_xoffset, 0);
  static lv_style_t style_value_label;
  lv_style_init(&style_value_label);
  lv_style_set_text_font(&style_value_label, &lv_font_montserrat_18);
  lv_obj_add_style(value_label, &style_value_label, 0);

  lv_obj_t *high_label = lv_label_create(arc.arc);
  char valuehigh[10];
  sprintf(valuehigh, "%d", arc.highvalue);
  lv_label_set_text(high_label, valuehigh);
  lv_obj_align(high_label, LV_ALIGN_LEFT_MID, 90, 8);
  static lv_style_t style_high_label;
  lv_style_init(&style_high_label);
  lv_style_set_text_font(&style_high_label, &lv_font_montserrat_10);
  lv_obj_add_style(high_label, &style_high_label, 0);

  /*  lv_obj_t * unit_label = lv_label_create(arc.arc);
    lv_label_set_text(unit_label, arc.unit);
    lv_obj_align(unit_label, LV_ALIGN_LEFT_MID, 48, 8);
    static lv_style_t style_unit_label;
    lv_style_init(&style_unit_label);
    lv_style_set_text_font(&style_unit_label, &lv_font_montserrat_12);
    lv_obj_add_style(unit_label, &style_unit_label, 0);
  */
}

void showAussenData(float val, bool what)
{
  ta_label = lv_label_create(lv_screen_active());
  lv_label_set_text(ta_label," ");
  tta_label = lv_label_create(lv_screen_active());
  lv_label_set_text(tta_label," ");

  fa_label = lv_label_create(lv_screen_active());
  lv_label_set_text(fa_label," ");
  tfa_label = lv_label_create(lv_screen_active());
  lv_label_set_text(tfa_label," ");

  static lv_style_t style_ta_label;
  lv_style_init(&style_ta_label);
  lv_style_set_text_font(&style_ta_label, &lv_font_montserrat_16);
  lv_obj_add_style(ta_label, &style_ta_label, 0);
  lv_obj_add_style(fa_label, &style_ta_label, 0);

  static lv_style_t style_tta_label;
  lv_style_init(&style_tta_label);
  lv_style_set_text_font(&style_tta_label, &lv_font_montserrat_10);
  lv_style_set_text_color(&style_tta_label, lv_color_hex(TEXTCOLOTR_TFAUSSEN));
  lv_obj_add_style(tta_label, &style_tta_label, 0);
  lv_obj_add_style(tfa_label, &style_tta_label, 0);
}

void lv_create_main_gui(void)
{

  // Create a text label aligned on top: https://docs.lvgl.io/master/widgets/label.html
  time_label = lv_label_create(lv_screen_active());
  lv_label_set_text(time_label, "17:30");
  lv_obj_align(time_label, LV_ALIGN_TOP_MID, 0, 8);

  // Set font type and font size. More information: https://docs.lvgl.io/master/overview/font.html
  static lv_style_t style_time_label;
  lv_style_init(&style_time_label);
  lv_style_set_text_font(&style_time_label, &lv_font_montserrat_28);
  lv_obj_add_style(time_label, &style_time_label, 0);

  // Create a text label aligned on top: https://docs.lvgl.io/master/widgets/label.html
  date_label = lv_label_create(lv_screen_active());
  lv_label_set_text(date_label, "Dienstag, 12. Dezember 2024");
  lv_obj_align(date_label, LV_ALIGN_TOP_MID, 0, 38);

  // Set font type and font size. More information: https://docs.lvgl.io/master/overview/font.html
  static lv_style_t style_date_label;
  lv_style_init(&style_date_label);
  lv_style_set_text_font(&style_date_label, &lv_font_montserrat_12);
  lv_obj_add_style(date_label, &style_date_label, 0);

  /* Refresh-Symbol anzeigen
    lv_obj_t * refresh_label = lv_label_create(lv_screen_active());
    lv_label_set_text(refresh_label, LV_SYMBOL_REFRESH);
    lv_obj_align(refresh_label, LV_ALIGN_CENTER, 0, -45);
  */

  /*Create an Arc*/
  lv_obj_t *aTemp = lv_arc_create(lv_screen_active());
  arcTemp.arc = aTemp;
  buildarc(arcTemp);
  lv_obj_t *aHum = lv_arc_create(lv_screen_active());
  arcHum.arc = aHum;
  buildarc(arcHum);

  lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(BACKGROUND_COLOR), LV_PART_MAIN);

  showAussenData(0, true);
  showAussenData(0, false);

//  show2lines();
}

void setValuetoArc(ARC arc, float value)
{
  int r = arc.highvalue - arc.lowvalue;
  int v = (value - arc.lowvalue) * 100 / r;
  arc.value = v;
  lv_arc_set_value(arc.arc, arc.value);
  lv_obj_t *value_label = lv_obj_get_child(arc.arc, 1);
  char valuestr[10];
  sprintf(valuestr, arc.valformat, value);
  lv_label_set_text(value_label, valuestr);

  if (strcmp(arc.name, "humi") == 0)
  {
    if (value < arc.green)
    {
      lv_obj_set_style_arc_color(arc.arc, lv_palette_main(LV_PALETTE_GREEN), LV_PART_INDICATOR);
    }
    else if (value < arc.yellow)
    {
      lv_obj_set_style_arc_color(arc.arc, lv_palette_main(LV_PALETTE_YELLOW), LV_PART_INDICATOR);
    }
    else
    {
      lv_obj_set_style_arc_color(arc.arc, lv_palette_main(LV_PALETTE_RED), LV_PART_INDICATOR);
    }
  }
}
#define CONTAINER_WIDTH SCREEN_WIDTH
#define CONTAINER_HEIGHT SCREEN_HEIGHT - 140
#define LEFTAXIS_WIDTH 25
#define RIGHTAXIS_WIDTH 15
#define CHART_WIDTH (CONTAINER_WIDTH - LEFTAXIS_WIDTH - RIGHTAXIS_WIDTH - 40)
#define CHART_HEIGHT (CONTAINER_HEIGHT)

void drawChart()
{
  Serial.println("draw_chart ");
  int scaleHeight = 85;

  // Create a container to display the chart and scale
  lv_obj_t *container_row = lv_obj_create(lv_screen_active());
  lv_obj_set_size(container_row, CONTAINER_WIDTH, CONTAINER_HEIGHT);
  lv_obj_align(container_row, LV_ALIGN_BOTTOM_MID, 0, -4);
  // Set the container in a flexbox row layout aligned center
  lv_obj_set_flex_flow(container_row, LV_FLEX_FLOW_ROW);
  lv_obj_set_flex_align(container_row, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
  lv_obj_set_scrollbar_mode(container_row, LV_SCROLLBAR_MODE_OFF);
  static lv_style_t style_container_row;
  lv_style_set_pad_row(&style_container_row, 0);
  // lv_style_set_bg_color(&style_container_row, lv_palette_lighten(LV_PALETTE_LIGHT_BLUE, 4));
  lv_obj_add_style(container_row, &style_container_row, 0);
  lv_obj_set_style_border_side(container_row, LV_BORDER_SIDE_NONE, LV_PART_MAIN);
  lv_obj_set_style_bg_color(container_row, lv_color_hex(BACKGROUND_COLOR), LV_PART_MAIN);

  // linke Axe
  lv_obj_t *scaleT = lv_scale_create(container_row);
  lv_obj_set_size(scaleT, 30, scaleHeight);
  lv_scale_set_mode(scaleT, LV_SCALE_MODE_VERTICAL_LEFT);

  static const char *scaleT_labels[6] = {"15°C", "20°C", "25°C", "30°C", "35°C"};
  lv_scale_set_text_src(scaleT, scaleT_labels);
  lv_scale_set_label_show(scaleT, true);

  lv_scale_set_total_tick_count(scaleT, 21);
  lv_scale_set_major_tick_every(scaleT, 5);

  lv_obj_set_style_length(scaleT, 0, LV_PART_ITEMS);
  lv_obj_set_style_length(scaleT, 0, LV_PART_INDICATOR);
  lv_obj_set_style_line_width(scaleT, 0, LV_PART_ITEMS);
  lv_obj_set_style_line_width(scaleT, 0, LV_PART_INDICATOR);
  lv_obj_set_style_line_width(scaleT, 0, LV_PART_MAIN);
  lv_scale_set_range(scaleT, 15, 35);

  static lv_style_t style_scaleT;
  lv_style_init(&style_scaleT);
  lv_style_set_text_font(&style_scaleT, &lv_font_montserrat_10);
  lv_style_set_text_color(&style_scaleT, lv_color_hex(TEXTCOLOR));
  //        lv_style_set_bg_color(&style_scaleT, lv_color_hex(0xFF00FF));
  lv_obj_add_style(scaleT, &style_scaleT, 0);

  // Create a chart
  // Info: die Breite eines X-Abschnittes (von vertikaler Linie zu vertikaler Linie) beträgt 55 Pixel
  chart = lv_chart_create(container_row);
  lv_obj_set_size(chart, CHART_WIDTH, CHART_HEIGHT);
  lv_chart_set_type(chart, LV_CHART_TYPE_LINE); /*Show lines and points too*/
  lv_chart_set_point_count(chart, MAXREADINGS);
  lv_chart_set_div_line_count(chart, 5, 5);
  lv_chart_set_range(chart, LV_CHART_AXIS_SECONDARY_Y, 40, 100);
  lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 15, 35);
  lv_obj_set_style_size(chart, 0, 0, LV_PART_INDICATOR); // No points on line
  lv_obj_set_scrollbar_mode(chart, LV_SCROLLBAR_MODE_OFF);
  lv_obj_set_style_border_width(chart, 0, LV_PART_MAIN); // No border
  lv_obj_set_style_bg_color(chart, lv_color_hex(BACKGROUND_COLOR), LV_PART_MAIN);

  // lv_obj_set_style_pad_right(chart, -10, LV_PART_MAIN);  // No border
  /*Add data series*/
  lv_chart_series_t *ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_BLUE), LV_CHART_AXIS_PRIMARY_Y);
  lv_chart_set_ext_y_array(chart, ser1, (lv_coord_t *)bmewert);

  lv_chart_series_t *ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_SECONDARY_Y);
  lv_chart_set_ext_y_array(chart, ser2, (lv_coord_t *)bmewert_hum);

  lv_chart_refresh(chart); /*Required after direct set*/

  // rechte Axe
  lv_obj_t *scale = lv_scale_create(container_row);
  lv_obj_set_size(scale, 30, scaleHeight);
  lv_scale_set_mode(scale, LV_SCALE_MODE_VERTICAL_RIGHT);

  static const char *scale_labels[5] = {"40%", "55%", "70%", "85%", "100%"};
  lv_scale_set_text_src(scale, scale_labels);
  lv_scale_set_label_show(scale, true);

  lv_scale_set_total_tick_count(scale, 21);
  lv_scale_set_major_tick_every(scale, 5);

  lv_obj_set_style_length(scale, 0, LV_PART_ITEMS);
  lv_obj_set_style_length(scale, 0, LV_PART_INDICATOR);
  lv_obj_set_style_line_width(scale, 0, LV_PART_ITEMS);
  lv_obj_set_style_line_width(scale, 1, LV_PART_INDICATOR);
  lv_obj_set_style_line_width(scale, 0, LV_PART_MAIN);
  lv_obj_set_style_bg_color(scale, lv_color_hex(BACKGROUND_COLOR), LV_PART_MAIN);
  lv_scale_set_range(scale, 40, 100);

  static lv_style_t style_scale;
  lv_style_init(&style_scale);
  lv_style_set_text_font(&style_scale, &lv_font_montserrat_10);
  lv_style_set_text_color(&style_scale, lv_color_hex(TEXTCOLOR_FEUCHTE));
  lv_obj_add_style(scale, &style_scale, 0);

  // X-Achse
  lv_obj_t *xscale = lv_scale_create(chart);
  lv_obj_set_size(xscale, 220, 30);
  lv_scale_set_mode(xscale, LV_SCALE_MODE_HORIZONTAL_TOP);

  //static const char *xscale_labels[6] = {"200", "150", "100", "50", "0"};
  //lv_scale_set_text_src(xscale, xscale_labels);
  lv_scale_set_label_show(xscale, true);

  lv_scale_set_total_tick_count(xscale, 21);
  lv_scale_set_major_tick_every(xscale, 5);

  lv_obj_set_style_length(xscale, 0, LV_PART_ITEMS);
  lv_obj_set_style_length(xscale, 0, LV_PART_INDICATOR);
  lv_obj_set_style_line_width(xscale, 0, LV_PART_ITEMS);
  lv_obj_set_style_line_width(xscale, 0, LV_PART_INDICATOR);
  lv_obj_set_style_line_width(xscale, 0, LV_PART_MAIN);
  lv_scale_set_range(xscale, -110, 0);
  lv_obj_set_pos(xscale, 5, -25);


  static lv_style_t style_xscale;
  lv_style_init(&style_xscale);
  lv_style_set_text_font(&style_xscale, &lv_font_montserrat_10);
  lv_style_set_text_color(&style_xscale, lv_color_hex(TEXTCOLOR_XACHSE));
  lv_obj_add_style(xscale, &style_xscale, 0);

  // Text als Überschrift an die Axen
  lv_obj_t *feuchte_label = lv_label_create(lv_screen_active());
  lv_label_set_text(feuchte_label, "Feuchte");
  lv_obj_align(feuchte_label, LV_ALIGN_RIGHT_MID, -3, 8);

  lv_obj_t *temp_label = lv_label_create(lv_screen_active());
  lv_label_set_text(temp_label, "Temperatur");
  lv_obj_align(temp_label, LV_ALIGN_LEFT_MID, 3, 8);

  // Set font type and font size. More information: https://docs.lvgl.io/master/overview/font.html
  static lv_style_t style_tf_label;
  lv_style_init(&style_tf_label);
  lv_style_set_text_font(&style_tf_label, &lv_font_montserrat_10);
  lv_obj_add_style(feuchte_label, &style_tf_label, 0);
  lv_obj_add_style(temp_label, &style_tf_label, 0);

  /* ganz unten etwas Info anzeigen */
  // Style dafür
  static lv_style_t style_info_label;
  lv_style_init(&style_info_label);
  lv_style_set_text_font(&style_info_label, &lv_font_montserrat_8);
  lv_style_set_text_color(&style_info_label, lv_color_hex(TEXTCOLOR_INFO));

  // Versionsnummer, IP-Adresse und Datum
  lv_obj_t *version_label = lv_label_create(lv_screen_active());
  char ver[40];
  sprintf(ver, "V %s %s %s", VERSION, VDATE, VTIME);
  lv_label_set_text(version_label, ver);
  lv_obj_align(version_label, LV_ALIGN_BOTTOM_RIGHT, -4, 0);
  lv_obj_add_style(version_label, &style_info_label, LV_PART_MAIN);
}

void showRate(int r) {
  char rate[20];
  sprintf(rate, "Rate: %ds", r);
  lv_label_set_text(bmr_label, rate);
}

void updatechartData(float value, float humvalue)
{
  int i = 0;
  for (i = 0; i < MAXREADINGS - 1; i++)
  {
    bmewert[i] = bmewert[i + 1];
    bmewert_hum[i] = bmewert_hum[i + 1];
  }
  bmewert[MAXREADINGS - 1] = value;
  bmewert_hum[MAXREADINGS - 1] = humvalue;

  lv_chart_refresh(chart);
}

void setAussenDataValues(float val, bool what, struct tm t)
{
  if (what)
  {
    lv_label_set_text_fmt(ta_label,"Ta:\n%.1f °C", val);
    lv_obj_align(ta_label, LV_ALIGN_TOP_LEFT, 10, 10);
    lv_label_set_text_fmt(tta_label,"%02d:%02d\n", t.tm_hour, t.tm_min);
    lv_obj_align(tta_label, LV_ALIGN_TOP_LEFT, 10, 45);
  }
  else
  {
    lv_label_set_text_fmt(fa_label,"Fa:\n%.0f %%", val);
    lv_obj_align(fa_label, LV_ALIGN_TOP_RIGHT, -10, 10);
    lv_label_set_text_fmt(tfa_label,"%02d:%02d\n", t.tm_hour, t.tm_min);
    lv_obj_align(tfa_label, LV_ALIGN_TOP_RIGHT, -23, 45);
  }
}

void show2lines() {
  int x1 = 104;
  int x2 = x1 + 56;
  static lv_point_precise_t line1_points[] = { {x1, 70}, {x1, 220} };
  static lv_point_precise_t line2_points[] = { {x2, 70}, {x2, 220}};

  static lv_style_t style_line;
  lv_style_init(&style_line);
  lv_style_set_line_width(&style_line, 1);
  lv_style_set_line_color(&style_line, lv_palette_main(LV_PALETTE_BLUE));

  lv_obj_t *line1, *line2;
  line1 = lv_line_create(lv_screen_active());
  lv_line_set_points(line1,  line1_points, 2);
  lv_obj_add_style(line1, &style_line, 0);

  line2 = lv_line_create(lv_screen_active());
  lv_line_set_points(line2,  line2_points, 2);
  lv_obj_add_style(line2, &style_line, 0);
}

void showResetTime(struct tm tinfo) {
    static lv_style_t style_info_label;
    lv_style_init(&style_info_label);
    lv_style_set_text_font(&style_info_label, &lv_font_montserrat_8);
    lv_style_set_text_color(&style_info_label, lv_color_hex(TEXTCOLOR_INFO));

    char date[20];
    strftime(date, 20, "%d-%m-%Y %H:%M", &tinfo);

    lv_obj_t *resdate_label = lv_label_create(lv_screen_active());
    lv_label_set_text(resdate_label, date);
    lv_obj_align(resdate_label, LV_ALIGN_BOTTOM_LEFT, 4, 0);
    lv_obj_add_style(resdate_label, &style_info_label, LV_PART_MAIN);
}

void setDateTime(char *time, char *date)
{
    lv_label_set_text(time_label, time);
    lv_label_set_text(date_label, date);
}

