#include <Arduino.h>
#include <Adafruit_GFX.h>    // Libreria de graficos
#include <Adafruit_TFTLCD.h> // Libreria de LCD
#include <TouchScreen.h>     // Libreria del panel tactil
void lecturaPanel();
void draw_btn1(bool on);
void draw_btn2(bool on);
int get_btn();

// Pines necesarios para los 4 pines del panel tactil
#define YP A1 // Pin analogico A1 para ADC
#define XM A2 // Pin analogico A2 para ADC
#define YM 7
#define XP 6

// Definimos la presion máxima y minima que podemos realizar sobre el panel
#define MINPRESSURE 1
#define MAXPRESSURE 1000

// Para mejor precision de la presion realizada, es necesario
// medir la resistencia entre los pines X+ y X-.
// En Shield TFT 2.4" LCD se mide entre los pines A2 y 6
// Instancia del panel tactil (Pin XP, YP, XM, YM, Resistencia del panel)
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 364);

short TS_MINX = 150; // Coordenadas del panel tactil para delimitar
short TS_MINY = 120; // el tamaño de la zona donde podemos presionar
short TS_MAXX = 850; // y que coincida con el tamaño del LCD
short TS_MAXY = 891;

#define LCD_CS A3 // Definimos los pines del LCD
#define LCD_CD A2 // para poder visualizar elementos graficos
#define LCD_WR A1
#define LCD_RD A0
#define LCD_RESET A4

#define BLACK 0x0000 // Definimos los colores
#define BLUE 0x001F  // que utilizaremos para
#define RED 0xF800   // el texto y los elementos graficos
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET); // Instancia LCD

int X; // Variables que almacenaran la coordenada
int Y; // X, Y donde presionemos y la variable Z
int Z; // almacenara la presion realizada

bool btn1_press = false; // variable "flag" para control rebotes
bool btn2_press = false; // variable "flag" para control rebotes

#define ledA 21
#define ledK 20

void setup(void)
{
  tft.begin(0x9325); // Iniciamos el LCD especificando el controlador ILI9341.

  tft.fillScreen(BLACK); // Pintamos la pantalla de Rojo
  tft.setRotation(0); // Establecemos la posición de la pantalla Vertical u Horizontal
  draw_btn1(true);
  draw_btn2(true);
  Serial.begin(115200);
}

void loop()
{
  lecturaPanel(); // Realizamos lectura del panel para detectar presion y coordenadas

  // Si la pulsación del eje X se produce entre los puntos 40 y 160
  // Y la pulsacion del eje Y se produce entre los puntos 20 y 60
  // Y la presión realizada esta entre el margen determinado
  int btn = get_btn();
  switch (btn)
  {
  case 1:
      draw_btn1(btn1_press);
      btn1_press = !btn1_press;
      Serial.print("Boton 1 >> ");
      Serial.println(btn1_press);
      delay(150);
    break;
  case 2:
      draw_btn2(btn2_press);
      btn2_press = !btn2_press; 
      Serial.print("Boton 2 >> ");
      Serial.println(btn2_press);
      delay(150);
  default:
    break;
  }
}

void lecturaPanel()
{
  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint(); // Realizamos lectura de las coordenadas
  digitalWrite(13, LOW);

  pinMode(XM, OUTPUT); // La librería utiliza estos pines como entrada y salida
  pinMode(YP, OUTPUT); // por lo que es necesario declararlos como salida justo
                       // despues de realizar una lectura de coordenadas.

  // Mapeamos los valores analogicos leidos del panel tactil (0-1023)
  // y los convertimos en valor correspondiente a la medida del LCD 320x240
  X = map(p.x, TS_MAXX, TS_MINX, tft.width(), 0);
  Y = map(p.y, TS_MAXY, TS_MINY, tft.height(), 0);
  Z = p.z;
}

void draw_btn1(bool on)
{

  if (on)
  {
    tft.fillRoundRect(40, 20, 160, 120, 15, BLUE); // Dibujamos un "boton"
    tft.setCursor(100, 70);                        // Colocamos el cursor
    tft.setTextSize(4);                            // Especificamos el tamaño del texto
    tft.setTextColor(WHITE);                       // Definimos el color del texto
    tft.println("ON");                             // Escribimos por pantalla
  }
  else
  {
    tft.fillRoundRect(40, 20, 160, 120, 15, RED); // Dibujamos un "boton"
    tft.setCursor(90, 70);                       // Colocamos el cursor
    tft.setTextSize(4);                           // Especificamos el tamaño del texto
    tft.setTextColor(WHITE);                      // Definimos el color del texto ft
    tft.println("OFF");                           // Escribimos por pantalla
  }
}

void draw_btn2(bool on)
{

  if (on)
  {
    tft.fillRoundRect(40, 180, 160, 120, 15, CYAN); // Dibujamos un "boton"
    tft.setCursor(100, 230);                        // Colocamos el cursor
    tft.setTextSize(4);                             // Especificamos el tamaño del texto
    tft.setTextColor(WHITE);                        // Definimos el color del texto
    tft.println("ON");                              // Escribimos por pantalla
  }
  else
  {
    tft.fillRoundRect(40, 180, 160, 120, 15, RED); // Dibujamos un "boton"
    tft.setCursor(90, 230);                       // Colocamos el cursor
    tft.setTextSize(4);                            // Especificamos el tamaño del texto
    tft.setTextColor(WHITE);                       // Definimos el color del texto ft
    tft.println("OFF");                            // Escribimos por pantalla
  }
}

int get_btn()
{
  int result = 0;
  if ((X > 40 && X < 200) && (Y > 20 && Y < 140) && (Z > MINPRESSURE && Z < MAXPRESSURE))
  {
    result = 1;
  }
  else if ((X > 40 && X < 200) && (Y > 180 && Y < 300) && (Z > MINPRESSURE && Z < MAXPRESSURE))
  {
    result = 2;
  }
  return result;
}