<!DOCTYPE html>
<html>
  <head>
    <title>ILStec Mobile Phone Mouse</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale = 1.0, maximum-scale = 1.0, user-scalable=no">
    <style type="text/css">
      html
      {
        height: 100%;
        width: 100%;
      }
      body
      {
        border: 0px;
        padding: 0px;
        margin: 0px;
        background-color: #336699;
        height: 100%;
        width: 100%;
      }
      .DIVinput
      {
        text-align: center;
      }
      .DIVinputLayout
      {
        text-align: center;
        font-weight: 700;
        text-align: center;
        color: white;
      }
      .CGIResponse
      {
        text-align: center;
        font-family: 'Courier New', monospace;
        font-weight: 700;
      }
      table, th, td
      {
        border: 0px;
        padding: 0px;
        margin: 0px;
        border-collapse: collapse;
      }
      #outertable
      {
        height: 100%;
        width: 100%;
        border: 0px;
        padding: 0px;
        margin: 0px;
      }
      #row0
      {
        height: 50vh;
      }
      #row1
      {
        height: 50vh;
      }
      #col00
      {
        height: 100%;
        width: 10%;
      }
      #col01
      {
        height: 100%;
        width: 80%;
      }
      #col02
      {
        height: 100%;
        width: 10%;
      }
      #col10
      {
        height: 100%;
        width: 10%;
      }
      #col12
      {
        height: 100%;
        width: 10%;
      }
      #DivL0
      {
        border: none;
        padding: 0px;
        margin: 0px;
        background-color: #FF0000;
        height: 100%;
        width: 100%;
      }
      #DivXY
      {
        border: none;
        padding: 0px;
        margin: 0px;
        background-color: #0000FF;
        height: 100%;
        width: 100%;
      }
      #DivR0
      {
        border: none;
        padding: 0px;
        margin: 0px;
        background-color: #FF0000;
        height: 100%;
        width: 100%;
      }
      #DivL1
      {
        border: none;
        padding: 0px;
        margin: 0px;
        background-color: #00FF00;
        height: 100%;
        width: 100%;
      }
      #DivR1
      {
        border: none;
        padding: 0px;
        margin: 0px;
        background-color: #00FF00;
        height: 100%;
        width: 100%;
      }
      #container
      {
        height: 100%;
        width: 100%;
      }
      #container:fullscreen
      {
        width: 100%;
        height: 100%;
        background-color: green;
      }
      #container:-webkit-full-screen
      {
        width: 100%;
        height: 100%;
        background-color: green;
      }
      #orientation-status
      {
        border: none;
        padding: 0px;
        margin: 0px;
        text-align: center;
        color: white;
        display: none;
      }
      label
      {
        text-align: center;
        border: none;
        padding: 0px;
        margin: 0px;
        font-weight: 700;
        text-align: center;
        color: white;
      }
      #version
      {
        text-align: center;
        border: none;
        padding: 0px;
        margin: 0px;
        color: #336699;
        font-weight: 700;
        text-align: center;
        color: white;
      }
      button
      {
        background-color: white;
        border: 1px solid #336699;
        color: #336699;
        width: 200px;
        padding: 10px;
        display: block;
        margin-left: auto;
        margin-right: auto;
        font-weight: 700;
        outline: none;
      }
      #Layout0
      {
        background-color: white;
        border: 1px solid #336699;
        color: #336699;
        width: 50px;
        padding: 10px;
        display: inline-block;
        margin-left: auto;
        margin-right: auto;
        font-weight: 700;
        outline: none;
      }
      #Layout1
      {
        background-color: white;
        border: 1px solid #336699;
        color: #336699;
        width: 50px;
        padding: 10px;
        display: inline-block;
        margin-left: auto;
        margin-right: auto;
        font-weight: 700;
        outline: none;
      }
      #Layout2
      {
        background-color: white;
        border: 1px solid #336699;
        color: #336699;
        width: 50px;
        padding: 10px;
        display: inline-block;
        margin-left: auto;
        margin-right: auto;
        font-weight: 700;
        outline: none;
      }
      #lock-landscape-button
      {
        background-color: green;
        border: 1px solid #336699;
        color: white;
        width: 200px;
        height: 60px;
        padding: 10px;
        display: block;
        margin-left: auto;
        margin-right: auto;
        font-weight: 700;
        outline: none;
      }
      #unlock-button
      {
        background-color: red;
        border: 1px solid #336699;
        color: #336699;
        width: 200px;
        height: 20px;
        padding: 10px;
        margin-left: auto;
        margin-right: auto;
        font-weight: 700;
        outline: none;
        display: none;
      }
    </style>
  </head>
  <body>
    <div id="container">
      <table id="outertable">
        <tr id="row0">
          <td id="col00">
            <div id="DivL0" ontouchstart="OnTouchStartDivL0(event)" ontouchmove="OnTouchMoveDivL0(event)" ontouchend="OnTouchEndDivL0(event)"></div>
          </td>
          <td id="col01" rowspan="2">
            <div id="DivXY" ontouchmove="OnTouchMoveDivXY(event)">
              <br><br>
              <div id="version">Version 2023-02-20-C</DIV><br>
              <p id="orientation-status"></p>
              <button id="SendTestRequests" onclick="SendTestRequests();">Send 5000 XYS Requests</button>
              <br>
              <div id="DIVinputLayout" class="DIVinputLayout">
                <label for="Layout0">0:&nbsp;</label><input type="radio" id="Layout0" name="LayoutGroup" value="0" onclick="SelectLayout(0);">
                <label for="Layout1">1:&nbsp;</label><input type="radio" id="Layout1" name="LayoutGroup" value="1" onclick="SelectLayout(1);">
                <label for="Layout2">2:&nbsp;</label><input type="radio" id="Layout2" name="LayoutGroup" value="2" onclick="SelectLayout(2);">
              </div><br>
              <div id="DIVinputScreen" class="DIVinput"><label for="inputScreen">Screen:&nbsp;</label><input type="text" id="inputScreen" name="inputScreen" oninput="SetScreen();"></DIV><br>
              <div id="DIVinputPointer" class="DIVinput"><label for="inputPointer">Pointer:&nbsp;</label><input type="text" id="inputPointer" name="inputPointer" oninput="SetPointer();"></DIV><br>
              <button id="WriteParameters" onclick="WriteParameters();">Write Parameters</button>
              <button id="Vibrate" onclick="MyVibrate();">Test Vibrate</button>
              <p class="CGIResponse" id="CGIResponse"></p>
              <div id="buttons-container">
                <button id="lock-landscape-button">START</button>
                <button id="unlock-button"></button>
              </div>
            </div>
          </td>
          <td id="col02">
            <div id="DivR0" ontouchstart="OnTouchStartDivR0(event)" ontouchmove="OnTouchMoveDivR0(event)" ontouchend="OnTouchEndDivR0(event)"></div>
          </td>
        </tr>
        <tr id="row1">
          <td id="col10">
            <div id="DivL1" ontouchstart="OnTouchStartDivL1(event)" ontouchmove="OnTouchMoveDivL1(event)" ontouchend="OnTouchEndDivL1(event)"></div>
          </td>
          <td id="col12">
            <div id="DivR1" ontouchstart="OnTouchStartDivR1(event)" ontouchmove="OnTouchMoveDivR1(event)" ontouchend="OnTouchEndDivR1(event)"></div>
          </td>
        </tr>
      </table>
    </div>
    <script>
      function fFIFOCMD(iNumElements)
      {
        this.size = 0;
        this.capacity = iNumElements;
        var iWriteIndex=0;
        var iReadIndex=0;
        var dwArray = new Uint32Array(iNumElements);
        this.IsFull=function()
        {
          return this.capacity === this.size;
        }
        this.IsEmpty=function()
        {
          return this.size === 0;
        }
        this.Write=function(v)
        {
          dwArray[iWriteIndex] = v;
          iWriteIndex=(iWriteIndex+1)%this.capacity;
          this.size++;
        }
        this.Read=function()
        {
          var tmp = dwArray[iReadIndex];
          iReadIndex=(iReadIndex+1)%this.capacity;
          this.size--;
          return tmp;
        }
      }
      var iLayout=0;
      var iScreen=0;
      var iPointer=0;
      var iPointerX=0;
      var iPointerY=0;
      var iPointerL=0;
      var iPointerR=0;
      var iFrameCounter=0;
      var rectDivXY=document.getElementById("DivXY").getBoundingClientRect();
      var iLeftXY = rectDivXY.left|0;
      var iRightXY = rectDivXY.right|0;
      var iTopXY = rectDivXY.top|0;
      var iBottomXY = rectDivXY.bottom|0;
      var iWidthXY=iRightXY-iLeftXY;
      var iHeightXY=iBottomXY-iTopXY;
      var bAskVibrate = true;
      var bCanVibrate = false;
      var bTimerEnable = false;
      var bTimerActive = false;
      iTimerSetLandscapeMode=0;
      var iVibrationActiveTime=0;
      var iAcknowledgeMode=0;
      var iAcknowledgePacket=0;
      var FIFOCMD=new fFIFOCMD(100);
      navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
      if('vibrate' in navigator) bCanVibrate = true;
      document.getElementById("SendTestRequests").style.display = 'none';
      document.getElementById("WriteParameters").style.display = 'none';
      document.getElementById("Vibrate").style.display = 'none';	/* uncomment for debug purpose */
      document.getElementById("CGIResponse").style.display = 'none';	/* uncomment for debug purpose */
      var responseout = document.getElementById("CGIResponse");
      if (localStorage.getItem("Layout")) iLayout=parseInt(localStorage.getItem("Layout"));
      if (localStorage.getItem("Screen")) iScreen=parseInt(localStorage.getItem("Screen"));
      if (localStorage.getItem("Pointer")) iPointer=parseInt(localStorage.getItem("Pointer"));
      SelectLayout(iLayout);
      document.getElementById("inputScreen").value = iScreen;
      document.getElementById("inputPointer").value = iPointer;
      setInterval(OnTimer50Msec, 50);
      function OnTimer50Msec()
      {
        if (iTimerSetLandscapeMode>0)
        {
          iTimerSetLandscapeMode--;
          if (iTimerSetLandscapeMode==0)
          {
            LandscapeMode(false);
          }
        }
        if (bTimerEnable==false) return; 
        if (bTimerActive) return;
        bTimerActive=true;
        if (iVibrationActiveTime>0)
        {
          iVibrationActiveTime-=50;
        }
        else
        {
          if (!FIFOCMD.IsEmpty())
          {
            var iMyCmd = FIFOCMD.Read();
            if (iMyCmd==0xA0)
            {
              navigator.vibrate([100, 150]);
              iVibrationActiveTime=250;
            }
            if (iMyCmd==0xA1)
            {
              navigator.vibrate([200, 150]);
              iVibrationActiveTime=350;
            }
            if (iMyCmd==0xA2)
            {
              navigator.vibrate([400, 150]);
              iVibrationActiveTime=550;
            }
            if (iMyCmd==0xA3)
            {
              navigator.vibrate([100, 150, 100, 150]);
              iVibrationActiveTime=500;
            }
            if (iMyCmd==0xA4)
            {
              navigator.vibrate([200, 150, 200, 150]);
              iVibrationActiveTime=700;
            }
            if (iMyCmd==0xA5)
            {
              navigator.vibrate([400, 150, 400, 150]);
              iVibrationActiveTime=1100;
            }
          }
        }
        SendRequest();
        bTimerActive=false;
      }
      function OnTouchStartDivL0(event)
      {
        event.preventDefault();
        iPointerR=1;
      }
      function OnTouchStartDivR0(event)
      {
        event.preventDefault();
        iPointerR=1;
      }
      function OnTouchStartDivL1(event)
      {
        event.preventDefault();
        iPointerL=1;
      }
      function OnTouchStartDivR1(event)
      {
        event.preventDefault();
        iPointerL=1;
      }
      function OnTouchMoveDivL0(event)
      {
        event.preventDefault();
        iPointerR=1;
      }
      function OnTouchMoveDivR0(event)
      {
        event.preventDefault();
        iPointerR=1;
      }
      function OnTouchMoveDivL1(event)
      {
        event.preventDefault();
        iPointerL=1;
      }
      function OnTouchMoveDivR1(event)
      {
        event.preventDefault();
        iPointerL=1;
      }
      function OnTouchEndDivL0(event)
      {
        event.preventDefault();
        iPointerR=0;
      }
      function OnTouchEndDivR0(event)
      {
        event.preventDefault();
        iPointerR=0;
      }
      function OnTouchEndDivL1(event)
      {
        event.preventDefault();
        iPointerL=0;
      }
      function OnTouchEndDivR1(event)
      {
        event.preventDefault();
        iPointerL=0;
      }
      function OnTouchMoveDivXY(event)
      {
        event.preventDefault();
        rectDivXY=document.getElementById("DivXY").getBoundingClientRect();
	iLeftXY = rectDivXY.left|0;
	iRightXY = rectDivXY.right|0;
	iTopXY = rectDivXY.top|0;
	iBottomXY = rectDivXY.bottom|0;
	iWidthXY=iRightXY-iLeftXY;
	iHeightXY=iBottomXY-iTopXY;
        var iX = event.touches[0].clientX | 0;
        var iY = event.touches[0].clientY | 0;
        if ((iX>iLeftXY)&&(iX<iRightXY)) iPointerX=((iX-iLeftXY)*65535/iWidthXY)|0;
        if ((iY>iTopXY)&&(iY<iBottomXY)) iPointerY=((iY-iTopXY)*65535/iHeightXY)|0;
      }
      async function SendRequest()
      {
        var strL=('0000' + iLayout.toString(16).toUpperCase()).slice(-1);
        var strS=('0000' + iScreen.toString(16).toUpperCase()).slice(-2);
        var strP=('0000' + iPointer.toString(16).toUpperCase()).slice(-2);
        var strF=('0000' + iFrameCounter.toString(16).toUpperCase()).slice(-4);
        var strX=('0000' + iPointerX.toString(16).toUpperCase()).slice(-4);
        var strY=('0000' + iPointerY.toString(16).toUpperCase()).slice(-4);
        var strBL=('0000' + iPointerL.toString(16).toUpperCase()).slice(-1);
        var strBR=('0000' + iPointerR.toString(16).toUpperCase()).slice(-1);
        var strAck=('0000' + iAcknowledgeMode.toString(16).toUpperCase()).slice(-2)+('0000' + iAcknowledgePacket.toString(16).toUpperCase()).slice(-2);
        iAcknowledgeMode=0x02;
        var requesturl = "ILStec"+strL+strS+strP+strF+strX+strY+strBL+strBR+strAck;
        let httpresponse = await fetch(requesturl);
        if (httpresponse.ok)
        {
          let response = await httpresponse.text();
          iFrameCounter++;
          if (iFrameCounter>65535) iFrameCounter=0;
          let iPacket=parseInt(response.substr(0, 2),16);
          let iCommand=parseInt(response.substr(2, 2),16);
          if (iPacket>iAcknowledgePacket)
          {
            iAcknowledgePacket=iPacket;
            iAcknowledgeMode=0x03;
            /* remove commenting to see the acknowledged data in the HTTP response */
            /* responseout.innerHTML = response + " / " + iAcknowledgePacket + " / " + iAcknowledgeMode + " / " + iCommand; */
            if (iCommand!=0)
            {
              FIFOCMD.Write(iCommand)
            }
          }
        }
      }
      async function SendTestRequests(e)
      {
        var strL=('0000' + iLayout.toString(16).toUpperCase()).slice(-1);
        var strS=('0000' + iScreen.toString(16).toUpperCase()).slice(-2);
        var strP=('0000' + iPointer.toString(16).toUpperCase()).slice(-2);
        var strX=('0000' + iPointerX.toString(16).toUpperCase()).slice(-4);
        var strY=('0000' + iPointerY.toString(16).toUpperCase()).slice(-4);
        var strBL=('0000' + iPointerL.toString(16).toUpperCase()).slice(-4);
        var strBR=('0000' + iPointerR.toString(16).toUpperCase()).slice(-4);
        var x;
        var requesturl = "ILStec"+strL+strS+strP+strX+strY+strBL+strBR;
        for (x=0;x<5000;x++)
        {
          var httpresponse = await fetch(requesturl);
          if (httpresponse.ok)
          {
            var response = await httpresponse.text();
            responseout.innerHTML = response;
          }
        }
      }
      function WriteParameters()
      {
        localStorage.setItem("Layout", iLayout);
        localStorage.setItem("Screen", iScreen);
        localStorage.setItem("Pointer", iPointer);
      }
      function SetScreen()
      {
        iScreen = parseInt(document.getElementById("inputScreen").value);
      }
      function SetPointer()
      {
        iPointer = parseInt(document.getElementById("inputPointer").value);
      }
      function LandscapeMode(bLandscape)
      {
        var x;
        if (bLandscape==true)
        {
          WriteParameters();
          iAcknowledgeMode=0x02;
          bTimerEnable=true;
          document.getElementById("version").style.visibility = "hidden";
          document.getElementById("orientation-status").style.visibility = "hidden";
          document.getElementById("SendTestRequests").style.visibility = "hidden";
          document.getElementById("DIVinputLayout").style.visibility = "hidden";
          document.getElementById("Layout0").style.visibility = "hidden";
          document.getElementById("Layout1").style.visibility = "hidden";
          document.getElementById("Layout2").style.visibility = "hidden";
          document.getElementById("DIVinputScreen").style.visibility = "hidden";
          document.getElementById("DIVinputPointer").style.visibility = "hidden";
          document.getElementById("WriteParameters").style.visibility = "hidden";
          document.getElementById("Vibrate").style.visibility = "hidden";
          document.getElementById("CGIResponse").style.visibility = "visible";		/*was visible for testing, hidden for final */
          document.getElementById("buttons-container").style.visibility = "hidden";
          document.getElementById("lock-landscape-button").style.visibility = "hidden";
          document.getElementById("unlock-button").style.visibility = "visible";
        }
        else
        {
          bTimerEnable=false;
          for (x=0;x<10;x++)
          {
            iAcknowledgeMode=0x01;
            SendRequest();
          }
          document.getElementById("version").style.visibility = "visible";
          document.getElementById("orientation-status").style.visibility = "visible";
          document.getElementById("SendTestRequests").style.visibility = "visible";
          document.getElementById("DIVinputLayout").style.visibility = "visible";
          document.getElementById("Layout0").style.visibility = "visible";
          document.getElementById("Layout1").style.visibility = "visible";
          document.getElementById("Layout2").style.visibility = "visible";
          document.getElementById("DIVinputScreen").style.visibility = "visible";
          document.getElementById("DIVinputPointer").style.visibility = "visible";
          document.getElementById("WriteParameters").style.visibility = "visible";
          document.getElementById("Vibrate").style.visibility = "visible";
          document.getElementById("CGIResponse").style.visibility = "visible";
          document.getElementById("buttons-container").style.visibility = "visible";
          document.getElementById("lock-landscape-button").style.visibility = "visible";
          document.getElementById("unlock-button").style.visibility = "hidden";
        }
      }
      function SelectLayout(x)
      {
        iLayout=x;
        if (x==0)
        {
          document.getElementById("Layout0").checked = true;
          document.getElementById("Layout1").checked = false;
          document.getElementById("Layout2").checked = false;
          document.getElementById("col00").style.width="10%";
          document.getElementById("col01").style.width="90%";
          document.getElementById("col02").style.width="0%";
          document.getElementById("col10").style.width="10%";
          document.getElementById("col12").style.width="0%";
          document.getElementById("row0").style.height="50vh";
          document.getElementById("row1").style.height="50vh";
          document.getElementById("DivL0").style.background="#FF0000";
        }
        if (x==1)
        {
          document.getElementById("Layout0").checked = false;
          document.getElementById("Layout1").checked = true;
          document.getElementById("Layout2").checked = false;
          document.getElementById("col00").style.width="0%";
          document.getElementById("col01").style.width="90%";
          document.getElementById("col02").style.width="10%";
          document.getElementById("col10").style.width="0%";
          document.getElementById("col12").style.width="10%";
          document.getElementById("row0").style.height="50vh";
          document.getElementById("row1").style.height="50vh";
          document.getElementById("DivL0").style.background="#FF0000";
        }
        if (x==2)
        {
          document.getElementById("Layout0").checked = false;
          document.getElementById("Layout1").checked = false;
          document.getElementById("Layout2").checked = true;
          document.getElementById("row0").style.height="100vh";
          document.getElementById("row1").style.height="0vh";
          document.getElementById("col00").style.width="10%";
          document.getElementById("col01").style.width="80%";
          document.getElementById("col02").style.width="10%";
          document.getElementById("DivL0").style.background="#00FF00";
        }
      }
      function MyVibrate()
      {
        if (bCanVibrate==false) return;
        if (bAskVibrate == true)
        {
          bAskVibrate = false;
          alert("Click OK to allow vibration!");
        }
        navigator.vibrate([500, 0]);
        FIFOCMD.Write(0xA0);
        FIFOCMD.Write(0xA0);
        FIFOCMD.Write(0xA0);
        FIFOCMD.Write(0xA1);
        FIFOCMD.Write(0xA1);
        FIFOCMD.Write(0xA1);
        FIFOCMD.Write(0xA0);
        FIFOCMD.Write(0xA0);
        FIFOCMD.Write(0xA0);
      }
      
      var _LOCK_BUTTON = document.querySelector("#lock-landscape-button");
      var _UNLOCK_BUTTON = document.querySelector("#unlock-button");
      var _STATUS = document.querySelector("#orientation-status");
      
      _STATUS.innerHTML = screen.orientation.type + " mode";
      
      document.querySelector("#lock-landscape-button").addEventListener('click',
                                                                         function()
                                                                         {
                                                                           if (bAskVibrate == true)
                                                                           {
                                                                             bAskVibrate = false;
                                                                             alert("Click OK to allow vibration!");
                                                                           }
                                                                           if(document.documentElement.requestFullscreen)
                                                                           {
                                                                             document.querySelector("#container").requestFullscreen();
                                                                           }
                                                                           else if(document.documentElement.webkitRequestFullScreen)
                                                                           {
                                                                             document.querySelector("#container").webkitRequestFullScreen();
                                                                           }
                                                                           screen.orientation.lock("landscape-primary").then
                                                                                                                         (
                                                                                                                           function()
                                                                                                                           {
                                                                                                                             _LOCK_BUTTON.style.display = 'none';
                                                                                                                             _UNLOCK_BUTTON.style.display = 'block';
                                                                                                                           }
                                                                                                                         )
                                                                                                                       .catch
                                                                                                                         (
                                                                                                                           function(error)
                                                                                                                           {
                                                                                                                             alert(error);
                                                                                                                           }
                                                                                                                         );
                                                                           LandscapeMode(true);
                                                                         }
                                                                       );
      document.querySelector("#unlock-button").addEventListener('click',
                                                                 function()
                                                                 {
                                                                   screen.orientation.unlock();
                                                                   _LOCK_BUTTON.style.display = 'block';
                                                                   _UNLOCK_BUTTON.style.display = 'none';
                                                                   iTimerSetLandscapeMode=20;
                                                                 }
                                                               );
      screen.orientation.addEventListener("change",
                                           function()
                                           {
                                             _STATUS.innerHTML = screen.orientation.type + ' mode';
                                           }
                                         );
      document.addEventListener("fullscreenchange",
                                 function()
                                 {
                                   _LOCK_BUTTON.style.display = 'block';
                                   _UNLOCK_BUTTON.style.display = 'none';
                                 }
                               );
      document.addEventListener("webkitfullscreenchange",
                                 function()
                                 {
                                   _LOCK_BUTTON.style.display = 'block';
                                   _UNLOCK_BUTTON.style.display = 'none';
                                 }
                               );
    </script>
  </body>
</html>
