var Platform = require('./Platform');
var Log = require('./Log');
var merge = require('merge');
var requestAnimFrameFps = 60;
if (Platform.isBrowser) {
window.requestAnimFrame = function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) {
window.setTimeout(callback, 1000 / requestAnimFrameFps);
};
}();
}
var eventListeners = [];
function fireEvent(eventType, event) {
for (var i = 0; i < eventListeners.length; i++) {
if (eventListeners[i].eventType == eventType) {
eventListeners[i].handler(event);
}
}
}
function registerEvents(canvas, win) {
makeMouseDownHandler(canvas, win);
makeMouseUpHandler(canvas, win);
makeMouseDraggedHandler(canvas, win);
makeMouseMovedHandler(canvas, win);
makeScrollWheelHandler(canvas, win);
makeTouchDownHandler(canvas, win);
makeTouchUpHandler(canvas, win);
makeTouchMoveHandler(canvas, win);
makeKeyDownHandler(canvas, win);
makeWindowResizeHandler(canvas, win);
}
function makeMouseDownHandler(canvas, win) {
canvas.addEventListener('mousedown', function(e) {
fireEvent('leftMouseDown', {
x: (e.offsetX || e.layerX || e.clientX - e.target.offsetLeft) * win.settings.highdpi,
y: (e.offsetY || e.layerY || e.clientY - e.target.offsetTop) * win.settings.highdpi,
option: e.altKey,
shift: e.shiftKey,
control: e.ctrlKey
});
});
}
function makeMouseUpHandler(canvas, win) {
canvas.addEventListener('mouseup', function(e) {
fireEvent('leftMouseUp', {
x: (e.offsetX || e.layerX || e.clientX - e.target.offsetLeft) * win.settings.highdpi,
y: (e.offsetY || e.layerY || e.clientY - e.target.offsetTop) * win.settings.highdpi,
option: e.altKey,
shift: e.shiftKey,
control: e.ctrlKey
});
});
}
function makeMouseDraggedHandler(canvas, win) {
var down = false;
var px = 0;
var py = 0;
canvas.addEventListener('mousedown', function(e) {
down = true;
px = (e.offsetX || e.layerX || e.clientX - e.target.offsetLeft) * win.settings.highdpi;
py = (e.offsetY || e.layerY || e.clientY - e.target.offsetTop) * win.settings.highdpi;
});
canvas.addEventListener('mouseup', function(e) {
down = false;
});
canvas.addEventListener('mousemove', function(e) {
if (down) {
var x = (e.offsetX || e.layerX || e.clientX - e.target.offsetLeft) * win.settings.highdpi;
var y = (e.offsetY || e.layerY || e.clientY - e.target.offsetTop) * win.settings.highdpi;
fireEvent('mouseDragged', {
x: x,
y: y,
dx: x - px,
dy: y - py,
option: e.altKey,
shift: e.shiftKey,
control: e.ctrlKey
});
px = x;
py = y;
}
});
}
function makeMouseMovedHandler(canvas, win) {
canvas.addEventListener('mousemove', function(e) {
fireEvent('mouseMoved', {
x: (e.offsetX || e.layerX || e.clientX - e.target.offsetLeft) * win.settings.highdpi,
y: (e.offsetY || e.layerY || e.clientY - e.target.offsetTop) * win.settings.highdpi,
option: e.altKey,
shift: e.shiftKey,
control: e.ctrlKey
});
});
}
function makeScrollWheelHandler(canvas, win) {
var mousewheelevt = /Firefox/i.test(navigator.userAgent) ? 'DOMMouseScroll' : 'mousewheel';
document.addEventListener(mousewheelevt, function(e) {
fireEvent('scrollWheel', {
x: (e.offsetX || e.layerX) * win.settings.highdpi,
y: (e.offsetY || e.layerY) * win.settings.highdpi,
dy: e.wheelDelta / 10 || -e.detail / 10,
option: e.altKey,
shift: e.shiftKey,
control: e.ctrlKey
});
});
}
var lastTouch = null;
function makeTouchDownHandler(canvas, win) {
canvas.addEventListener('touchstart', function(e) {
lastTouch = {
clientX: e.touches[0].clientX * win.settings.highdpi,
clientY: e.touches[0].clientY * win.settings.highdpi
};
var touches = Array.prototype.slice.call(this, e.touches).map(function(touch) {
touch.x = touch.clientX * win.settings.highdpi;
touch.y = touch.clientY * win.settings.highdpi;
return touch;
});
fireEvent('leftMouseDown', {
x: e.touches[0].clientX * win.settings.highdpi,
y: e.touches[0].clientY * win.settings.highdpi,
option: false,
shift: false,
control: false,
touches: touches
});
});
}
function makeTouchUpHandler(canvas, win) {
canvas.addEventListener('touchend', function(e) {
var touches = Array.prototype.slice.call(this, e.touches).map(function(touch) {
touch.x = touch.clientX * win.settings.highdpi;
touch.y = touch.clientY * win.settings.highdpi;
return touch;
});
fireEvent('leftMouseUp', {
x: lastTouch ? lastTouch.clientX : 0,
y: lastTouch ? lastTouch.clientY : 0,
option: false,
shift: false,
control: false,
touches: touches
});
lastTouch = null;
});
}
function makeTouchMoveHandler(canvas, win) {
canvas.addEventListener('touchmove', function(e) {
e.preventDefault();
lastTouch = {
clientX: e.touches[0].clientX * win.settings.highdpi,
clientY: e.touches[0].clientY * win.settings.highdpi
};
var touches = Array.prototype.slice.call(this, e.touches).map(function(touch) {
touch.x = touch.clientX * win.settings.highdpi;
touch.y = touch.clientY * win.settings.highdpi;
return touch;
});
fireEvent('mouseDragged', {
x: e.touches[0].clientX * win.settings.highdpi,
y: e.touches[0].clientY * win.settings.highdpi,
option: false,
shift: false,
control: false,
touches: touches
});
return false;
});
}
function makeKeyDownHandler(canvas, win) {
var timeout = 0;
window.addEventListener('keydown', function(e) {
timeout = setTimeout(function() {
fireEvent('keyDown', {
str: '',
keyCode: e.keyCode,
option: e.altKey,
shift: e.shiftKey,
control: e.ctrlKey
}, 1);
});
});
window.addEventListener('keypress', function(e) {
if (timeout) {
clearTimeout(timeout);
timeout = 0;
}
fireEvent('keyDown', {
str: String.fromCharCode(e.charCode),
keyCode: e.keyCode,
option: e.altKey,
shift: e.shiftKey,
control: e.ctrlKey
});
});
}
function makeWindowResizeHandler(canvas, win) {
window.addEventListener('resize', function(e) {
var width = window.innerWidth;
var height = window.innerHeight;
if (win.settings.fullscreen) {
canvas.width = width * win.settings.highdpi;
canvas.height = height * win.settings.highdpi;
canvas.style.width = width + 'px';
canvas.style.height = height + 'px';
win.width = width * win.settings.highdpi;
win.height = height * win.settings.highdpi;
}
fireEvent('resize', { width: width, height: height });
});
}
function simpleWindow(obj) {
var canvas = obj.settings.canvas;
if (obj.settings.fullscreen) {
obj.settings.width = window.innerWidth;
obj.settings.height = window.innerHeight;
}
if (!canvas) {
canvas = document.getElementById('canvas');
}
else if (obj.settings.width && obj.settings.height) {
canvas.width = obj.settings.width;
canvas.height = obj.settings.height;
}
else {
obj.settings.width = canvas.width;
obj.settings.height = canvas.height;
}
if (!canvas) {
canvas = document.createElement('canvas');
canvas.width = obj.settings.width;
canvas.height = obj.settings.height;
}
if (window.devicePixelRatio == 2) {
if (obj.settings.highdpi == 2) {
canvas.width = obj.settings.width * 2;
canvas.height = obj.settings.height * 2;
canvas.style.width = obj.settings.width + 'px';
canvas.style.height = obj.settings.height + 'px';
obj.settings.width = canvas.width;
obj.settings.height = canvas.height;
}
}
else {
obj.settings.highdpi = 1;
}
if (obj.settings.multisample) {
canvas.msaaEnabled = true;
canvas.msaaSamples = 2;
}
obj.width = obj.settings.width;
obj.height = obj.settings.height;
obj.canvas = canvas;
canvas.style.backgroundColor = '#000000';
function go() {
if (obj.stencil === undefined)
obj.stencil = false;
if (obj.settings.fullscreen) {
document.body.style.margin = '0';
document.body.style.padding = '0';
document.body.style.overflow = 'hidden';
}
var gl = null;
var ctx = null;
if (obj.settings.type == '3d') {
try {
gl = canvas.getContext('experimental-webgl', {
antialias: true,
stencil: obj.settings.stencil,
premultipliedAlpha : obj.settings.premultipliedAlpha,
preserveDrawingBuffer: obj.settings.preserveDrawingBuffer
});
}
catch (err) {
Log.error(err.message);
return;
}
if (gl === null) {
throw 'No WebGL context is available.';
}
}else if (obj.settings.type == '2d') {
ctx = canvas.getContext('2d');
}
obj.framerate = function(fps) {
requestAnimFrameFps = fps;
};
obj.on = function(eventType, handler) {
eventListeners.push({
eventType: eventType,
handler: handler
});
};
registerEvents(canvas, obj);
obj.dispose = function() {
obj.__disposed = true;
};
obj.gl = gl;
obj.ctx = ctx;
obj.init();
function drawloop() {
if (!obj.__disposed) {
obj.draw();
requestAnimFrame(drawloop);
}
}
requestAnimFrame(drawloop);
}
if (!canvas.parentNode) {
if (document.body) {
document.body.appendChild(canvas);
go();
}else {
window.addEventListener('load', function() {
document.body.appendChild(canvas);
go();
}, false);
}
}
else {
go();
}
return obj;
}
var BrowserWindow = { simpleWindow: simpleWindow };
module.exports = BrowserWindow;