(function () {
function orderByThreshold(a,b) {
return b.threshold - a.threshold;
}
function createFakeEvent(evtype,remote,diff,ind) {
var evObj = document.createEvent('Events');
evObj.initEvent( evtype, false, true );
evObj.remoteData = remote;
evObj.difference = diff;
evObj.detail = ind;
wiievents.dispatchEvent(evObj);
}
function createFakeKeyEvent(evtype,remote,keyCode,ind) {
var evObj = document.createEvent('UIEvents');
evObj.initUIEvent( evtype, false, false, window, ind );
evObj.remoteData = remote;
evObj.keyCode = keyCode;
wiievents.dispatchEvent(evObj);
}
function pollForChanges() {
var tempValues = {}, tempRemote, tempkeys, difference, absdifference, n, numlist;
for( var i = 0; i < maxRemotes; i++ ) {
if( remotesToCheck[i] && ( tempRemote = wiiremote.update(i) ).isEnabled ) {
tempValues.roll = Math.atan2(tempRemote.dpdRollY,tempRemote.dpdRollX);
tempValues.distance = tempRemote.dpdDistance;
tempValues.vert = tempRemote.dpdY;
tempValues.horiz = tempRemote.dpdX;
if( evToCheck.rollEvents.numeric.length ) {
difference = tempValues.roll - remotedatastore[i].roll;
absdifference = Math.abs(difference);
if( absdifference > Math.PI ) {
absdifference = ( 2 * Math.PI ) - absdifference;
difference = ( ( ( difference > 0 ) ? -2 : 2 ) * Math.PI ) + difference;
}
numlist = evToCheck.rollEvents.numeric;
for( n = 0; n < numlist.length; n++ ) {
if( absdifference >= numlist[n].threshold && !createFakeEvent(numlist[n].eventname,tempRemote,difference,i) ) {
break;
}
}
}
if( evToCheck.distanceEvents.numeric.length ) {
difference = tempValues.distance - remotedatastore[i].distance;
absdifference = Math.abs(difference);
numlist = evToCheck.distanceEvents.numeric;
for( n = 0; n < numlist.length; n++ ) {
if( absdifference >= numlist[n].threshold && !createFakeEvent(numlist[n].eventname,tempRemote,difference,i) ) {
break;
}
}
}
if( evToCheck.movehorizEvents.numeric.length ) {
difference = tempValues.horiz - remotedatastore[i].horiz;
absdifference = Math.abs(difference);
numlist = evToCheck.movehorizEvents.numeric;
for( n = 0; n < numlist.length; n++ ) {
if( absdifference >= numlist[n].threshold && !createFakeEvent(numlist[n].eventname,tempRemote,difference,i) ) {
break;
}
}
}
if( evToCheck.movevertEvents.numeric.length ) {
difference = tempValues.vert - remotedatastore[i].vert;
absdifference = Math.abs(difference);
numlist = evToCheck.movevertEvents.numeric;
for( n = 0; n < numlist.length; n++ ) {
if( absdifference >= numlist[n].threshold && !createFakeEvent(numlist[n].eventname,tempRemote,difference,i) ) {
break;
}
}
}
if( evToCheck.moveEvents.numeric.length ) {
difference = Math.sqrt( Math.pow( tempValues.horiz - remotedatastore[i].horiz, 2 ) + Math.pow( tempValues.vert - remotedatastore[i].vert, 2 ) );
absdifference = Math.abs(difference);
numlist = evToCheck.moveEvents.numeric;
for( n = 0; n < numlist.length; n++ ) {
if( absdifference >= numlist[n].threshold && !createFakeEvent(numlist[n].eventname,tempRemote,difference,i) ) {
break;
}
}
}
remotedatastore[i].roll = tempValues.roll;
remotedatastore[i].distance = tempValues.distance;
remotedatastore[i].vert = tempValues.vert;
remotedatastore[i].horiz = tempValues.horiz;
for( n = 0; n < keyCodes.length; n++ ) {
tempkeys = tempRemote.hold & keyCodes[n];
if( tempkeys && !remotedatastore[i].keysdown[keyCodes[n]] ) {
remotedatastore[i].keysdown[keyCodes[n]] = true;
createFakeKeyEvent('keydown',tempRemote,keyCodes[n],i)
createFakeKeyEvent('keypress',tempRemote,keyCodes[n],i)
} else if( !tempkeys && remotedatastore[i].keysdown[keyCodes[n]] ) {
remotedatastore[i].keysdown[keyCodes[n]] = false;
createFakeKeyEvent('keyup',tempRemote,keyCodes[n],i)
} else if( tempkeys ) {
createFakeKeyEvent('keypress',tempRemote,keyCodes[n],i)
}
}
}
}
}
if( !window.opera || !opera.wiiremote ) { return; }
var maxRemotes = 4;
var pollingInterval;
var remotesToCheck = [];
var remotedatastore = [];
for( var i = 0; i < maxRemotes; i++ ) {
remotedatastore[i] = { roll: 0, distance: 2.5, vert: -1, horiz: -1, keysdown: {} };
}
var evToCheck = { rollEvents: {numeric:[]}, distanceEvents: {numeric:[]}, moveEvents: {numeric:[]}, movevertEvents: {numeric:[]}, movehorizEvents: {numeric:[]} };
var eventPattern = /wii(move(vert|horiz)?|roll|distance)-([\d\.]+)/;
var keyCodes = [1,2,4,8,16,256,512,1024,2048,4096,8192,16384];
var wiiremote = opera.wiiremote;
var wiievents = opera.wiievents = document.createElement('wiievents');
wiievents.realAddEventListener = wiievents.addEventListener;
wiievents.realRemoveEventListener = wiievents.addEventListener;
wiievents.addEventListener = function (eventtype,handler,phase) {
var captures;
if( typeof(eventtype) == 'string' && ( captures = eventtype.match(eventPattern) ) ) {
var eventbase = evToCheck[captures[1]+'Events'], thresh = captures[3];
if( !eventbase[eventtype] ) {
eventbase.numeric[eventbase.numeric.length] = eventbase[eventtype] = { threshold: thresh * 1, eventname: eventtype, count: 0, currentindex: 0 };
}
eventbase[eventtype].count++;
eventbase.numeric.sort(orderByThreshold);
for( var i = 0; i < eventbase.numeric.length; i++ ) {
eventbase.numeric[i].currentindex = i;
}
}
wiievents.realAddEventListener(eventtype,handler,phase);
};
wiievents.removeEventListener = function (eventtype,handler,phase) {
var captures;
if( typeof(eventtype) == 'string' && ( captures = eventtype.match(eventPattern) ) ) {
var eventbase = evToCheck[captures[1]+'Events'], thresh = captures[3];
if( !eventbase[eventtype] ) { return; }
eventbase[eventtype].count--;
if( !eventbase[eventtype].count ) {
eventbase.numeric.splice(eventbase[eventtype].currentindex,1);
for( var i = eventbase[eventtype].currentindex; i < eventbase.numeric.length; i++ ) {
eventbase.numeric[i].currentindex = i;
}
delete eventbase[eventtype];
}
}
wiievents.realAddEventListener(eventtype,handler,phase);
};
wiievents.setPolling = function (interval) {
if( pollingInterval ) { clearInterval(pollingInterval); }
if( interval ) {
pollForChanges();
pollingInterval = setInterval(pollForChanges,interval);
}
};
wiievents.monitorRemote = function (remoteNum,enable) {
remotesToCheck[remoteNum] = enable;
};
})();