<!doctype html>
<html>
<head>
<title>Simon Says Game - using Device Motion - RJM Programming - August, 2016 - Thanks to http://www.html5rocks.com/en/tutorials/device/orientation/</title>

<style>
.td { text-align: center; }
input[type=button] { background-color: yellow; }
select { background-color: pink; }
</style>

<script type='text/javascript'>
var dmore='none';
var dblock='BLOCK';

if ((navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) || document.URL.indexOf('alert=') != -1) && document.URL.toLowerCase().indexOf('https:') != 0) {
location.href=(document.URL.replace('http:','https:') + '&random=' + Math.floor(Math.random() * 174765654)).replace('.html&','.html?');
}
if ((navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) || document.URL.indexOf('update=') != -1) && document.URL.toLowerCase().indexOf('https:') != 0) {
location.href=(document.URL.replace('http:','https:') + '&random=' + Math.floor(Math.random() * 174765654)).replace('.html&','.html?');
}


// Thanks to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await and
// https://gist.github.com/Ajasra/ddd616505013a4309c0dda8a8ba626cb

async function myfunction() {
console.log('Inside of myfunction');
//alert(0);
if (window.DeviceOrientationEvent && typeof(DeviceOrientationEvent.requestPermission) === "function") {
//alert(4);
const permissionState = await DeviceOrientationEvent.requestPermission().then(response => {
if (response === 'granted') {
if (1 == 2) { alert('GrAnted'); }
//window.addEventListener('deviceorientation', OrientationHandler, true);
dmore=dblock;
dblock='none';
setTimeout(fallow, 2000);
setInterval(tenth,100);
onlo(); //dorh();
onl();
} else { console.log('prompt'); return false; } //} else if (result.state === 'prompt') {
//if (1 == 1) { alert("Need prompt!"); }
//} else {
//if (1 == 1) { alert("Not Supported!"); }
//}
}).catch(console.error);

//if (permissionState === "granted") {
// alert('granted');
//} else {
// alert('denied');
//}
} else if (window.DeviceOrientationEvent) {
//alert(44);
dmore='none';
setTimeout(fallow, 2000);
setInterval(tenth,100);
onlo(); //dorh();
onl();
} else {
dmore='none';
setTimeout(fallow, 2000);
}

if (window.DeviceMotionEvent && typeof(DeviceMotionEvent.requestPermission) === "function") {
//alert(24);
const permissionStateM = await DeviceMotionEvent.requestPermission().then(response => {
if (response === 'granted') {
if (1 == 2) { alert('GranTed'); }
window.addEventListener('devicemotion', function(event) {
lalpha='' + event.rotationRate.alpha;
});
//window.addEventListener('deviceorientation', OrientationHandler, true);
} else { console.log('prompt'); return false; } //} else if (result.state === 'prompt') {
//if (1 == 2) { alert("NeeD prompt!"); }
//} else {
//if (1 == 2) { alert("NoT Supported!"); }
//}
}).catch(console.error);

//if (permissionStateM === "granted") {
// alert('Granted');
//} else {
// alert('Denied');
//}
} else if (window.DeviceMotionEvent) {
//alert(244);
window.addEventListener('devicemotion', function(event) {
lalpha='' + event.rotationRate.alpha;
});
}


}

// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later

// Also point that we don't use async keyword on the function because
// we can simply returns the promise returned by myfunction
function start() {
return myfunction();
}

// Call start
(async() => {
console.log('before start');

await start();

console.log('after start');
})();

var degtorad = Math.PI / 180; // Degree-to-Radian conversion ... thanks to https://www.w3.org/TR/orientation-event/#worked-example


var simonarray1=[];
var simonarray2=[];

var atstart=true;

var initial_yaw=0;
var initial_pitch=0;
var initial_roll=0;
var secselapsed=0;
var irange=0;

// gamma is the left-to-right tilt in degrees, where right is positive
var tiltLeftToRight=0; // = eventData.gamma;

// beta is the front-to-back tilt in degrees, where front is positive
var tiltFrontToBack=0; // = eventData.beta;

// alpha is the compass direction the device is facing in degrees
var brg=0; // = eventData.alpha

var gameon=false;
var instrcnt='0,0,0';

var origsel="<select id='ideas' onchange='gameon=false; selval=this.value; setTimeout(prestartsubgame,1200); '><option value=''>Please select instruction below ...</option></select>";

var score=[100000,100000];
var setselopts=["Full clockwise turn in 4 seconds","Full anticlockwise turn in 4 seconds","Pick up and put down in 3 seconds","Simon's choice in 2 seconds","Simon's choice in 6 seconds","Simon's choice in 8 seconds","Simon's choice in 10 seconds"];
var recording=false;
var numrec=0;
var recordednumrec=-1;
var setnumrec=-1;
var readytoask=true;
var whosego=1;
var askingsimon=1;
var formstring="<form></form>";
var setsel='<select id=selset onchange=hitrecord(this.value,this.options[this.selectedIndex].text)><option value="">Optionally select motion idea below and hit record when ready to start ...</option></select>';
var selih='';
var motionbit='youllneverfindthis';
var cnt=0;
var goes=0;
var cimg='';
var cntpassive=0;
var cntactive=0;
var every20=20000;
var variance=0.0;
var prefixurl='http://www.rjmprogramming.com.au/PHP/HistogramChart/histogram_chart.php?title=Device%20Motion%20Activity&onclick=y&task=Activity&desc=Motion&data=,[~Active~,0],[~Passive~,0]';
var ndt = new Date();
var nutcDate = ndt.toUTCString();


function fallow() {
if (dmore == 'BLOCK') {
document.getElementById('ballow').style.backgroundColor='lightgreen';
document.getElementById('ballow').innerHTML='Start';
} else {
document.getElementById('ballow').style.display=dmore; //'none';
}
}

function analyze() {
variance=0.0;
//alert(simonarray1.length + ',' + simonarray2.length);
for (var ii=0; ii<Math.min(simonarray1.length,simonarray2.length); ii++) {
variance+=Math.abs(simonarray1[ii],simonarray2[ii]);
}
//alert(variance);
simonarray1=[];
simonarray2=[];
return variance;
}

function addtoarray(one,two,three,four,five,six) {
//alert(0);
//alert("simonarray" + whosego + ".push(" + one + ");");
eval("simonarray" + whosego + ".push(" + one + ");");
eval("simonarray" + whosego + ".push(" + two + ");");
eval("simonarray" + whosego + ".push(" + three + ");");
eval("simonarray" + whosego + ".push(" + four + ");");
eval("simonarray" + whosego + ".push(" + five + ");");
eval("simonarray" + whosego + ".push(" + six + ");");
//eval("document.title=simonarray" + whosego + ".length;");
//alert(10);
}

function seccounter() {
if (gameon && score > 0) {
if (next_yaw != Math.round(brg) || next_pitch != Math.round(tiltFrontToBack) || next_roll != Math.round(tiltLeftToRight)) {
next_yaw=Math.round(brg);
next_pitch=Math.round(tiltFrontToBack);
next_roll=Math.round(tiltLeftToRight);
secselapsed++;
}
document.getElementById("secs").innerHTML="" + secselapsed;
score=newscore();
document.getElementById("score").innerHTML="" + score;
setTimeout(seccounter, 1000);
} else {
gameon=false;
}
}

function prestartsubgame() {
var thisv=selval;
startsubgame(thisv);
}

function startsubgame(thisv) {
if (thisv.replace(' ','') == '') {
if (thisv != '') score-=20;
gameon=false;
document.getElementById("doEvent").innerHTML = origsel.replace("</select>", newinstruction() + "</select>");
} else {
goes++;
//document.getElementById("secs").title="Goes:" + goes;
if (document.getElementById("ideas").value.indexOf(', ') != -1) {
document.getElementById("roll_h").innerHTML="Tilt Left/Right [gamma or roll=" + to_roll + "]";
document.getElementById("pitch_h").innerHTML="Tilt Front/Back [beta or pitch=" + to_pitch + "]";
document.getElementById("yaw_h").innerHTML="Bearing [alpha or yaw=" + to_yaw + "]";
} else {
document.getElementById("roll_h").innerHTML="Tilt Left/Right [gamma or roll]";
document.getElementById("pitch_h").innerHTML="Tilt Front/Back [beta or pitch]";
document.getElementById("yaw_h").innerHTML="Bearing [alpha or yaw]";
}
gameon=true;
setTimeout(seccounter, 1000);
}
}

function changeit() {
document.getElementById("ideas").value=instrcnt;
gameon=false;
startsubgame(instrcnt);
}

function newinstruction() {
initial_yaw=Math.round(brg);
initial_pitch=Math.round(tiltFrontToBack);
initial_roll=Math.round(tiltLeftToRight);
next_yaw=initial_yaw;
next_pitch=initial_pitch;
next_roll=initial_roll;
diff_roll=eval(Math.floor(Math.random() * 160) - 80);
diff_pitch=eval(Math.floor(Math.random() * 160) - 80);
diff_yaw=eval(Math.floor(Math.random() * 160) - 80);
to_yaw=eval(initial_yaw + diff_yaw);
to_pitch=eval(initial_pitch + diff_pitch);
to_roll=eval(initial_roll + diff_roll);
instrcnt="" + diff_roll + "," + diff_pitch + "," + diff_yaw;
setTimeout(changeit, 500);
return "<option value='" + instrcnt + "'>Roll " + instrcnt.replace(",", " Pitch ").replace(",", " Yaw ") + "</option>" + "<option value='" + instrcnt.replace(/,/g,', ') + "'>Easier Roll " + instrcnt.replace(",", " Pitch ").replace(",", " Yaw ") + "</option><option value=' '>Give up ... next please</option>";
}

function hitrecord(selv,selh) {
selih=selh;
if (selv != '') {
setnumrec=eval(selv * 10);
if (1 == 1) {
document.getElementById('td' + eval(whosego)).innerHTML=document.getElementById('td' + eval(whosego)).innerHTML.replace('... or ...','... of ...');
document.getElementById('selset').innerHTML='<option value="' + selv + '">' + selih + '</option>';
motionbit='Motion';
document.getElementById('i' + eval(whosego)).focus();
} else {
document.getElementById('i' + eval(whosego)).click();
}
}
}

function tenth() {
if (numrec == setnumrec && recording) {
setnumrec=-1;
document.getElementById('i' + eval(whosego)).click();
} else if (numrec != recordednumrec) {
if (recording) {
numrec++;
}
} else if (recording) {
recording=false;
document.getElementById('td' + eval(whosego)).innerHTML='<br><p>Simon mimic of Simon being analyzed now ... ' + numrec + ' vs ' + recordednumrec + '</p>';
recordednumrec=-1;
score[eval(-1 + whosego)]-=analyze();
document.getElementById('th1').innerHTML='"Simon" Player 1 Score ' + score[0];
document.getElementById('th2').innerHTML='"Simon" Player 2 Score ' + score[1];
numrec=0;
askingsimon=whosego;
readytoask=true;
}
}

function onc(oni) {
if (oni.value.substring(0,4) == 'Record'.substring(0,4)) {
recording=true;
if (askingsimon == whosego) {
oni.value='Stop';
oni.focus();
} else {
//oni.value=oni.value.replace('Record','Will stop in');
document.getElementById('td' + eval(whosego)).innerHTML=document.getElementById('td' + eval(whosego)).innerHTML.replace('button','text').replace('Record','Will stop in');
}
} else if (oni.value == 'Stop') {
recording=false;
if (askingsimon == whosego) document.getElementById('td' + eval(whosego)).innerHTML='<br><p>Simon has said, and done ... Motion recorded</p>'.replace(motionbit,selih);
whosego=eval(3 - whosego);
readytoask=true;
recordednumrec=-1;
setnumrec=-1;
}
}

function askperhaps() {
var ourform=formstring;
if (readytoask) {
readytoask=false;
if (askingsimon == whosego) {
document.getElementById('td' + eval(3 - whosego)).innerHTML='';
ourform=ourform.replace('<form></form>', '<input id=i' + whosego + ' type=button value=Record onclick=onc(this)></input> ... or ... ' + setsel);
} else {
recordednumrec=numrec;
numrec=0;
ourform=ourform.replace('<form></form>', '<input id=i' + whosego + ' type=button value="Record ' + eval(recordednumrec / 10) + ' seconds worth of motion when you are ready to mimic what Simon did" onclick=onc(this)></input>'.replace(motionbit.toLowerCase(),selih));
motionbit='youllneverfindthis';
}
document.getElementById('td' + eval(whosego)).innerHTML=ourform;
document.getElementById('i' + eval(whosego)).focus();
}
setTimeout(askperhaps, 1000);
}

function onl() {
var bbits, bbbits, cval='';
for (var isetsel=0; isetsel<setselopts.length; isetsel++) {
bbits=setselopts[isetsel].split(' second');
if (bbits.length == 2) {
bbbits=bbits[0].split(' ');
cval=bbbits[eval(-1 + bbbits.length)];
setsel=setsel.replace('</select>','<option value="' + cval + '">' + setselopts[isetsel] + '</option></select>');
}
}
if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', deviceMotionHandler, false);
setTimeout(askperhaps, 1000);
} else {
document.getElementById("dmEvent").innerHTML = "Not supported."
if ('temp' == 'temp') setTimeout(askperhaps, 1000);
}
}

function dohistogram() {
document.getElementById('myi').src=prefixurl.replace('&onclick=', encodeURIComponent(' as at ' + nutcDate) + '&onclick=').replace('~Active~,0','~Active~,' + cntactive).replace('~Passive~,0','~Passive~,' + cntpassive);
}

function deviceOrientationHandler(xtiltLeftToRight, xtiltFrontToBack, xbrg) { //tiltLeftToRight, tiltFrontToBack, brg) {
}

function deviceMotionHandler(eventData) {
var info, xyz = "[X, Y, Z]";

cnt++;
ndt = new Date();
nutcDate = ndt.toUTCString();

// Grab the acceleration from the results
acceleration = eventData.accelerationIncludingGravity;
if (Math.pow((acceleration.x * acceleration.x + acceleration.y * acceleration.y + acceleration.z * acceleration.z), 0.5) >= 10) {
cntactive++;
document.getElementById('toopassive').innerHTML = '';
// Grab the acceleration including gravity from the results
info = xyz.replace("X", acceleration.x);
info = info.replace("Y", acceleration.y);
info = info.replace("Z", acceleration.z);

if (recording) addtoarray(acceleration.x, acceleration.y, acceleration.z, tiltLeftToRight, tiltFrontToBack, brg);

document.getElementById("moAccelGrav").innerHTML = info + " ... " + Math.pow((acceleration.x * acceleration.x + acceleration.y * acceleration.y + acceleration.z * acceleration.z), 0.5) + ' ... ' + nutcDate;

var acceleration = eventData.acceleration;
info = xyz.replace("X", acceleration.x);
info = info.replace("Y", acceleration.y);
info = info.replace("Z", acceleration.z);
document.getElementById("moAccel").innerHTML = info + " ... " + Math.pow((acceleration.x * acceleration.x + acceleration.y * acceleration.y + acceleration.z * acceleration.z), 0.5);

// Grab the rotation rate from the results
var rotation = eventData.rotationRate;
info = xyz.replace("X", rotation.alpha);
info = info.replace("Y", rotation.beta);
info = info.replace("Z", rotation.gamma);
document.getElementById("moRotation").innerHTML = info + " ... " + Math.pow((rotation.alpha * rotation.alpha + rotation.beta * rotation.beta + rotation.gamma * rotation.gamma), 0.5);

// // Grab the refresh interval from the results
info = eventData.interval;
document.getElementById("moInterval").innerHTML = info;
document.getElementById('toopassive').innerHTML = ' ' + eval((cntactive * 100.0 / cnt)) + '%';
} else {
cntpassive++;
document.getElementById('toopassive').innerHTML = ' ... ' + nutcDate + ' ... ' + eval((cntactive * 100.0 / cnt)) + '% ... sorry, your device is too still for scoring right now at this game';
}
document.getElementById('imeter').max=cnt;
document.getElementById('imeter').value=cntactive;
document.getElementById('imeter').innerHTML="" + cntactive + " out of " + cnt;
//if (every20 > 0) {
// setInterval(dohistogram, 20000);
// every20=0;
//}
}


function onlo() {
if (window.DeviceOrientationEvent) {
document.getElementById("doEvent").innerHTML = "DeviceOrientation";
// Listen for the deviceorientation event and handle the raw data
window.addEventListener('deviceorientation', function(eventData) {
// gamma is the left-to-right tilt in degrees, where right is positive
tiltLeftToRight = eventData.gamma;

// beta is the front-to-back tilt in degrees, where front is positive
tiltFrontToBack = eventData.beta;

// alpha is the compass direction the device is facing in degrees
brg = eventData.alpha


if (atstart) {
initial_yaw=Math.round(brg);
initial_pitch=Math.round(tiltFrontToBack);
initial_roll=Math.round(tiltLeftToRight);
//alert(initial_yaw + ',' + initial_pitch + ',' + initial_roll);
}

try { document.getElementById('compass_needle').style.webkitTransform = ("rotate(" + Math.round(brg) + "deg)"); } catch(e10) { }
try { document.getElementById('compass_needle').style.MozTransform = ("rotate(" + Math.round(brg) + "deg)"); } catch(e1000) { }
try { document.getElementById('compass_needle').style.msTransform = ("rotate(" + Math.round(brg) + "deg)"); } catch(e100) { }
try { document.getElementById('compass_needle').style.OTransform = ("rotate(" + Math.round(brg) + "deg)"); } catch(e10000) { }
try { document.getElementById('compass_needle').style.transform = ("rotate(" + Math.round(brg) + "deg)"); } catch(e1) { }

atstart=false;

// call our orientation event handler
deviceOrientationHandler(tiltLeftToRight, tiltFrontToBack, brg);
}, false);
} else {
document.getElementById("doEvent").innerHTML = "Not supported."
// temp two below
//document.getElementById("event_supported").innerHTML = "<a href='" + document.URL + "' title='New Game'>Score</a>: <span id='score'>" + score + "</span> / Seconds Alive: <span title='Goes:0' id='secs'>" + secselapsed + "</span>";
document.getElementById("doEvent").innerHTML = origsel.replace("</select>", newinstruction() + "</select>");
}
}


</script>
</head>
<body onload="if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) { setInterval(tenth,100); onlo(); onl(); }">
<button id=ballow style='display:block;background-color:yellow;' onclick='start();'>Allow</button>

<div class="main" style='display: none;'>
<table>
<tr>
<td rowspan=5><img id='compass_needle' height="150px;" src="./compass-needle.png" title="Thanks to http://marylandlearninglinks.org/wp-content/themes/learning-links/img/compass-needle.png"></img></td>
<td><h2>Device Orientation</h2></td>
<td><form method='GET' action='./yaw_etc.html'><input type='text' value='geolocation_ipad_wifialways.jpg' id='image' name='image' style='width:180px;'></input><br><input type='submit' value='Use' style='background-color:yellow;'></input><input name='game' type='submit' value='Game' style='background-color:lightgreen;'></input><br><input onclick=" document.getElementById('image').value='http://ndl.mgccw.com/mu3/game/000/946/622/sss/48fe14ac9ff54f17a802ce89f8272775_small.png'; " style="background-color:lightblue;" name='viamobogenie_game' type='submit' value='Game via Cockpit Image' title='Thanks to mobogenie.com at http://ndl.mgccw.com/mu3/game/000/946/622/sss/48fe14ac9ff54f17a802ce89f8272775_small.png'></input><input style='width:1px;margin-left:-9000px;' type='text' id='junk' type='text' value=''></input></form></td>
</tr>
<tr>
<td id='event_supported'>Event Supported</td>
<td id="doEvent"></td>
</tr>
<tr>
<td id='roll_h'>Tilt Left/Right [gamma or roll]</td>
<td id="doTiltLeftToRight"></td>
</tr>
<tr>
<td id='pitch_h'>Tilt Front/Back [beta or pitch]</td>
<td id="doTiltFrontToBack"></td>
</tr>
<tr>
<td id='yaw_h'>Bearing [alpha or yaw]</td>
<td id="doBearing"></td>
</tr>
</table>
<div class="container" style="perspective: 300;">
<img src="geolocation_ipad_wifialways.jpg" id="imageId" width="50%" onerror=" this.src='geolocation_ipad_wifialways.jpg'; document.getElementById('image').value='geolocation_ipad_wifialways.jpg'; ">
</div>
<h2>Device Motion <div id='toopassive'></div></h2><br> Activity meter: <progress id='imeter' value=0 max=0>0 out of 0</progress>
<table>
<tr>
<td>Event Supported</td>
<td id="dmEvent"></td>
</tr>
<tr>
<td>acceleration</td>
<td id="moAccel"></td>
</tr>
<tr>
<td>accelerationIncludingGravity</td>
<td id="moAccelGrav"></td>
</tr>
<tr>
<td>rotationRate</td>
<td id="moRotation"></td>
</tr>
<tr>
<td>interval</td>
<td id="moInterval"></td>
</tr>
</table>
<!--iframe width=900 height=600 id='myi' src='http://www.rjmprogramming.com.au/PHP/HistogramChart/histogram_chart.php?title=Device%20Motion%20Activity&onclick=y&task=Activity&desc=Motion&data=,[~Active~,0],[~Passive~,0]' title='Device Motion Activity'></iframe-->
</div>

<table class='td' border=7 style='width:100%;' cellspacing=20 cellpadding=20>
<tr><th id='th1' class='td'>"Simon" Player 1 Score 100000</th><th id='th2' class='td'>"Simon" Player 2 Score 100000</th></tr>
<tr><td id='td1' class='td'></td><td id='td2' class='td'></td></tr>
</table>

</body>
</html>