<!DOCTYPE html>
<html>

<!--This is the uncompressed version of the main index.htm file-->
<!--For the Arduino code source, visit thestuffwebuild.com-->

<head>
  <meta http-equiv="cache-control" content="max-age=0">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="pragma" content="no-cache">
  <title>Arduino AJAX Camera Server</title>
  <style>
    body {
      background: #fff;
      font-family: arial;
      font-size: 14px;
      line-height: 20px;
      padding: 5px
    }
    a {
      font-weight: normal
    }
    img {
      display: block;
      margin: 0
    }
    p {
      display: block;
      margin: 2px 2px 2px 2px;
      font-weight: normal;
    }
    .btn1 {
      display: block;
      height: 90px;
      width: 200px;
      font-weight: bolder
    }
    .btn2 {
      display: block;
      width: 200px;
    }
    .vat {
      vertical-align: top;
      width: 250px;
    }
    .hh00 {
      margin-top: 6px;
      margin-bottom: 6px;
      font-size: 25px;
      font-weight: 700
    }
    .tab1 {
      border-collapse: collapse;
      border-spacing: 0;
      margin-top: 0.75em;
      padding: 2em 2em 2em 2em;
      border: 1px solid #aaa;
      margin: 0;
      padding: 4px;
    }
    .tab2 {
      border-collapse: collapse;
      width: 100%;
      border: 1px;
      margin: 0;
      padding: 4px
    }
    .bt {
      border-top: 1px solid #aaa
    }
    td {
      border: 0px;
      margin: 0;
      padding: 4px
    }
    tr {
      border: 0px;
      margin: 0;
      padding: 4px
    }
    .t {
      text-align: right;
      margin: 0 0 0px 0px
    }
    .l {
      text-align: left;
      margin: 0 0 0px 0px
    }
    .loading {
      position: absolute;
      left: 0px;
      top: 0px;
      font-size: 20px;
      font-weight: 900
    }
    .light {
      color: lightgray
    }
    .cc {
      text-align: center;
      margin: 2em 0px 2em 0px;
      font-size: 10px;
      font-weight: 700;
    }
    .c2 {
      text-align: center;
      margin: 2em 0px 2em 0px;
      font-size: 10px;
      font-weight: normal;
    }
    .chk {
      margin: 0;
      padding: 0;
    }

  </style>
  <script>
    var myVar; //for xml request timer
    var myVarb; //for timelapse timer
    var rep = 0
    var waiting = 0;
    var force = 1;
    var heartbeat = 2000; //how often we will check for new data

    function dataRTimer() {
      myVar = setInterval(function() {
        dataReq()
      }, heartbeat);
    }

    function dataReq() {
      var nocachea = "&nocache=" + (new Date()).getTime();
      var age = document.getElementById("age"); // for updating picture age 
      var myselect = document.getElementById("myselect"); //for button higind
      var myselectValue = myselect.options[myselect.selectedIndex].value; //for button hiding
      var notify = document.getElementById("incominga"); //for "downloading now" text
      var xrequest = new XMLHttpRequest();
      xrequest.onreadystatechange = function() {
        if(xrequest.readyState == 4) {
          if(xrequest.status == 200) {
            if(xrequest.responseXML != null) {
              var picture = document.getElementById("camimage"); //for updating image
              var tmppicture = new Image();

              function peanuts() {
                //force = 1;
                waiting = 0;
                clearTimeout(delay6);
                notify.innerHTML = "Ready. ";
                //only unhide button if we are not in timelapse mode
                if(myselect.options[myselect.selectedIndex].value == 0) {
                  document.getElementById("btn1id").disabled = false;
                  document.getElementById("myselect").disabled = false;
                }
              };

              function cashews() {
                //we got a responce, that menes we are nolonger waiting
                force = 1;
                waiting = 0;
                clearTimeout(delay6);
                notify.innerHTML = "Image malformed. Trying again.";
              };
              picture.addEventListener('load', peanuts, false);
              picture.addEventListener('error', cashews, false);
              // extract XML data from XML file (containing switch states and analog value)
              document.getElementById("imgid").innerHTML = xrequest.responseXML.getElementsByTagName('id')[0].childNodes[0].nodeValue;
              tmppicture.src = xrequest.responseXML.getElementsByTagName('id')[0].childNodes[0].nodeValue;
              var realtime = xrequest.responseXML.getElementsByTagName('age')[0].childNodes[0].nodeValue;
              if(realtime <= 0) realtime = "a few";
              age.innerHTML = realtime;
              document.getElementById("A0").innerHTML = xrequest.responseXML.getElementsByTagName('A0')[0].childNodes[0].nodeValue;
              document.getElementById("maxpics").innerHTML = xrequest.responseXML.getElementsByTagName('mp')[0].childNodes[0].nodeValue;
              document.getElementById("hits").innerHTML = xrequest.responseXML.getElementsByTagName('hit')[0].childNodes[0].nodeValue;
              var uptime = xrequest.responseXML.getElementsByTagName('up')[0].childNodes[0].nodeValue;
              document.getElementById("uptime").innerHTML = Math.round(uptime * 100.0 / 3600000) / 100;
              document.getElementById("imgsize").innerHTML = xrequest.responseXML.getElementsByTagName('size')[0].childNodes[0].nodeValue;
              document.getElementById("load").innerHTML = xrequest.responseXML.getElementsByTagName('lo')[0].childNodes[0].nodeValue;
              var delay6 = setTimeout(function() {
                notify.innerHTML = "Downloading a new image. Please wait. ";
                document.getElementById("btn1id").disabled = true;
                if(myselectValue == 0) document.getElementById("myselect").disabled = true;
              }, 250);
              if(picture.src == tmppicture.src) {
                waiting = 0;
                clearTimeout(delay6);
                notify.innerHTML = "Ready. ";
                //only unhide buttons if we are not in timelapse mode
                if(myselect.options[myselect.selectedIndex].value == 0) {
                  document.getElementById("btn1id").disabled = false;
                  document.getElementById("myselect").disabled = false;
                }
              }
              picture.src = tmppicture.src;
            }
          }
        }
      };

      xrequest.addEventListener("error", function() {
        waiting = 0;
      });

      //send xml request 
      if(waiting == 0 || force == 1) {
        xrequest.open("GET", "/?xml" + nocachea, true);
        xrequest.send(null);
        force = 0;
        waiting = 1;
      }
      else {
        //wait for main timer to call us again.
      }
    }

    function picReq() {
      var notify = document.getElementById("incominga"); //for status text
      var myselect = document.getElementById("myselect"); //so we can hide the timelapse button
      var myselectValue = myselect.options[myselect.selectedIndex].value;
      var myselect2 = document.getElementById("myselect2"); //so we can choose a image resolution
      var myselectValue2 = myselect2.options[myselect2.selectedIndex].value;
      var picreq = new XMLHttpRequest();
      //hide buttons (will unhide on image onload/onerror)
      document.getElementById("btn1id").disabled = true;
      if(myselectValue == 0) document.getElementById("myselect").disabled = true;
      if(waiting == 0) {
        if(myselectValue2 == 60000) {
          picreq.open("GET", "/?pic3", true);
          picreq.send();
        }
        else if(myselectValue2 == 30000) {
          picreq.open("GET", "/?pic2", true);
          picreq.send();
        }
        else { //if myselectValue2 <= 10000
          picreq.open("GET", "/?pic1", true);
          picreq.send();
        }
        force = 1;
        waiting = 1;
        notify.innerHTML = "Picture request sent. Please wait. ";
        var delay8 = setTimeout(function() {
        dataReq();
        }, 50);
      }
      else {
        notify.innerHTML = "The server is busy. Trying again.";
        var delay8 = setTimeout(function() {
          picReq();
          waiting = 0;
        }, 100);
      }
    }

    //set timelapse interval to appropriate size when res is increased
    function imageRes() {
      var myselect2 = document.getElementById("myselect2");
      var myselectValue2 = myselect2.options[myselect2.selectedIndex].value;
      if(myselectValue2 > myselect.value && myselect.value != 0) {
        if(myselect.value != 120000) {
          myselect.value = myselectValue2;
        }
      }
    }

    //auto mode
    function timeLapse() {
      //stop main xml timer
      clearInterval(myVar);
      //stop timelapse timer
      clearTimeout(myVarb);
      var myselect = document.getElementById("myselect");
      var myselectValue = myselect.options[myselect.selectedIndex].value;
      var autonotify = document.getElementById("incomingb");
      //set img res appropriately for sake of sanity
      if(myselectValue < myselect2.value && myselectValue != 0) {
        if(myselectValue <= 60000) {
          myselect2.value = myselectValue;
        }
      }
      //if timelapse box is set to none, unhide btns and start main heartbeat timer
      if(myselectValue == 0) {
        //document.getElementById("btn1id").disabled = false;
        //document.getElementById("btn2id").disabled = false;
        incomingb.innerHTML = "";
        dataRTimer();
      }
      //if timelapse box is on, hide btns and takepic, then resume timelapse timer
      else {
        document.getElementById("btn1id").disabled = true;
        //document.getElementById("btn2id").disabled = true;
        if(waiting == 0) {
          incomingb.innerHTML = "<p class=\"l\"><b>Auto mode: </b>Active.</p>";
          picReq();
          myVarb = setTimeout('timeLapse()', myselectValue);
        }
        else {
          incomingb.innerHTML = "<p class=\"l\"><b>Auto mode: </b>Server busy. Trying again in a few seconds.</p>";
          myVarb = setTimeout("timeLapse()", 500);
        }
      }
    }

    var closedir; //to see if dir list is open or closed
    //receives and prints the latest directory index
    function dirReq() {
      var nocacheb = "&nocache=" + (new Date()).getTime();
      var dddir = document.getElementById("dir"); //the <span> tag so we can output the data
      var loader = document.getElementById("loadindex"); //button element so we can change its text
      var xmlhttpx = new XMLHttpRequest();
      //if we get a response, do this
      xmlhttpx.onreadystatechange = function() {
        if(xmlhttpx.readyState == 4 && xmlhttpx.status == 200) {
          dddir.innerHTML = xmlhttpx.responseText;
          //change button text to normal
          loader.innerHTML = "Close list";
          document.getElementById("btn2id").disabled = false;
          closedir = 1;
          //turn all href links to open in new tab
          var els = document.getElementsByTagName('a');
          for(var i = 0, len = els.length; i < len; i++) els[i].setAttribute('target', '_blank');
        }
      }
      if(closedir != 1) {
        xmlhttpx.open("GET", "/?dir" + nocacheb, true);
        xmlhttpx.send();
        loader.innerHTML = "Loading list";
        document.getElementById("btn2id").disabled = true;
      }
      else {
        dddir.innerHTML = "<i class=\"light\">Update index to see all files on root.</i>";
        loader.innerHTML = "Update index";
        closedir = 0;
      }
    }

    var foot; //var to see if dynfooter is open or closed
    function debug() {
      var spaces = " &nbsp; &nbsp; ";
      var deb = document.getElementById("dynfooter"); //for "downloading now" text
      if(foot != 1) {
        deb.innerHTML = "<button type=\"button\" onclick=\"picReq();\" title=\"Request Picture - 'picReq()' - normally fired by big button\">picReq</button>" + spaces + "<button type=\"button\" onclick=\"dataReq()\" title=\"Request XML Data - 'dataReq()' - normally fired by 'dataRTimer()' every couple seconds\">dataReq</button>" + spaces + "<button type=\"button\" onclick=\"location.reload()\" title=\"Refresh Page - fixes everything!\">!!!</button>" + spaces + "<button type=\"button\" onclick=\"waiting=0\" title=\"Reset 'waiting' var - global var used to disable big button\">rset: " + waiting + "</button><br><b>AJAX requests:</b> /?pic1 - /?pic2 - /?pic3 - /?xml - /?dir";
        foot = 1;
      }
      else {
        deb.innerHTML = ""
        foot = 0;
      }
    }

    function howto() {
      var debe = document.getElementById("dynfooter"); //for "downloading now" text
      if(foot != 1) {
        debe.innerHTML = "Hover your mouse over various parts of this page to learn what they are. Can you also close this readme? It's a bit chilly in here.";
        foot = 1;
      }
      else {
        debe.innerHTML = ""
        foot = 0;
      }
    }

    function ispaused() {
      var debs = document.getElementById("ss");
      if(document.getElementById("myCheck").checked == false) {
        debs.innerHTML = "Polling Paused.";
        clearInterval(myVar);
      }
      else {
        if(waiting == 0) {
          debs.innerHTML = "Polling Resumed! ";
          document.getElementById("myCheck").disabled = true;
          clearInterval(myVar);
          dataRTimer();
          var delay7 = setTimeout(function() {
            debs.innerHTML = "";
            document.getElementById("myCheck").disabled = false;
          }, 1000);
        }
        else {
          document.getElementById("myCheck").checked = false;
          //force = 1;
        }
      }
    }

  </script>
</head>

<body>
  <p class="loading" id="loading" title="Still?! Try refreshing the page or make sure scripts are enabled.">Loading document...</p>
  <table class="tab1">
    <tr>
      <th>
        <p title="Now with 100% more Asynchronous JavaScript and XML (AJAX)!" class="hh00">Arduino AJAX Camera Server</p>
      </th>
    </tr>
    <tr>
      <td class="bt">
        <p class="l" title="This shows the age and filename of the most recently taken picture. ">This picture, titled <b><span id="imgid">[loading]</span></b>, was taken <b><span id="age">[loading]</span></b> seconds ago: </p>
      </td>
    </tr>
    <tr>
      <td> <img src="//:0" id="camimage" height="480" width="640" alt="Waiting for picture..."> </td>
    </tr>
    <tr>
      <td class="bt">
        <p class="l" title="Watch here for status pertaining to the webserver. "><b>Camera control: </b><span id="incominga">Connecting...</span> </p>
        <table class="tab2">
          <tr>
            <th rowspan="3" class="vat">
              <button type="button" onclick="picReq()" class="btn1" id="btn1id" title="Take a picture! - But be patient for it takes roughly 10sec for the low-resolution image to arrive, and about 60sec for the highest-resolution.">Take new picture!</button>
            </th>
            <td>
              <p class="t"> Automatically record new image
                <select id="myselect" onchange="timeLapse()" title="Set how often you want your browser to automatically take and receive a new picture with this drop-down box.">
                  <option value="0" selected="selected">never</option>
                  <option value="10000">every 10 seconds</option>
                  <option value="30000">every 30 seconds</option>
                  <option value="60000">every 60 seconds</option>
                  <option value="120000">every 120 seconds</option>
                </select>
              </p>
            </td>
          </tr>
          <tr>
            <td>
              <p class="t"> Set image size/resolution:
                <select id="myselect2" onchange="imageRes()" title="You can select a higher or lower resolution with this drop-down box. Keep in mind that the highest resolution will take about 60-seconds round trip. The lowest will take about 10sec.">
                  <option value="0" selected="selected">default</option>
                  <option value="10000">160x120</option>
                  <option value="30000">320x240</option>
                  <option value="60000">640x480</option>
                </select>
              </p>
            </td>
          </tr>
          <tr>
            <td>
              <p class="t">Automatically update XML data?
                <input type="checkbox" id="myCheck" class="chk" onclick="ispaused()" title="Click here to pause/resume data polling.">
              </p>
            </td>
          </tr>
        </table> <span id="incomingb"></span> </td>
    </tr>
    <tr>
      <td class="bt" title="This section shows server-generated values for various elements of the server's function. Every couple of seconds, your browser will ask for fresh data and update these values (unless polling is paused).">
        <p class="l"><b>XML Status: </b><span id="ss"></span>
        </p>
        <table class="tab2">
          <tr>
            <th>
              <p title="Hits - how many times this page was loaded.">Hits = <b><span id="hits">&lt; 0</span></b> </p>
            </th>
            <th>
              <p title="Load - how much work the server is doing presently.">Load = <b><span id="load">null</span></b> </p>
            </th>
            <th>
              <p title="Uptime - how long the server has been running for.">Uptime = <b><span id="uptime">&lt; 0</span>hrs</b> </p>
            </th>
          </tr>
          <tr>
            <th>
              <p title="Size - the most recently used image size.">Size = <b><span id="imgsize">&lt; 0</span>px</b> </p>
            </th>
            <th>
              <p title="maxpics - the maximum number of pictures the system will keep on the card before writing them over.">maxpics = <b><span id="maxpics">&lt; 0</span></b> </p>
            </th>
            <th>
              <p title="Temp - tempeture measured near the server.">Temp = <b><span id="A0">&lt; 0</span>&deg;F</b> </p>
            </th>
          </tr>
        </table>
      </td>
    </tr>
    <tr>
      <td class="bt" title="This section will display a list of all the files in the root directory of the SD card once the 'Update index' button is pressed. This may take a few seconds, so be patient.">
        <p class="l"><b>Root File Index: </b>
        </p>
        <table class="tab2">
          <tr>
            <th class="vat">
              <button type="button" onclick="dirReq()" class="btn2" id="btn2id"><span id="loadindex">Update index</span> </button>
            </th>
            <td>
              <p class="l"><span id="dir" title=""><i class="light">Update index to see all files on root.</i></span> </p>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    <tr>
      <td class="bt">
        <p class="cc">v1.0.4 &nbsp; - &nbsp; visit thestuffwebuild.com for more &nbsp; - &nbsp; <span onclick="debug()" title="For advanced users. Debugging.">adv</span> &nbsp; - &nbsp; <span onclick="howto()" Title="Click me!">readme</span> </p>
        <p class="c2"><span id="dynfooter"></span> </p>
      </td>
    </tr>
  </table>
  <br />
  <br />
  <br />
  <script>
    window.onload = function() {
      dataRTimer();
      document.getElementById("myselect").disabled = false;
      document.getElementById("btn1id").disabled = false;
      document.getElementById("btn2id").disabled = false;
      document.getElementById("myCheck").checked = true;
    }

  </script>
  <script>
    document.getElementById("loading").innerHTML = "";

  </script>
</body>

</html>
