/*
--------------------------------------------------------------------------------
key input
--------------------------------------------------------------------------------
functions for keyboard input with polling for clean continuous repeats
check the keyPressed array to see if a key is currently down
*/

var keyPressed;


function setupKeyInput() {
	// set up key handlers
	document.addEventListener("keydown", keyPress, false);
	document.addEventListener("keyup", keyRelease, false);
	document.addEventListener("blur", blurHandler);
	
	keyPressed = new Array(10000);
	for (var i = 0; i < 10000; i ++)
		keyPressed[i] = false;
}

		
// tweak the key state array on press / release
// supposedly this is unreliable
// perhaps there's a better way to do polling?
function keyPress(event) {
	var keycode = event.keyCode;

	var keyWasPressed = keyPressed[keycode];
	keyPressed[keycode] = true;
	console.log(keycode + " pressed");
	
	// this is project specific- let the project know when a key is pressed
	if (keyWasPressed == false)
		notifyKeyPress(event.keyCode);
}


function keyRelease(event) {
	var keycode = event.keyCode;
	keyPressed[keycode] = false;
	//console.log(keycode + " released");
	notifyKeyRelease(event.keyCode);
}


function blurHandler() {
	//console.log("blur event detected");
	for (var i = 0; i < 10000; i ++)
		keyPressed[i] = false;
}


/*
--------------------------------------------------------------------------------
input source
--------------------------------------------------------------------------------
an object for abstracting input. project specific. put controller / keyboard / autonomous inputs into an inputsource, and objects can watch the inputsource instead of checking input directly.
*/

// for containing controller / keyboard input in a tidy way
// characters who use human input can check this without doing fiddly key checks
var commandCount = 8;
function InputSource() {
	this.inputX0 = 0.0; // two axes of input by default
	this.inputY0 = 0.0;
	this.inputX1 = 0.0; // two axes of input by default
	this.inputY1 = 0.0;
	this.command = new Array(commandCount); // an array of booleans for various commands

	// mapping- let the input source manage itself instead of doing it externally
	// keyboard control defaults (arrows)
	this.left0 = 37;
	this.right0 = 39;
	this.up0 = 38;
	this.down0 = 40;
	this.left1 = 37;
	this.right1 = 39;
	this.up1 = 38;
	this.down1 = 40;
	this.commandMapping = new Array(commandCount);
	// experimental addition: independent press + hold callbacks per function?
	this.pressCallback = [];
	this.holdCallback = [];
	this.releaseCallback = [];
	for (var i = 0; i < commandCount; i ++) {
		this.command[i] = false;
		this.commandMapping[i] = 999;
		// experimental
		this.pressCallback[i] = function() {console.log("press callback " + i + " run");};
		this.holdCallback[i] = function() {console.log("hold callback " + i + " run");};
		this.releaseCallback[i] = function() {console.log("release callback " + i + " run");};
	}
	
	
	this.update = function() {
		// keyboard
		// directional input (key input is aliased to -1 / 0 / 1
		// the input for this game has two directional inputs per player
		this.inputX0 = 0;
		if (keyPressed[this.left0])
			this.inputX0 -= 1;
		if (keyPressed[this.right0])
			this.inputX0 += 1;
		this.inputY0 = 0;
		if (keyPressed[this.up0])
			this.inputY0 -= 1;
		if (keyPressed[this.down0])
			this.inputY0 += 1;
		this.inputX1 = 0;
		if (keyPressed[this.left1])
			this.inputX1 -= 1;
		if (keyPressed[this.right1])
			this.inputX1 += 1;
		this.inputY1 = 0;
		if (keyPressed[this.up1])
			this.inputY1 -= 1;
		if (keyPressed[this.down1])
			this.inputY1 += 1;

		// buttons
		for (var i = 0; i < commandCount; i ++) {
			var old = this.command[i];
			var pressed = this.command[i] = keyPressed[this.commandMapping[i]];
			// press + hold callbacks
			if ((old == false) && (pressed == true))
				if (this.pressCallback[i])
					this.pressCallback[i]();
			// do we want to call this first frame?
			// if so, use if instead of else
			if ((old == true) && (pressed == true))
				if (this.holdCallback[i])
					this.holdCallback[i]();
			
			if ((old == true) && (pressed == false))
				if (this.releaseCallback[i])
					this.releaseCallback[i]();
		}
		
		// add: gamepad checks
		// directional input here could be floating point -1 to 1
	};
}