//
//
#include "CustomHandlers.h"
#include "WiFiStateHandler.h"

// General Purpose helper stuff

// Handlers

void HandleNotFound() {
  bool found = false;
  const DirEntry *de = Directory;
  Serial.printf("No Custom Handler for '%s'\n", server.uri().c_str()+1);
  while (de->Filename) {
    Serial.printf("test for '%s' with '%s'\n", de->Filename, server.uri().c_str()+1);
#if 0
    if (0 == strcmp(server.uri().c_str()+1, de->Filename)) {
      Serial.printf("send '%s' (%i B) as '%s'\n", de->Filename, de->Filesize, de->Filetype);
      server.send_P(200, de->Filetype, (const char *)de->Filedata, de->Filesize);
      found = true;
      break;
    }
#endif
    de++;
  }
  if (!found) {
    Serial.printf("!found '%s' - redirect to home\n", server.uri().c_str());
    server.sendHeader("Location", "/", true);
    server.send(302, "text/plain", "Not supported. Heading for home.");
  }
}

void HandleMyIP_js() {
  server.sendHeader("Access-Control-Allow-Origin", String("*"), true);
  String message = "var mySite = 'http://";
  message += String(WiFi.localIP()[0]);
  message += "." + String(WiFi.localIP()[1]);
  message += "." + String(WiFi.localIP()[2]);
  message += "." + String(WiFi.localIP()[3]);
  message += "';\n";
  server.send(200, "text/javascript", message);
}


void HandleRootPage() {
  if (server.hasArg("SW")) {
    String newState = server.arg("SW");
    if (newState == "1") {
      // @todo SetCircuit(CMD_On);
      Serial.printf("SW 1\n");
    } else if (newState == "0") {
      // @todo SetCircuit(CMD_Off);
      Serial.printf("SW 0\n");
    } else if (newState == "2") {
      // @todo SetCircuit(CMD_Toggle);
      Serial.printf("SW 2\n");
    } else {
      Serial.printf("SW %s ???\n", newState.c_str());
      ; // no action
    }
  }
  // @todo String modeText = (isStationMode) ? "Station mode<br/>" : "Access Point mode<br/>";
  // @todo String status = GetCircuitStatus() ? "On<br/>" : "Off<br/>";
  String myIP = String(WiFi.localIP()[0]);
  myIP += "." + String(WiFi.localIP()[1]);
  myIP += "." + String(WiFi.localIP()[2]);
  myIP += "." + String(WiFi.localIP()[3]);
  server.send_P(200, "text/html", (const char *)index_htm);
}

static String EncType_str(uint8_t encType) {
  switch (encType) {
    case ENC_TYPE_NONE:
      return "open";
      break;
    case ENC_TYPE_WEP:
      return "wep";
      break;
    case ENC_TYPE_TKIP:
      return "wpa psk";
      break;
    case ENC_TYPE_CCMP:
      return "wpa2 psk";
      break;
    case ENC_TYPE_AUTO:
      return "wpa wpa2 psk";
      break;
    default:
      return "unknown";
      break;
  }
}

void HandleAPScan() {
  // WiFi.scanNetworks will return the number of networks found
  Serial.println("Scan ...");
  int n = WiFi.scanNetworks(false, true);   // blocking call and show hidden.
  Serial.println("scan done.");
  if (n == 0) {
    Serial.println("no networks found");
  } else {
    Serial.print(n);
    Serial.println(" networks found");
    server.sendContent_P("HTTP/1.1 200 OK\r\n");
    server.sendContent_P("Content-Type: text/html\r\n");
    server.sendContent_P("\r\n");
    server.sendContent_P(
      "<!DOCTYPE html>\n"
      "<html>\n"
      "<head><title>Grow Controller - Scan</title></head>\n"
      "<body>\n"
      "<h1>Grow Controller - Scan</h1>"
    );

    server.sendContent_P(
      " <form action=\"/config\">\n"
      " <blockquote>\n"
      "   <table width='800' border='0'>\n"
      "     <tr bgcolor='#E0E0E0'><td colspan='2'>Net</td><td>RSSI</td><td>SSID</td><td>BSSID</td><td>Encryption</td><td>Channel</td><td>Hidden</td></tr>\n"
    );

    for (int i = 0; i < n; ++i) {
      // Select, Network #, RSSI, SSID, BSSID, Channel, Hidden
      String bgcolor = (i & 1) ? "#E0E0E0" : "#FFFFFF";
      String record =
        "     <tr bgcolor='" + bgcolor + "'><td><input type='radio' name='ssid' value='" + WiFi.SSID(i) + "'></td>\n"
        + "       <td>" + (i + 1) + "</td>\n"
        + "       <td>" + WiFi.RSSI(i) + "</td>\n"
        + "       <td>" + WiFi.SSID(i) + "<br/>"
        + "         <img src='/green1x1.png' width='" + String(5 * (100 + WiFi.RSSI(i))) + "' height='3'></td>\n"
        + "       <td>" + WiFi.BSSIDstr(i) + "</td>\n";

      record += "             <td>" + EncType_str(WiFi.encryptionType(i)) + "</td>\n";
      record += "       <td>" + String(WiFi.channel(i));
      record += "</td>\n";
      record += WiFi.isHidden(i) 
        ? "       <td>Yes</td>\n" 
        : "       <td>No</td>\n";
      record += "     </tr>\n";
      server.sendContent(record);
      //
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE) ? " " : "*");
    }
    server.sendContent_P(
      "     <tr><td>&nbsp;</td>\n"
      "       <td colspan='7'>\n"
      "         <input type=\"submit\" value=\"Select\" />\n"
      "         <input type=\"reset\"/>\n"
      "       </td>\n"
      "     </tr>\n"
      "   </table>\n"
      " </blockquote>\n"
      " </form>\n"
      "NAV:&nbsp;&nbsp;"
      " <a href='/'>Home</a> | "
      " <a href='/config'>Config</a> | "
      " <a href='/scan'>Scan</a> | "
      "   <a href='/rssi'>RSSI</a> | "
      "   <a href='/curr'>Current</a> | "
      " <a href='/config?ssid=reset&pass=reset' onclick=\"return confirm('Are you sure?')\">Factory Reset</a> | "
      " <a href='/about'>About</a>\n"
      " <br/>\n"
      "</body>\n"
      "</html>\n"
    );
  }
}

void HandleAPConfigPage() {
  String name = wifiConfig.getName();
  String ssid = wifiConfig.getSSID();
  String pass = wifiConfig.getPassword();
  String url = wifiConfig.getURL();
  String ntp = wifiConfig.getNTPServerName();

  // Handle submissions from the client
  if (server.hasArg("ssid") && server.hasArg("pass")) {
    String _ssid = server.hasArg("_ssid") ? server.arg("_ssid") : "";
    String _pass = server.hasArg("_pass") ? server.arg("_pass") : "";
    name = server.arg("name");
    ssid = server.arg("ssid");
    pass = server.arg("pass");
    url = server.hasArg("url") ? server.arg("url") : "";
    ntp = server.hasArg("ntp") ? server.arg("ntp") : "";
    if (ssid == "reset" && pass == "reset") {
      FactoryReset(true);
    }
    wifiConfig.setName(name);
    wifiConfig.setSSID(ssid);
    wifiConfig.setPassword(pass);
    wifiConfig.setURL(url);
    wifiConfig.setNTPServerName(ntp);
    wifiConfig.save();
    Serial.println("Settings saved.");
    if (ssid != _ssid || pass != _pass) {
      // They changed stuff that requires a restart.
      server.send(200, "text/html", "Configuration Saved! Restarting in 3 sec...");
      Serial.printf("Config saved. Restarting in 3 sec . . .");
      delay(3000);
      ESP.restart();
      return;
    }
  } 

  // Send [updated] Configuration page to client
  //
  String modeText = (WiFiStateGet() == WFC_JoinedAP) ? "Station mode<br/>" : "Access Point mode<br/>";
  if (server.hasArg("ssid") && !server.hasArg("pass")) {
    ssid = server.arg("ssid");
    pass = "";
    Serial.println("ssid: " + ssid + ", pass: " + pass);
  } else {
	Serial.printf("name : %s\n", name.c_str());
	Serial.printf(" ssid: %s\n", ssid.c_str());
	Serial.printf(" pass: %s\n", pass.c_str());
  }
  if (server.hasArg("url"))
    url = server.arg("url");
  //if (server.hasArg("ntp"))
  //  ntp = server.arg("ntp");
  server.send(200, "text/html",
    "<!DOCTYPE html>\n"
    "<html>\n"
    "<head><title>Grow Controller - Config</title>\n"
	"<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>\n"
	"<meta name='viewport' content='initial-scale=1.0, width=device-width'>\n"
	"</head>\n"
    "<body onload='NavInit();'>\n"
    "<h1>Grow Controller - Configuration</h1>"
    " <form action=\"\">\n"
    " <blockquote>\n"
    "   <table border='0'>\n"
    "     <tr>\n"
    "       <td>Node Name</td>\n"
    "       <td><input type='text' size='32' maxlength='32' name='name' value='" + name + "' /></td>\n"
    "     </tr>\n"
    "     <tr>\n"
    "       <td>SSID</td>\n"
    "       <td><input type='text' size='32' maxlength='32' name='ssid' value='" + ssid  + "' />&nbsp;**\n"
    "                   <input type='hidden' name='_ssid' value='" + ssid + "' /></td>\n"
    "     </tr>\n"
    "     <tr nowrap='nowrap'>\n"
    "       <td>Password</td>\n"
    "       <td nowrap='nowrap'><input type='password' size='32' maxlength='64' name='pass' value='" + pass + "' />&nbsp;**\n"
    "                   <input type='hidden' name='_pass' value='" + pass + "' /></td>\n"
    "     </tr>\n"
    "     <tr>\n"
    "       <td>Update URL</td>\n"
    "       <td><input type='text' size='32' maxlength='64' name='url' value='" + url + "' /></td>\n"
    "     </tr>\n"
    "     <tr>\n"
    "       <td>NTP Server</td>\n"
    "       <td><input type=\"text\" size=\"64\" name=\"ntp\" value=\"" + ntp + "\" /></td>\n"
    "     </tr>\n"
    "     <tr>\n"
    "       <td>&nbsp;</td>\n"
    "       <td>\n"
    "         <input type='submit' value='Save' />\n"
    "         <input type='reset'/> ** Changes to these will trigger a module restart.\n"
    "       </td>\n"
    "     </tr>\n"
    "     <tr>\n"
    "       <td colspan='2'><hr/></td>\n"
    "     </tr>\n"
    "     <tr>\n"
    "       <td>&nbsp;</td>\n"
    "       <td><a href='/swupdatecheck'>Check for SW update (module will restart if updated)</a></td/>\n"
    "     </tr>\n"
    "   </table>\n"
    " </blockquote>\n"
    " </form>\n"
	"<span id='nav'></span>\n"
    "</body>\n"
    "</html>\n"
  );
}


// ###################################################################
//
//  Old handlers, for 'static' information that needs to be send to 
//  build a web page.
//
//  This is to be obsoleted by the new method at the top of this file.
//
// ###################################################################


void HandlePlantModel() {
  Serial.printf("PlantModel\n");
  server.send_P(200, "image/png", plantmodel_png, sizeof(plantmodel_png));
}
void HandlePlantModel_css() {
  server.sendHeader("Access-Control-Allow-Origin", String("*"), true);
  server.send_P(200, "text/css", plantmodel_css);
}
void HandleButton_css() {
  server.sendHeader("Access-Control-Allow-Origin", String("*"), true);
  server.send_P(200, "text/css", button_css);
}
void HandleIndex_js() {
  server.sendHeader("Access-Control-Allow-Origin", String("*"), true);
  server.send_P(200, "text/javascript", index_js);
}
void HandleAbout_htm() {
  server.sendHeader("Access-Control-Allow-Origin", String("*"), true);
  server.send_P(200, "text/html", about_htm);
}
void HandleAbout_js() {
  server.sendHeader("Access-Control-Allow-Origin", String("*"), true);
  server.send_P(200, "text/javascript", about_js);
}
void HandleFavIcon() {
  Serial.printf("favicon.ico\n");
  server.send_P(200, "image/x-icon", favicon_ico, sizeof(favicon_ico));
}
void HandleIcon() {
  Serial.printf("icon.png\n");
  server.send_P(200, "image/png", icon_png, sizeof(icon_png));
}
void HandleOpenDoor() {
  Serial.printf("open.png\n");
  server.send_P(200, "image/png", open_png, sizeof(open_png));
}
void HandleGreen1x1() {
  Serial.printf("green1x1.png\n");
  server.send_P(200, "image/png", green1x1_png, sizeof(green1x1_png));
}
void HandleHeaterOn() {
  Serial.printf("soilheater_on.png\n");
  server.send_P(200, "image/png", soilheater_on_png, sizeof(soilheater_on_png));
}
void HandleHeaterOff() {
  Serial.printf("soilheater_off.png\n");
  server.send_P(200, "image/png", soilheater_off_png, sizeof(soilheater_off_png));
}
void HandleThermometer() {
  Serial.printf("thermometer.png\n");
  server.send_P(200, "image/png", thermometer_png, sizeof(thermometer_png));
}
void HandleSoilMoisture() {
  Serial.printf("soilmoisture.png\n");
  server.send_P(200, "image/png", soilmoisture_png, sizeof(soilmoisture_png));
}
void HandlePointer() {
  Serial.printf("pointer.png\n");
  server.send_P(200, "image/png", pointer_png, sizeof(pointer_png));
}
void HandleWater() {
  Serial.printf("water.png\n");
  server.send_P(200, "image/png", water_png, sizeof(water_png));
}
void HandleRSSIPage() {
  server.send_P(200, "text/html", rssi_htm);
}
void HandleRSSI_js() {
  server.send_P(200, "text/javascript", rssi_js);
}
void HandleCurrPage() {
  server.send_P(200, "text/html", curr_htm);
}
void HandleCurr_js() {
  server.send_P(200, "text/javascript", curr_js);
}
void HandleNav_js() {
  server.send_P(200, "text/javascript", nav_js);
}
void HandleSWUpdateCheck() {
  updateCheck = true;
  HandleAPConfigPage();
}

#if 0
void HandleCircuitOn() {
  //SetCircuit(CMD_On);
  HandleGetState(); // Reply with current state
}
void HandleCircuitOff() {
  //SetCircuit(CMD_Off);
  HandleGetState(); // Reply with current state
}
void HandleCircuitToggle() {
  //SetCircuit(CMD_Toggle);
  HandleGetState(); // Reply with current state
}
#endif
