/// ESP32_38pin-Serial Monitor with ILI9341 2.8 inch Display ///
#include <Adafruit_GFX.h>       // Version 1.5.3
#include <Adafruit_ILI9341.h>   // Version 1.5.6
#include <SPI.h>                // Version 2.1
#include <WiFi.h>

// ******************************************** //
// Pin configuration for the ILI9341 display/2.8inch
const int TFT_CS    = 5;    // Pin-29 ESP32 "VSPISS" (GPIO 05)
const int TFT_RST   = -1;   // It is not used, connected to +Vcc (1K/5V) or directly 3V3
const int TFT_DC    = 21;   // PIN-33 ESP32 "I2CSDA" (GPIO 21)
const int TFT_MOSI  = 23;   // MOSI---> ESP32 pin 37 "VSPIMOSI" (GPIO 23)
const int TFT_SCK   = 18;   // SCLK---> ESP32 pin 30 "VSPISCK"  (GPIO 18)

// Initialize the Display
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
#define ILI9341_GREY 0x5AEB

// ******************************************** //
// Replace with your network credentials
const char* ssidAP = "Led_Manager";
const char* passwordAP = "12345678";

// Define pin OUT
const int output15 = 15;    // ADC13:GPIO15_Pin-23, OUT LED-1
const int output2 = 2;      // ADC12:GPIO2_Pin-24, OUT LED-2

// Variable to store the HTTP request
String currentLine = "";    // Declare the currentLine variable
String header = "";         // This is where we store the entire HTTP request

// Auxiliar variables to store the current output state
String output15State = "OFF";
String output2State = "OFF";

// Set web server port number to 80
WiFiServer server(80);

///******************************************************************///
void setup()
{
  Serial.begin(115200);
  
	tft.begin();
	tft.setRotation(1);
	tft.fillScreen(ILI9341_GREY);

	// Adding a background color that automatically erases the previous text
	tft.setTextColor(ILI9341_WHITE, ILI9341_GREY);
	tft.setTextSize(3);

	// Configurarea variabile IN/OUT
	pinMode(output15, OUTPUT);          // ADC13:GPIO15_Pin-23, OUT LED-1
	pinMode(output2, OUTPUT);           // ADC12:GPIO2_Pin-24, OUT LED-2

	// Set outputs to LOW
	digitalWrite(output15, LOW);
	digitalWrite(output2, LOW);

	tft.setCursor(20, 20);    // Cursor coordinates: Horizontal, Vertical
	tft.println("ESP32 WiFi AP WS");
	tft.setCursor(55, 60);
	tft.setTextSize(2);
	tft.setTextColor(ILI9341_RED, ILI9341_GREY);

	tft.println("Connect to WiFi...");
	WiFi.softAP(ssidAP, passwordAP);
/*
	// Waiting for AP to connect (one second)
	while (WiFi.softAPgetStationNum() == 0)
	{
	  delay(1000);  // Wait 1 second
	  tft.print(".");
	}
*/
	// Use "fillRect" to clear the display
	// tft.fillRect(xStart, yStart, tft.width(), yEnd - yStart, background_color);
	tft.fillRect(0, 80, 320, 160, ILI9341_GREY);

	// Get the IP address of the AP
	IPAddress IP = WiFi.softAPIP();

	server.begin();           // Start the HTTP server
	tft.setCursor(20, 85);
	tft.setTextColor(ILI9341_GREEN, ILI9341_GREY);
	tft.print("AP_IPaddress:");
	tft.println(IP);
	tft.setCursor(40, 110);
	tft.println("WiFi Connected");
	tft.setCursor(105, 165);
	tft.println("GPIO 15 OFF");
	tft.setCursor(105, 185);
	tft.println("GPIO  2 OFF");
	tft.setCursor(20, 210);
	tft.println("Client Disconnected.");
}

///******************************************************************///
void loop()
{
	// Check if there is a Client Connection
	tft.setCursor(20, 140);
	tft.println("Missing Connection    ");
	///delay(500);

	WiFiClient client = server.available();
	if (client)
	{
		tft.setCursor(20, 140);
		tft.println("Connection Established");
		///delay(500);

		// Read the HTTP request byte by byte to its end
		while (client.connected())    // Loop "while" the client's connected
		{
			tft.setCursor(20, 210);
			tft.println("Client Connected!   ");
			if (client.available())     // If there's bytes to read from the client,
			{
				header += client.readString();
				if (header.endsWith("\r\n\r\n"))
				{

					// If you have reached the end of the HTTP request (after two newline characters),
					// can process the request and exit the loop
					if (currentLine.length() == 0)
					{
						// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
						// and a content-type so the client knows what's coming, then a blank line:
						client.println("HTTP/1.1 200 OK");
						client.println("Content-type:text/html");
						client.println("Connection: close");
						client.println();

						// Turns the GPIOs ON and OFF
						if (header.indexOf("GET /15/ON") >= 0)
						{
							tft.setCursor(105, 165);
							tft.println("GPIO 15  ON");
							
							///Serial.println("GPIO 15 ON");
							output15State = "ON";
							digitalWrite(output15, HIGH);
						}
						else
						if (header.indexOf("GET /15/OFF") >= 0)
						{
							tft.setCursor(105, 165);
							tft.println("GPIO 15 OFF");
							///Serial.println("GPIO 15 OFF");
							output15State = "OFF";
							digitalWrite(output15, LOW);
						}
						else
						
						if (header.indexOf("GET /2/ON") >= 0)
						{
							tft.setCursor(105, 185);
							tft.println("GPIO  2  ON");
							///Serial.println("GPIO  2 ON");
							output2State = "ON";
							digitalWrite(output2, HIGH);
						}
						else

						if (header.indexOf("GET /2/OFF") >= 0)
						{
							tft.setCursor(105, 185);
							tft.println("GPIO  2 OFF");
							///Serial.println("GPIO  2 OFF");
							output2State = "OFF";
							digitalWrite(output2, LOW);
						}

						// Display the HTML web page & CSS to style the ON/OFF buttons
						client.println("<!DOCTYPE html><html><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">");
						///client.println("<link rel=\"icon\" href=\"data:,\">");
						client.println("<style>html{font-family:Helvetica;display:inline-block;margin:0 auto;text-align:center;}");
						client.println(".button{background-color:GREEN;border:none;color:white;padding:16px 40px;text-decoration:none;font-size:30px;margin:2px;cursor:pointer;}");
						client.println(".button2{background-color:RED;}</style></head><body><h1>ESP32 WiFi AP WebServer</h1>");

						// Display current state, and ON/OFF buttons for GPIO 15 
						client.println("<p>GPIO 15 - State " + output15State + "</p>");

						// If the output15State is OFF, it displays the ON button      
						if (output15State=="OFF")
						{client.println("<p><a href=\"/15/ON\"><button class=\"button\">ON</button></a></p>");}
						else
						{client.println("<p><a href=\"/15/OFF\"><button class=\"button button2\">OFF</button></a></p>");}

						// Display current state, and ON/OFF buttons for GPIO 2 
						client.println("<p>GPIO 2 - State " + output2State + "</p>");

						// If the output2State is OFF, it displays the ON button      
						if (output2State=="OFF")
						{client.println("<p><a href=\"/2/ON\"><button class=\"button\">ON</button></a></p>");}

						else
						{client.println("<p><a href=\"/2/OFF\"><button class=\"button button2\">OFF</button></a></p>");}
						client.println("</body></html>");

						// The HTTP response ends with another blank line
						client.println();

						// Break out of the while loop
						break;
					}

					else  // If you got a newline, then clear currentLine
					{currentLine = "";}

				}

			}

		}

		// Clear the header variable
		header = "";

		// Close the connection
		client.stop();
		tft.setCursor(20, 210);
		tft.println("Client Disconnected!");
		///Serial.println("Client Disconnected!");
		///Serial.println("");
		///delay(500);
	}
}
///******************************************************************///

/// END PROGRAM ///