#include <TFT_eSPI.h>      // Hardware-specific library
#include <SPI.h>
#include <ESP32-TWAI-CAN.hpp>


TFT_eSPI tft = TFT_eSPI(); // Invoke custom library
CanFrame canframe;

#include "Logo.h"
//offset of all the graphics if the screen is incorrecly placed in the cluster
int offset_x = 3;
int offset_y = 2;



/*###############################
          Functions
###############################*/

void clearBot() {
  tft.fillSmoothRoundRect(8 + offset_x, 61 + offset_y, 145, 57, 5, TFT_BLACK, TFT_BLACK);
}
void drawTopLine() {
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextSize(2);
  tft.setTextDatum(ML_DATUM);
  tft.drawFloat(26.3, 1, 4 + offset_x, 14 + offset_y);                      //draw temp value
  tft.drawChar(53 + offset_x, 6 + offset_y, 0xF7, TFT_WHITE, TFT_BLACK, 2); //draw degree sign
  tft.setTextDatum(MR_DATUM);
  tft.drawString("15:15", 157 + offset_x, 14 + offset_y);      //draw time
}
void logo1(uint16_t color1, uint16_t color2) {
  //Circles
  tft.fillSmoothCircle(80 + offset_x, 89 + offset_y, 26, color2, TFT_BLACK);
  tft.fillSmoothCircle(80 + offset_x, 89 + offset_y, 22, color1, color2);
  tft.fillSmoothCircle(80 + offset_x, 89 + offset_y, 18, color2, color1);
  //topV
  tft.fillTriangle(70 + offset_x, 72 + offset_y, 77 + offset_x, 87 + offset_y, 82 + offset_x, 87 + offset_y, color1); //  first
  tft.fillTriangle(73 + offset_x, 69 + offset_y, 70 + offset_x, 72 + offset_y, 82 + offset_x, 87 + offset_y, color1); //  this part /*  \   */
  tft.fillTriangle(86 + offset_x, 69 + offset_y, 77 + offset_x, 87 + offset_y, 82 + offset_x, 87 + offset_y, color1); //  this one /
  tft.fillTriangle(90 + offset_x, 72 + offset_y, 86 + offset_x, 69 + offset_y, 82 + offset_x, 87 + offset_y, color1); //  last
  //bottomW
  tft.fillTriangle(62 + offset_x, 78 + offset_y, 66 + offset_x, 78 + offset_y, 69 + offset_x, 104 + offset_y, color1);
  tft.fillTriangle(69 + offset_x, 104 + offset_y, 66 + offset_x, 75 + offset_y, 76 + offset_x, 106 + offset_y, color1);
  tft.fillTriangle(70 + offset_x, 107 + offset_y, 77 + offset_x, 90 + offset_y, 82 + offset_x, 90 + offset_y, color1);
  tft.fillTriangle(74 + offset_x, 108 + offset_y, 70 + offset_x, 107 + offset_y, 82 + offset_x, 90 + offset_y, color1);
  tft.fillTriangle(90 + offset_x, 107 + offset_y, 77 + offset_x, 90 + offset_y, 82 + offset_x, 90 + offset_y, color1);
  tft.fillTriangle(90 + offset_x, 106 + offset_y, 85 + offset_x, 107 + offset_y, 79 + offset_x, 93 + offset_y, color1);
  tft.fillTriangle(83 + offset_x, 108 + offset_y, 94 + offset_x, 75 + offset_y, 98 + offset_x, 81 + offset_y, color1);
  tft.fillTriangle(86 + offset_x, 106 + offset_y, 91 + offset_x, 107 + offset_y, 97 + offset_x, 76 + offset_y, color1);
}

void printCanFrame(CanFrame p_CAN_Frame, uint8_t index = 0) {

  char str[12];

  canframe.identifier = random(0x0, 0x7FF);
  canframe.data_length_code = random(1, 8);
  canframe.data[0] = random(0x0, 0xFF);
  canframe.data[1] = random(0x0, 0xFF);
  canframe.data[2] = random(0x0, 0xFF);
  canframe.data[3] = random(0x0, 0xFF);
  canframe.data[4] = random(0x0, 0xFF);
  canframe.data[5] = random(0x0, 0xFF);
  canframe.data[6] = random(0x0, 0xFF);
  canframe.data[7] = random(0x0, 0xFF);

  tft.setTextDatum(ML_DATUM);
  for (int i = 0; i < 8; i++) {                             //parse through data[0-length]
    if (i < p_CAN_Frame.data_length_code) {
      sprintf(str, "%.2X", p_CAN_Frame.data[i]);
      tft.drawString(str, 35 + i * 15 + offset_x, 66 + index * 8 + offset_y);
    }
    else tft.drawString("  ", 35 + i * 15 + offset_x, 66 + index * 8 + offset_y);
  }
  sprintf(str, "%.3X", p_CAN_Frame.identifier);              //id
  tft.drawString(str, 10 + offset_x, 66 + index * 8 + offset_y);

}

void setup() {
  Serial.begin(115200);
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);
  tft.setSwapBytes(true);


  tft.drawRect(0 + offset_x, 0 + offset_y, 160, 25, TFT_RED);
  tft.setCursor(10 + offset_x, 2 + offset_y);
  tft.setTextColor(TFT_RED);
  tft.setTextSize(3);

  tft.println("GOLF GTD");


  tft.drawSmoothRoundRect(7 + offset_x, 60 + offset_y, 5, 5, 146, 58, TFT_RED, TFT_BLACK); //x,y,r1,r2, w,h, color, bgcolor
  logo1(TFT_WHITE, TFT_BLUE);
  delay(1000);
  tft.pushImage(53 + offset_x, 62  + offset_y, logoWidth, logoHeight, logo);
  delay(1000);
  tft.fillRect(1 + offset_x, 1 + offset_y, 158, 23, TFT_BLACK);  //reset top
  drawTopLine();
  clearBot();
}

void loop() {
  tft.drawString("CAN test", 125 + offset_x, 89 + offset_y);
  delay(1000);
  tft.fillRect(1 + offset_x, 1 + offset_y, 158, 23, TFT_BLACK);  //reset top
  clearBot();

  tft.setTextSize(2);
  tft.drawString("CAN in hex", 135 + offset_x, 13 + offset_y);
  tft.setTextSize(1);

  while (1) {

    for (int x = 0; x < 7; x++) {
      printCanFrame(canframe, x);
    }
    delay(1000);

  }
}