// More information at: https://www.aeq-web.com/arduino-tft-lcd-interface/?ref=arduinoide
 
#include <Elegoo_GFX.h>    // Core graphics library
#include <Elegoo_TFTLCD.h> // Hardware-specific library
#include <TouchScreen.h>

#if defined(__SAM3X8E__)
#undef __FlashStringHelper::F(string_literal)
#define F(string_literal) string_literal
#endif

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7

// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).
//   D0 connects to digital pin 22
//   D1 connects to digital pin 23
//   D2 connects to digital pin 24
//   D3 connects to digital pin 25
//   D4 connects to digital pin 26
//   D5 connects to digital pin 27
//   D6 connects to digital pin 28
//   D7 connects to digital pin 29


#define YP A3  // must be an analog pin, use "An" notation!
#define XM A2  // must be an analog pin, use "An" notation!
#define YM 9   // can be a digital pin
#define XP 8   // can be a digital pin

//Touch For New ILI9341 TP
#define TS_MINX 120
#define TS_MAXX 900

#define TS_MINY 70
#define TS_MAXY 920

// For better pressure precision, we need to know the resistance
// between X+ and X- Use any multimeter to read it
// For the one we're using, its 300 ohms across the X plate
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);

#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// optional
#define LCD_RESET A4

// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#define GRAY    0xDEFB

Elegoo_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

#define PENRADIUS 3

long crontimer = millis();
String runtime = "00:00:00";
int t_sec = 0;
int t_min = 0;
int t_hour = 0;
int fbutton_id = 0;
int clickcounter = 0;
int screen_id = 0;
int value_bar = 0;
boolean runstop = true;
void setup(void) {
  Serial.begin(9600);
  Serial.println(F("Paint!"));

  tft.reset();

  uint16_t identifier = tft.readID();
  if (identifier == 0x9325) {
    Serial.println(F("Found ILI9325 LCD driver"));
  } else if (identifier == 0x9328) {
    Serial.println(F("Found ILI9328 LCD driver"));
  } else if (identifier == 0x4535) {
    Serial.println(F("Found LGDP4535 LCD driver"));
  } else if (identifier == 0x7575) {
    Serial.println(F("Found HX8347G LCD driver"));
  } else if (identifier == 0x9341) {
    Serial.println(F("Found ILI9341 LCD driver"));
  } else if (identifier == 0x8357) {
    Serial.println(F("Found HX8357D LCD driver"));
  } else if (identifier == 0x0101)
  {
    identifier = 0x9341;
    Serial.println(F("Found 0x9341 LCD driver"));
  } else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.println(F("If using the Elegoo 2.8\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_Elegoo_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Elegoo_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    identifier = 0x9341;
  }

  tft.begin(identifier);
  tft.setRotation(1);
  screen_main();
}

#define MINPRESSURE 10
#define MAXPRESSURE 1000

void loop()
{

  TSPoint p = ts.getPoint();
  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

  if (p.z > MINPRESSURE && p.z < MAXPRESSURE) {

    // scale from 0->1023 to tft.width
    p.x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
    p.y = (tft.height() - map(p.y, TS_MINY, TS_MAXY, tft.height(), 0));

    //Display received X an Y value from touch
    Serial.print("("); Serial.print(p.x);
    Serial.print(", "); Serial.print(p.y);
    Serial.println(")");

    if (screen_id == 0) {//Get touch on Main-Screen

      if (p.x > 280 && p.y > 180) {
        fbutton_id = 1;
        clickcounter++;
        screen_f1();
      }

      if (p.x > 280 && p.y < 180 && p.y > 120) {
        fbutton_id = 2;
        clickcounter++;
        screen_f2();
      }

      if (p.x > 280  && p.y < 120 && p.y > 60) {
        fbutton_id = 3;
        clickcounter++;
        screen_f3();
      }


    } else if (screen_id == 1) { //F1 screen action
      if (p.x > 200 && p.x < 250 && p.y < 220 && p.y > 160) {
        clickcounter++;
        screen_main();
        //Action on F1-Screen yes
      }

      if (p.x > 200 && p.x < 250  && p.y < 75 && p.y > 20) {
        clickcounter++;
        screen_main();
        //Action on F1-Screen no
      }
    }

    else if (screen_id == 2) { //F2 screen action
      if (p.x > 200 && p.x < 250 && p.y < 150 && p.y > 95) {
        clickcounter++;
        screen_main();
        //Action on F2-Screen ok
      }
    }

    else if (screen_id == 3) { //F3 screen action
      if (p.x > 200 && p.x < 250 && p.y < 155 && p.y > 95) {
        clickcounter++;
        screen_main();
        //Action on F3-Screen ok
      }
      if (p.x > 130 && p.x < 170 && p.y < 225 && p.y > 13) {
        value_bar = (216 - p.y + 8) / 2.1;
        tft.fillRect(15 + value_bar * 2.9, 100, 290 - value_bar * 2.9, 30, WHITE);
        tft.fillRect(15, 100, value_bar * 2.9, 30, RED);
        tft.fillRect(120, 40, 120, 40 , BLACK);
        tft.setCursor(125, 50);
        tft.setTextColor(WHITE);
        tft.setTextSize(3);
        tft.print(value_bar);
        tft.println("%");
        //Action if value-bar changed
      }
    }
  
   if (p.x > 280  && p.y <= 60 && p.y >= 0) {//F4 screen action
      fbutton_id = 4;
      clickcounter++;
      if (runstop == true) {
        runstop = false;
      } else {
        runstop = true;
      }
      screen_main();
    }
  }

//Refresh Timer every second
  if ( millis() > crontimer + 1000) {

    t_sec++;
    if (t_sec > 59) {
      t_sec = 0;
      t_min++;
    }
    if (t_min > 59) {
      t_min = 0;
      t_hour++;
    }
    if (t_hour > 99) {
      runtime = "--:--:--";
    } else {
      String s = String(t_sec);
      String m = String(t_min);
      String h = String(t_hour);
      if (t_sec < 10) {
        s = "0" + String(t_sec);
      }
      if (t_min < 10) {
        m = "0" + String(t_min);
      }
      if (t_hour < 10) {
        h = "0" + String(t_hour);
      }
      runtime = h + ":" + m + ":" + s;
    }
    //Clear time box and write new time inside
    if (screen_id == 0) {
      tft.fillRect(0, 151, 150, 49 , BLACK);
      tft.setCursor(0, 154);
      tft.setTextColor(BLUE);
      tft.setTextSize(1);
      tft.println("TIME:");
      tft.setCursor(0, 170);
      tft.setTextColor(GREEN);
      tft.setTextSize(3);
      tft.println(runtime);
    }
    crontimer = millis();
  }
}

//Build MAIN screen
void screen_main() {
  screen_id = 0;
  tft.fillScreen(BLACK);
  tft.drawLine(0, 50, 320, 50, WHITE);     //Draw first horizontal line
  tft.drawLine(100, 0, 100, 50, WHITE);    //Draw first vertical line
  tft.drawLine(220, 0, 220, 50, WHITE);    //Draw second vertical line
  tft.drawLine(0, 150, 320, 150, WHITE);   //Draw second horizontal line
  tft.drawLine(0, 200, 320, 200, WHITE);   //Draw third horizontal line
  tft.drawLine(150, 150, 150, 200, WHITE); //Draw third vertical line
  tft.drawLine(220, 150, 220, 200, WHITE); //Draw fourth vertical line
  tft.setCursor(0, 0);
  //Show Temperature box
  tft.setTextColor(BLUE);
  tft.setTextSize(1);
  tft.println("TEMP:");
  tft.setCursor(3, 15);
  tft.setTextColor(GREEN);
  tft.setTextSize(3);
  tft.println("-22.8");
  //Show F-Button box
  tft.setCursor(105, 0);
  tft.setTextColor(BLUE);
  tft.setTextSize(1);
  tft.println("LAST BUTTON:");
  tft.setCursor(140, 15);
  tft.setTextColor(GREEN);
  tft.setTextSize(3);
  tft.print("F");
  tft.print(fbutton_id);
  //Show Battery box
  tft.setCursor(225, 0);
  tft.setTextColor(BLUE);
  tft.setTextSize(1);
  tft.println("BATTERY:");
  tft.setCursor(225, 15);
  tft.setTextColor(GREEN);
  tft.setTextSize(3);
  tft.println("100%");
  //Show RUN or STOP text
  if (runstop == true) {
    tft.setCursor(105, 80);
    tft.setTextColor(GREEN);
    tft.setTextSize(6);
    tft.println("RUN");
  } else {
    tft.setCursor(95, 80);
    tft.setTextColor(RED);
    tft.setTextSize(6);
    tft.println("STOP");
  }
  //Show F3 box value
  tft.setCursor(154, 154);
  tft.setTextColor(BLUE);
  tft.setTextSize(1);
  tft.println("F3 VALUE:");
  tft.setCursor(160, 170);
  tft.setTextColor(YELLOW);
  tft.setTextSize(3);
  tft.println(value_bar);
  //Show clickcounter
  tft.setCursor(225, 154);
  tft.setTextColor(BLUE);
  tft.setTextSize(1);
  tft.println("COUNTER:");
  tft.setCursor(225, 170);
  tft.setTextColor(GREEN);
  tft.setTextSize(3);
  tft.println(clickcounter);

  //Build F1 button
  tft.fillRect(0, 200, 80, 40, WHITE);
  tft.setCursor(25, 210);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("F1");
  //Build F2 button
  tft.fillRect(80, 200, 80, 40, GRAY);
  tft.setCursor(105, 210);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("F2");
  //Build F3 button
  tft.fillRect(160, 200, 80, 40, WHITE);
  tft.setCursor(185, 210);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("F3");
  //Build F4 button
  tft.fillRect(240, 200, 80, 40, GRAY);
  tft.setCursor(265, 210);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("F4");
}

//Generate F1 screen
void screen_f1() {
  screen_id = 1;
  tft.fillScreen(BLACK);
  tft.setCursor(0, 50);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("  Do you want to");
  tft.println("     proceed?"   );
  //Generate YES button
  tft.fillRect(20, 150, 80, 40, WHITE);
  tft.setCursor(33, 160);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("YES");
  //Generate NO button
  tft.fillRect(220, 150, 80, 40, WHITE);
  tft.setCursor(243, 160);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("NO");
}

//Generate F2 screen
void screen_f2() {
  screen_id = 2;
  tft.fillScreen(BLACK);
  tft.setCursor(85, 50);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.println("Info Box");
  //Generate OK button
  tft.fillRect(115, 150, 80, 40, WHITE);
  tft.setCursor(138, 160);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("OK");
}

//Generate F3 screen
void screen_f3() {
  screen_id = 3;
  tft.fillScreen(BLACK);
  tft.setCursor(125, 50);
  tft.setTextColor(WHITE);
  tft.setTextSize(3);
  tft.print(value_bar);
  tft.println("%");
  tft.fillRect(15 + value_bar * 2.9, 100, 290 - value_bar * 2.9, 30, WHITE);
  tft.fillRect(15, 100, value_bar * 2.9, 30, RED);
  //Generate OK button
  tft.fillRect(115, 150, 80, 40, WHITE);
  tft.setCursor(138, 160);
  tft.setTextColor(BLACK);
  tft.setTextSize(3);
  tft.println("OK");
}
