//extern ESP8266WebServer httpServer;

static const char httpRoot[] PROGMEM =
  R"(<html><body>
  <h1><span id='devname'></span></h1>
  <h3>WiFi Switch</h3>  
  <form id='BtnFrm1'><input type='hidden' name='Btn1' value='1'></form>
  <form id='BtnFrm2'><input type='hidden' name='Btn2' value='1'></form>
  <form id='BtnFrm3'><input type='hidden' name='Btn3' value='1'></form>
  <form id='AllOnFrm'><input type='hidden' name='allOn' value='1'></form>
  <form id='AllOffFrm'><input type='hidden' name='allOff' value='1'></form>
  <input type='button' value='All ON' id='allOn' onclick='return sendAllOn()'/><input type='button' value='All OFF' id='allOff' onclick='return sendAllOff()'/>
  <div style='font-size:xx-large'>
  <div id='sw1div' style='display:none'>1: <input type='button' id='tbtn1' onclick='return sendBtn(1)'/><br></div>
  <div id='sw2div' style='display:none'>2: <input type='button' id='tbtn2' onclick='return sendBtn(2)'/><br></div>
  <div id='sw3div' style='display:none'>3: <input type='button' id='tbtn3' onclick='return sendBtn(3)'/><br></div>
  </div>
  <br>  
  <br>
  WiFi connected to <i><span id='ssid'></span></i>.<br>
  <h6>Last update 
  <span id='ut'></span> seconds ago. 
  <span id='status'></span>
  </h6>
  <br>
  <a href='/wifi.htm'>WiFi settings</a><br>
  <a href='/confhw'>Hardware configuration</a><br>
  <a href='/conf'>Base configuration</a><br>
  <a href='/conf2'>Extended configuration</a><br>
  <a href='/update'>Firmware update</a><br>
  <a href='/restart'>Restart</a>
  <script>
  function g(i) { return document.getElementById(i) };
  var xhttp, updateTime, reqTime, reqFin;
  var textA = 'OFF';
  var textE = 'ON';
  
  function sendBtn(btn) {
  var frmn='BtnFrm'+btn;
  var form = g(frmn);
  return transmit(form);
  }
  
  function sendAllOn() {
  return transmit(g('AllOnFrm'));
  }
  function sendAllOff() {
  return transmit(g('AllOffFrm'));
  }
  
  function transmit(f) {
    if (!xhttp) { 
      g('status').innerHTML = 'loading...';
      reqTime = 0;
      reqFin = false;
      xhttp = new XMLHttpRequest();
      xhttp.timeout = 2000;
      xhttp.open('POST', 'api');
      xhttp.send(f ? (new FormData(f)) : '');
      xhttp.onreadystatechange = function () {
        if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
          var data = JSON.parse(xhttp.responseText);
          g('ssid').innerHTML = data.ssid;
          if(data.devname != undefined) g('devname').innerHTML = data.devname;
          if(data.swState1 != undefined) g('sw1div').style.display='inline';
          else g('sw1div').style.display='none';
     if(data.swState2 != undefined) g('sw2div').style.display='inline';
          else g('sw2div').style.display='none';
          if(data.swState3 != undefined) g('sw3div').style.display='inline';
          else g('sw3div').style.display='none';
          if(data.swState1 == '1') g('tbtn1').value = textE;
          else g('tbtn1').value = textA;
          if(data.swState2 == '1') g('tbtn2').value = textE;
          else g('tbtn2').value = textA;
          if(data.swState3 == '1') g('tbtn3').value = textE;
          else g('tbtn3').value = textA;
          xhttp = null;
          updateTime = 0;
          reqFin = true;
          }
        else {
          if(!reqFin && reqTime > 10) {
            xhttp = null;
            reqFin = true;
          }
        }
      }
    }
    return false;
  }
  transmit();
  setInterval(function () { g('ut').innerHTML = ++updateTime; ++reqTime; }, 1000);
  setInterval(transmit, 5000);
</script>
</body></html>)";


static const char httpConfPage[] PROGMEM =
  R"(<html><head><body>
<h3>Base configuration</h3>
<a href='/'>Home</a><br><br>
<input type='button' value='reload' onclick='return transmit()'/><br><br>
<form id='form1' onsubmit='return transmit(this)'>
Device Name: <input type='text' name='devName' id='devName'/><br><br>
HTTP User *: <input type='text' name='httpUser' id='httpUser'/><br>
HTTP Password *: <input type='text' name='httpPass' id='httpPass'/><br><br>
MQTT Server *: <input type='text' name='mqttHost' id='mqttHost'/><br>
MQTT Port *: <input type='number' name='mqttPort' id='mqttPort'/><br>
MQTT User *: <input type='text' name='mqttUser' id='mqttUser'/><br>
MQTT Password *: <input type='text' name='mqttPass' id='mqttPass'/><br><br>
In Topic *: <input type='text' name='inTop' id='inTop'/><br>
Out Topic: <input type='text' name='outTop' id='outTop'/><br>
Out Retain *: <input type='checkbox' name='outRet' id='outRet'/><br><br>
LastWill Topic *: <input type='text' name='willTop' id='willTop'/><br>
LastWill Qos *: <select name='willQos' id='willQos'><option>0</option><option>1</option><option>2</option></select><br>
LastWill Retain *: <input type='checkbox' name='willRet' id='willRet'/><br>
LastWill Message *: <input type='text' name='willMsg' id='willMsg'/><br><br>
Domoticz Out Topic *: <input type='text' name='domOutTop' id='domOutTop'/><br><br>
All ON/OFF Topic *: <input type='text' name='allOnOffTop' id='allOnOffTop'/><br>
<br>
<input type='submit' value='Save'/>
</form>
<form id='restartForm' onsubmit='return res()'>
<input type='hidden' name='restart' value='1'>
<input type='submit' value='Restart'/>
</form>

<script>
 function g(i) { return document.getElementById(i) };
  var xhttp, reqTime, reqFin, rxhttp;
  
  function res() {
    rxhttp = new XMLHttpRequest();
 rxhttp.timeout = 1000;
  rxhttp.open('POST', 'restart');
  rxhttp.send('');
  rxhttp = null;
  return false;
  }
  function setCheckbox(ele, dat) {
    if(dat == 1) {
      ele.checked = true;
      ele.style.visibility = 'visible';
    }
    else {
      ele.checked = false;
      ele.style.visibility = 'visible';
    }
  }
  function updateCheckboxValue(ele) {
    if (ele.checked) ele.value ='1';
    else {
      ele.value = '0';
      ele.checked = true;
      ele.style.visibility = 'hidden';
    }
  }
  
  function transmit(f) {
    if (!xhttp) {   
    reqTime = 0;
    reqFin = false;
    updateCheckboxValue(g('outRet'));
    updateCheckboxValue(g('willRet'));    
    xhttp = new XMLHttpRequest();
    xhttp.timeout = 2000;
    xhttp.open('POST', 'confdata');
    xhttp.send(f ? (new FormData(f)) : '');
    xhttp.onreadystatechange = function () {
      if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
        var data = JSON.parse(xhttp.responseText);
        g('httpUser').value = data.httpUser;
        g('httpPass').value = data.httpPass;
        g('devName').value = data.devName
        g('mqttHost').value = data.mqttHost;
        g('mqttPort').value = data.mqttPort;
        g('mqttUser').value = data.mqttUser;
        g('mqttPass').value = data.mqttPass;
        g('inTop').value = data.inTop;
        g('outTop').value = data.outTop;
        g('willTop').value = data.willTop;
        g('willQos').value = data.willQos;
        setCheckbox(g('outRet'), data.outRet);
        setCheckbox(g('willRet'), data.willRet);
        g('willMsg').value = data.willMsg;
        g('domOutTop').value = data.domOutTop;
        g('allOnOffTop').value = data.allOnOffTop;
        xhttp = null;
        reqFin = true;
       }
       else {
         if(!reqFin && reqTime > 10) {
           xhttp = null;
           reqFin = true;
         }
       }
     }
   }
    return false;
  }
  transmit();
  setInterval(function () { ++reqTime; }, 1000);
</script>
</body></html>)"; //httpConfPage

static const char httpConf2Page[] PROGMEM =
  R"(<html><head><body>
<h3>Extended configuration</h3>
<a href='/'>Home</a><br><br>
<input type='button' value='reload' onclick='return transmit()'/><br>
<form id='form1' onsubmit='return transmit(this)'>

<h4>Domoticz</h4>
Domoticz Idx 1: <input type='number' name='domIdx1' id='domIdx1'/><br>
Domoticz Idx 2: <input type='number' name='domIdx2' id='domIdx2'/><br>
Domoticz Idx 3: <input type='number' name='domIdx3' id='domIdx3'/><br>

<h4>Button MQTT-Out</h4>
Retain *: <input type='checkbox' name='btnRet' id='btnRet'/><br><br>
1:<br>
Topic: <input type='text' name='top1' id='top1'/> Payload: <input type='text' name='pld1' id='pld1'/><br>
Hold:<br>
Control relais: <select name='hld1ToRel' id='hld1ToRel'><option value='0'>-</option><option>1</option><option>2</option><option>3</option></select><br>
Topic: <input type='text' name='topHld1' id='topHld1'/> Payload: <input type='text' name='pldHld1' id='pldHld1'/><br><br>
2:<br>
Topic: <input type='text' name='top2' id='top2'/> Payload: <input type='text' name='pld2' id='pld2'/><br>
Hold:<br>
Control relais: <select name='hld2ToRel' id='hld2ToRel'><option value='0'>-</option><option>1</option><option>2</option><option>3</option></select><br>
Topic: <input type='text' name='topHld2' id='topHld2'/> Payload: <input type='text' name='pldHld2' id='pldHld2'/><br><br>
3:<br>
Topic: <input type='text' name='top3' id='top3'/> Payload: <input type='text' name='pld3' id='pld3'/><br>
Hold:<br>
Control relais: <select name='hld3ToRel' id='hld3ToRel'><option value='0'>-</option><option>1</option><option>2</option><option>3</option></select><br>
Topic: <input type='text' name='topHld3' id='topHld3'/> Payload: <input type='text' name='pldHld3' id='pldHld3'/><br>

<br>
<input type='submit' value='Save'/>
</form>
<form id='rebootForm' onsubmit='return res()'>
<input type='submit' value='Restart'/>
</form>

<script>
 function g(i) { return document.getElementById(i) };
  var xhttp, reqTime, reqFin, rxhttp;
  
  function res() {
    rxhttp = new XMLHttpRequest();
 rxhttp.timeout = 1000;
  rxhttp.open('POST', 'restart');
  rxhttp.send('');
  rxhttp = null;
  return false;
  }
  function setCheckbox(ele, dat) {
    if(dat == 1) {
      ele.checked = true;
      ele.style.visibility = 'visible';
    }
    else {
      ele.checked = false;
      ele.style.visibility = 'visible';
    }
  }
  function updateCheckboxValue(ele) {
    if (ele.checked) ele.value ='1';
    else {
      ele.value = '0';
      ele.checked = true;
      ele.style.visibility = 'hidden';
    }
  }

  function transmit(f) {
    if (!xhttp) {
      updateCheckboxValue(g('btnRet'));
      xhttp = new XMLHttpRequest();
      xhttp.timeout = 2000;
      xhttp.open('POST', 'confdata2');
      xhttp.send(f ? (new FormData(f)) : '');
      xhttp.onreadystatechange = function () {
        if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
          var data = JSON.parse(xhttp.responseText);
          setCheckbox(g('btnRet'), data.btnRet);
          g('top1').value = data.top1;
          g('top2').value = data.top2;
          g('top3').value = data.top3;
          g('topHld1').value = data.topHld1;
          g('topHld2').value = data.topHld2;
          g('topHld3').value = data.topHld3;
          g('pld1').value = data.pld1;
          g('pld2').value = data.pld2;
          g('pld3').value = data.pld3;
          g('pldHld1').value = data.pldHld1;
          g('pldHld2').value = data.pldHld2;
          g('pldHld3').value = data.pldHld3;
     g('hld1ToRel').value = data.hld1ToRel;
      g('hld2ToRel').value = data.hld2ToRel;
      g('hld3ToRel').value = data.hld3ToRel;
          g('domIdx1').value = data.domIdx1;
          g('domIdx2').value = data.domIdx2;
          g('domIdx3').value = data.domIdx3;
      
          xhttp = null;
          reqFin = false;
        }
      else {
          if(!reqFin && reqTime > 10) {
            xhttp = null;
            reqFin = true;
          }
       }
    }
    }
    return false;
  }
  transmit();
  setInterval(function () { ++reqTime; }, 1000);
</script>
</body></html>)"; //httpConf2Page

static const char httpConfHwPage[] PROGMEM =
  R"(<html><head><body>
<h3>Hardware configuration</h3>
<a href='/'>Home</a><br><br>
<input type='button' value='reload' onclick='return transmit()'/><br>
<form id='form1' onsubmit='return transmit(this)'>
<br>
Avoid duplicate GPIO assignments!<br>
GPIO 0 and 2 have fixed 10k pullup and must remain high during boot (otherwise flash mode is entered).<br>
GPIO 2 is also connected to builtin LED (active LOW) on most ESP boards, so don't care or strip it.<br>
GPIO 15 has 10k pull-down, so could only be used as active-high in/output.<br>
Some GPIOs go high for some time at boot, so using only active-low logic is advisable, particularly for switching outputs<br>
Invert = active HIGH, default LOW<br>
Impulses are 0 by default (on until off), otherwise will auto-turn-off after specified time in factors of 100ms.<br>

<h4>Relais</h4>
1 - Enable: <input type='checkbox' name='enaRel1' id='enaRel1'/><br>
GPIO: <select name='ioRel1' id='ioRel1'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
Impulse: <input type='number' name='puls1' id='puls1'/><br>
invert: <input type='checkbox' name='invRel1' id='invRel1'/><br><br>
2 - Enable: <input type='checkbox' name='enaRel2' id='enaRel2'/><br>
GPIO: <select name='ioRel2' id='ioRel2'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
Impulse: <input type='number' name='puls2' id='puls2'/><br>
invert: <input type='checkbox' name='invRel2' id='invRel2'/><br><br>
3 - Enable: <input type='checkbox' name='enaRel3' id='enaRel3'/><br>
GPIO: <select name='ioRel3' id='ioRel3'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
Impulse: <input type='number' name='puls3' id='puls3'/><br>
invert: <input type='checkbox' name='invRel3' id='invRel3'/><br>

<h4>Buttons</h4>
Debounce time: <input type='number' name='debtime' id='debtime'/> in ms. default: 120<br>
Hold time: <input type='number' name='hldtime' id='hldtime'/> in ms. default: 750<br><br>
1 - Enable: <input type='checkbox' name='enaBtn1' id='enaBtn1'/><br>
GPIO: <select name='ioBtn1' id='ioBtn1'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
invert: <input type='checkbox' name='invBtn1' id='invBtn1'/><br><br>
2 - Enable: <input type='checkbox' name='enaBtn2' id='enaBtn2'/><br>
GPIO: <select name='ioBtn2' id='ioBtn2'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
invert: <input type='checkbox' name='invBtn2' id='invBtn2'/><br><br>
3 - Enable: <input type='checkbox' name='enaBtn3' id='enaBtn3'/><br>
GPIO: <select name='ioBtn3' id='ioBtn3'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
invert: <input type='checkbox' name='invBtn3' id='invBtn3'/><br>

<h4>Status LEDs</h4>
1 - Enable: <input type='checkbox' name='enaLed1' id='enaLed1'/><br>
GPIO: <select name='ioLed1' id='ioLed1'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
invert: <input type='checkbox' name='invLed1' id='invLed1'/><br><br>
2 - Enable: <input type='checkbox' name='enaLed2' id='enaLed2'/><br>
GPIO: <select name='ioLed2' id='ioLed2'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
invert: <input type='checkbox' name='invLed2' id='invLed2'/><br><br>
3 - Enable: <input type='checkbox' name='enaLed3' id='enaLed3'/><br>
GPIO: <select name='ioLed3' id='ioLed3'><option>0</option><option>2</option><option>4</option><option>5</option><option>12</option><option>13</option><option>14</option><option>15</option></select><br>
invert: <input type='checkbox' name='invLed3' id='invLed3'/><br><br>

<br>
<input type='submit' value='Save'/>
</form>
<form id='rebootForm' onsubmit='return res()'>
<input type='submit' value='Restart'/>
</form>

<script>
 function g(i) { return document.getElementById(i) };
  var xhttp, reqTime, reqFin, rxhttp;
  
  function res() {
    rxhttp = new XMLHttpRequest();
 rxhttp.timeout = 1000;
  rxhttp.open('POST', 'restart');
  rxhttp.send('');
  rxhttp = null;
  return false;
  }
  
  function setCb(ele, dat) {
    if(dat == 1) {
      ele.checked = true;
      ele.style.visibility = 'visible';
    }
    else {
      ele.checked = false;
      ele.style.visibility = 'visible';
    }
  }
  
  function updCbVal(ele) {
    if (ele.checked) ele.value ='1';
    else {
      ele.value = '0';
      ele.checked = true;
      ele.style.visibility = 'hidden';
    }
  }
  

  function transmit(f) {
    if (!xhttp) {
   updCbVal(g('enaRel1'));
      updCbVal(g('enaRel2'));
      updCbVal(g('enaRel3'));
      updCbVal(g('enaBtn1'));
      updCbVal(g('enaBtn2'));
      updCbVal(g('enaBtn3'));
      updCbVal(g('invRel1'));
      updCbVal(g('invRel2'));
      updCbVal(g('invRel3'));
      updCbVal(g('invBtn1'));
      updCbVal(g('invBtn2'));
      updCbVal(g('invBtn3'));
   updCbVal(g('enaLed1'));
      updCbVal(g('enaLed2'));
      updCbVal(g('enaLed3'));
    updCbVal(g('invLed1'));
      updCbVal(g('invLed2'));
      updCbVal(g('invLed3'));
      xhttp = new XMLHttpRequest();
      xhttp.timeout = 2000;
      xhttp.open('POST', 'confdatahw');
      xhttp.send(f ? (new FormData(f)) : '');
      xhttp.onreadystatechange = function () {
        if (xhttp.readyState === XMLHttpRequest.DONE && xhttp.status === 200) {
          var data = JSON.parse(xhttp.responseText);
          g('debtime').value = data.debtime;
          g('hldtime').value = data.hldtime;
          g('ioRel1').value = data.ioRel1;
          g('ioRel2').value = data.ioRel2;
          g('ioRel3').value = data.ioRel3;
          g('puls1').value = data.puls1;
          g('puls2').value = data.puls2;
          g('puls3').value = data.puls3;
          g('ioBtn1').value = data.ioBtn1;
          g('ioBtn2').value = data.ioBtn2;
          g('ioBtn3').value = data.ioBtn3;
      g('ioLed1').value = data.ioLed1;
          g('ioLed2').value = data.ioLed2;
          g('ioLed3').value = data.ioLed3;
          setCb(g('enaRel1'), data.enaRel1);
          setCb(g('enaRel2'), data.enaRel2);
          setCb(g('enaRel3'), data.enaRel3);
          setCb(g('enaBtn1'), data.enaBtn1);
          setCb(g('enaBtn2'), data.enaBtn2);
          setCb(g('enaBtn3'), data.enaBtn3);
          setCb(g('invRel1'), data.invRel1);
          setCb(g('invRel2'), data.invRel2);
          setCb(g('invRel3'), data.invRel3);
          setCb(g('invBtn1'), data.invBtn1);
          setCb(g('invBtn2'), data.invBtn2);
          setCb(g('invBtn3'), data.invBtn3);
      setCb(g('enaLed1'), data.enaLed1);
          setCb(g('enaLed2'), data.enaLed2);
          setCb(g('enaLed3'), data.enaLed3);
      setCb(g('invLed1'), data.invLed1);
          setCb(g('invLed2'), data.invLed2);
          setCb(g('invLed3'), data.invLed3);
          xhttp = null;
      reqFin = false;
        }
      else {
          if(!reqFin && reqTime > 10) {
            xhttp = null;
            reqFin = true;
            }
      }
    }
    }
    return false;
  }
  transmit();
  setInterval(function () { ++reqTime; }, 1000);
</script>
</body></html>)"; //httpConfHwPage

void httpServerHandleRoot() {
  boolean sendData = false;
  if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
    if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
    sendData = true;
  }
  else sendData = true;
  if (sendData) {
    httpServer.send_P(200, "text/html", httpRoot);
  }
}

void httpServerHandleConfPage() {
  boolean sendData = false;
  if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
    if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
    sendData = true;
  }
  else sendData = true;
  if (sendData) {
    httpServer.send_P(200, "text/html", httpConfPage);
  }
}

void httpServerHandleConf2Page() {
  boolean sendData = false;
  if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
    if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
    sendData = true;
  }
  else sendData = true;
  if (sendData) {
    httpServer.send_P(200, "text/html", httpConf2Page);
  }
}

void httpServerHandleConfHwPage() {
  boolean sendData = false;
  if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
    if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
    sendData = true;
  }
  else sendData = true;
  if (sendData) {
    httpServer.send_P(200, "text/html", httpConfHwPage);
  }
}

//void httpServerHandleNotFound() {
//  String message = "File Not Found\n\n";
//  message += "URI: ";
//  message += httpServer.uri();
//  message += "\nMethod: ";
//  message += (httpServer.method() == HTTP_GET) ? "GET" : "POST";
//  message += "\nArguments: ";
//  message += httpServer.args();
//  message += "\n";
//  for (uint8_t i = 0; i < httpServer.args(); i++) {
//    message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n";
//  }
//  httpServer.send(404, "text/plain", message);
//}

void httpServerHandleNotFound() {
  //  if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
  //    if (!httpServer.authenticate(http_user, http_pass))
  //      return httpServer.requestAuthentication();
  httpServer.send(404, "text/plain", "");
  //}
}

void httpServerInit() {
  httpServer.on("/delconf", []() {
    Serial.println("httpServer.on /delconf");
    if (httpServer.hasArg("token")) {
      char buf[20];
      httpServer.arg("token").toCharArray(buf, 20);
      if (strcmp(buf, CLEARCONF_TOKEN) == 0) {
        //        httpServer.send(200, "text/plain", "Token OK - deleting config");
        deleteConfig();
      }
    } //if
    //    else {
    //      httpServer.send(200, "text/plain", "not allowed");
    //    }
  });
  httpServer.on("/api", []() {
    boolean sendData = false;
    if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
      if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
      sendData = true;
    }
    else sendData = true;
    if (sendData) {
      //Serial.println("httpServer.on /api");
      if (httpServer.hasArg("Btn1")) {
        lastSwitchSource[0] = 2;
        relaisToggle(0);
        Serial.println("web Btn1");
      } //if
      if (httpServer.hasArg("Btn2")) {
        lastSwitchSource[1] = 2;
        relaisToggle(1);
        Serial.println("web Btn2");
      } //if
      yield();
      if (httpServer.hasArg("Btn3")) {
        lastSwitchSource[2] = 2;
        relaisToggle(2);
        Serial.println("web Btn3");
      } //if
      if (httpServer.hasArg("allOn")) {
        lastSwitchSource[0] = 2;
        lastSwitchSource[1] = 2;
        lastSwitchSource[2] = 2;
        allRelaisOn();
        Serial.println("web allOn");
      } //if
      if (httpServer.hasArg("allOff")) {
        lastSwitchSource[0] = 2;
        lastSwitchSource[1] = 2;
        lastSwitchSource[2] = 2;
        allRelaisOff();
        Serial.println("web allOff");
      } //if
      yield();

      //build json object of program data
      StaticJsonBuffer<200> jsonBuffer;
      JsonObject &json = jsonBuffer.createObject();
      json["ssid"] = WiFi.SSID();
      if (relais_enabled[0]) json["swState1"] = relais_state[0];
      if (relais_enabled[1]) json["swState2"] = relais_state[1];
      if (relais_enabled[2]) json["swState3"] = relais_state[2];
      json["devname"] = deviceName;

      yield();

      char jsonchar[200];
      json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
      httpServer.send(200, "application/json", jsonchar);
    }
  }); //httpServer.on /api

  httpServer.on("/restart", []() {
    Serial.println("web triggered restart");
    ESP.restart();
  });

  httpServer.on("/confdata", []() {
    boolean sendData = false;
    if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
      if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
      sendData = true;
    }
    else sendData = true;
    if (sendData) {
      Serial.println("httpServer.on /confdata");

      for (int i = 0; i < httpServer.args(); i++) {
        char bufName[20];
        char bufValue[101];
        httpServer.argName(i).toCharArray(bufName, 20);
        httpServer.arg(i).toCharArray(bufValue, 101);

        if (strlen(bufName) > 0) {
          Serial.print("web update ");
          Serial.print(bufName);
          Serial.print(" = ");
          Serial.println(bufValue);
          setConfig(bufName, bufValue);
        }
        saveConfigToFlash = true; // will be saved in next loop()
        Serial.println("web triggered saveConfigToFlash");
      }
      yield();

      //build json object of program data
      StaticJsonBuffer<1000> jsonBuffer;
      JsonObject &json = jsonBuffer.createObject();
      json["devName"] = deviceName;
      json["httpUser"] =  http_user;
      json["httpPass"] =  http_pass;
      json["mqttHost"] = mqtt_server;
      json["mqttPort"] = mqtt_port;
      json["mqttUser"] =  mqtt_user;
      json["mqttPass"] =  mqtt_pass;
      json["inTop"] = mqtt_topic_in;
      json["outTop"] = mqtt_topic_out;
      json["outRet"] = mqtt_outRetain;
      json["willTop"] = mqtt_willTopic;
      json["willQos"] = mqtt_willQos;
      json["willRet"] = mqtt_willRetain;
      json["willMsg"] = mqtt_willMsg;
      json["domOutTop"] = domoticz_out_topic;
      json["allOnOffTop"] = mqtt_allOnOffTopic;

      yield();

      char jsonchar[1000];
      json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
      httpServer.send(200, "application/json", jsonchar);
    }
  }); //httpServer.on /confdata

  httpServer.on("/confdata2", []() {
    boolean sendData = false;
    if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
      if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
      sendData = true;
    }
    else sendData = true;
    if (sendData) {
      Serial.println("httpServer.on /confdata2");

      for (int i = 0; i < httpServer.args(); i++) {
        char bufName[20];
        char bufValue[101];
        httpServer.argName(i).toCharArray(bufName, 20);
        httpServer.arg(i).toCharArray(bufValue, 101);

        if (strlen(bufName) > 0) {
          Serial.print("web update ");
          Serial.print(bufName);
          Serial.print(" = ");
          Serial.println(bufValue);
          setConfig(bufName, bufValue);
        }
        saveConfig2ToFlash = true;
        Serial.println("web triggered saveConfig2ToFlash");
      }
      yield();

      //build json object of program data
      StaticJsonBuffer<1000> jsonBuffer;
      JsonObject &json = jsonBuffer.createObject();
      json["btnRet"] = mqtt_btnRetain;
      json["top1"] = mqtt_topic_out_1;
      json["top2"] = mqtt_topic_out_2;
      json["top3"] = mqtt_topic_out_3;
      json["pld1"] = mqtt_payload_out_1;
      json["pld2"] = mqtt_payload_out_2;
      json["pld3"] = mqtt_payload_out_3;
      json["topHld1"] = mqtt_topic_out_hold_1;
      json["topHld2"] = mqtt_topic_out_hold_2;
      json["topHld3"] = mqtt_topic_out_hold_3;
      json["pldHld1"] = mqtt_payload_out_hold_1;
      json["pldHld2"] = mqtt_payload_out_hold_2;
      json["pldHld3"] = mqtt_payload_out_hold_3;
      json["domIdx1"] = domoticzIdx[0];
      json["domIdx2"] = domoticzIdx[1];
      json["domIdx3"] = domoticzIdx[2];
      json["hld1ToRel"] = hldToRel[0];
      json["hld2ToRel"] = hldToRel[1];
      json["hld3ToRel"] = hldToRel[2];

      yield();

      char jsonchar[1000];
      json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
      httpServer.send(200, "application/json", jsonchar);
    }
  }); //httpServer.on /confdata2

  httpServer.on("/confdatahw", []() {
    boolean sendData = false;
    if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
      if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
      sendData = true;
    }
    else sendData = true;
    if (sendData) {
      Serial.println("httpServer.on /confdatahw");

      for (int i = 0; i < httpServer.args(); i++) {
        char bufName[20];
        char bufValue[101];
        httpServer.argName(i).toCharArray(bufName, 20);
        httpServer.arg(i).toCharArray(bufValue, 101);

        if (strlen(bufName) > 0) {
          Serial.print("web update ");
          Serial.print(bufName);
          Serial.print(" = ");
          Serial.println(bufValue);
          setConfig(bufName, bufValue);
        }
        saveConfigHwToFlash = true;
        Serial.println("web triggered saveConfigHwToFlash");
      }
      yield();

      //build json object of program data
      StaticJsonBuffer<1000> jsonBuffer;
      JsonObject &json = jsonBuffer.createObject();
      json["debtime"] = debounceTime;
      json["hldtime"] = buttonHoldTime;
      json["enaRel1"] = relais_enabled[0];
      json["enaRel2"] = relais_enabled[1];
      json["enaRel3"] = relais_enabled[2];
      json["enaBtn1"] = button_enabled[0];
      json["enaBtn2"] = button_enabled[1];
      json["enaBtn3"] = button_enabled[2];
      json["enaLed1"] = led_enabled[0];
      json["enaLed2"] = led_enabled[1];
      json["enaLed3"] = led_enabled[2];
      json["ioRel1"] = relais_pins[0];
      json["ioRel2"] = relais_pins[1];
      json["ioRel3"] = relais_pins[2];
      json["ioBtn1"] = buttons_pins[0];
      json["ioBtn2"] = buttons_pins[1];
      json["ioBtn3"] = buttons_pins[2];
      json["ioLed1"] = leds_pins[0];
      json["ioLed2"] = leds_pins[1];
      json["ioLed3"] = leds_pins[2];
      json["invRel1"] = relais_invert[0];
      json["invRel2"] = relais_invert[1];
      json["invRel3"] = relais_invert[2];
      json["invBtn1"] = button_invert[0];
      json["invBtn2"] = button_invert[1];
      json["invBtn3"] = button_invert[2];
      json["invLed1"] = led_invert[0];
      json["invLed2"] = led_invert[1];
      json["invLed3"] = led_invert[2];
      json["puls1"] = relais_impulse[0];
      json["puls2"] = relais_impulse[1];
      json["puls3"] = relais_impulse[2];

      yield();

      char jsonchar[1000];
      json.printTo(jsonchar); //print to char array, takes more memory but sends in one piece
      httpServer.send(200, "application/json", jsonchar);
    }
  }); //httpServer.on /confdatahw


  //get heap status, analog input value and all GPIO statuses in one json call
  httpServer.on("/info", HTTP_GET, []() {
    boolean sendData = false;
    if (strlen(http_user) > 0 && strlen(http_pass) > 0) {
      if (!httpServer.authenticate(http_user, http_pass)) return httpServer.requestAuthentication();
      sendData = true;
    }
    else sendData = true;
    if (sendData) {
      String json = "{";
      json += "\"wifissid\":\"" + WiFi.SSID() + "\"";
      json += "\"heap\":" + String(ESP.getFreeHeap());
      json += "}";
      httpServer.send(200, "text/json", json);
      json = String();
    }
  }); //httpServer.on /info

  httpServer.on("/", []() {
    httpServerHandleRoot();
  });

  httpServer.on("/conf", []() {
    httpServerHandleConfPage();
  });

  httpServer.on("/conf2", []() {
    httpServerHandleConf2Page();
  });

  httpServer.on("/confhw", []() {
    httpServerHandleConfHwPage();
  });

  httpServer.onNotFound([]() {
    httpServerHandleNotFound();
  }); //httpServer.onNotFound

  // HTTP Updater at /update
  httpUpdater.setup(&httpServer);

  httpServer.begin();
}


