"use strict";

//var DEFINE_CONTROLS_KEYCODES = {
//	"up" : 38,
//	"down" : 40,
//	"left" : 37,
//	"right" : 39,
//	"A" : 90, //z
//	"B" : 88, //x
//};
//var DEFINE_CONTROLS_KEYS = {
//	"up" : "ArrowUp",
//	"down" : "ArrowDown",
//	"left" : "ArrowLeft",
//	"right" : "ArrowRight",
//	"A" : "z",
//	"B" : "x",	
//};

var DEFINE_CONTROLS_KEYCODES = {
	"up": "up",
	"down": "down",
	"left": "left",
	"right": "right",
	"A": "A",
	"B": "B",
};

// TODO: rethink this later.  For now, hack in controls I can use on tablet.
var _CONTROLS_QUICKMAP = {
	38: DEFINE_CONTROLS_KEYCODES.up, // ArrowUp
	40: DEFINE_CONTROLS_KEYCODES.down, // ArrowDown
	37: DEFINE_CONTROLS_KEYCODES.left, // ArrowLeft
	39: DEFINE_CONTROLS_KEYCODES.right, // ArrowRight
	90: DEFINE_CONTROLS_KEYCODES.A, // z
	88: DEFINE_CONTROLS_KEYCODES.B, // x

	87: DEFINE_CONTROLS_KEYCODES.up, // w
	83: DEFINE_CONTROLS_KEYCODES.down, // s
	65: DEFINE_CONTROLS_KEYCODES.left, // a
	68: DEFINE_CONTROLS_KEYCODES.right, // d
	188: DEFINE_CONTROLS_KEYCODES.A, // ,
	190: DEFINE_CONTROLS_KEYCODES.B, // .
};
//for (var code in DEFINE_CONTROLS_KEYCODES){
//	_CONTROLS_QUICKMAP[DEFINE_CONTROLS_KEYCODES[code]] = code;
//}

var _CONTROLS_QUICKKEY = {
	"ArrowUp": DEFINE_CONTROLS_KEYCODES.up,
	"ArrowDown": DEFINE_CONTROLS_KEYCODES.down,
	"ArrowLeft": DEFINE_CONTROLS_KEYCODES.left,
	"ArrowRight": DEFINE_CONTROLS_KEYCODES.right,
	"z": DEFINE_CONTROLS_KEYCODES.A,
	"x": DEFINE_CONTROLS_KEYCODES.B,

	"w": DEFINE_CONTROLS_KEYCODES.up,
	"a": DEFINE_CONTROLS_KEYCODES.down,
	"s": DEFINE_CONTROLS_KEYCODES.left,
	"d": DEFINE_CONTROLS_KEYCODES.right,
	",": DEFINE_CONTROLS_KEYCODES.A,
	".": DEFINE_CONTROLS_KEYCODES.B,
};

var _CODES_NODEFAULT = {
	38: true, // ArrowUp
	40: true, // ArrowDown
	37: true, // ArrowLeft
	39: true, // ArrowRight
};
var _KEYS_NODEFAULT = {
	"ArrowUp": DEFINE_CONTROLS_KEYCODES.up,
	"ArrowDown": DEFINE_CONTROLS_KEYCODES.down,
	"ArrowLeft": DEFINE_CONTROLS_KEYCODES.left,
	"ArrowRight": DEFINE_CONTROLS_KEYCODES.right,
};


var Controls = function(){
	this.held = {
		"up" : false,
		"down" : false,
		"left" : false,
		"right" : false,
		"A" : false,
		"B" : false
	};

	this.pressed = {
		"up" : false,
		"down" : false,
		"left" : false,
		"right" : false,
		"A" : false,
		"B" : false
	};

	this.released = {
		"up" : false,
		"down" : false,
		"left" : false,
		"right" : false,
		"A" : false,
		"B" : false
	};

	this.depeat = {};

	this._heap = {};
};
	Controls.prototype.onKeyDown = function(event,controls){
		if (this.depeat[event.key] || (!event.key && this.depeat[event.keyCode])) return; // prevent every-frame autorepeat keyspamming from keyboards
		if (event.key) this.depeat[event.key] = true;
		else  this.depeat[event.keyCode] = true;

		if (document.activeElement.id==="diary"){
			return;
		}

		//DEBUG PLAYTEST
		//if (event.keyCode==187){ // +
		//	this._heap.completion=0;
		//	for (var i=0; i<GLOBAL_DIARY.narrative.length; i++){
		//		if (GLOBAL_DIARY.narrative[i].chaptergory!="DIARIES") this._heap.completion++;
		//	}
		//	this._heap.completionStr = "Completion Index: "+this._heap.completion;
		//	this._heap.timeStr = "Play Time This Session: "+GLOBAL_TIME_HOURS+"h "+GLOBAL_TIME_MINUTES+"m "+GLOBAL_TIME_SECONDS+"s "+GLOBAL_TIME_FRAMES+"f";
		//	alert(this._heap.completionStr+"\n"+this._heap.timeStr);
		//}


		if (event.key=="`" || (!event.key && event.keyCode==192)){ // `
			Controls_ToggleOSC();
		}
		//if (event.keyCode==122 || event.keyCode==70){ // F11 || f as in cmd-f
		// fullscreen keystroke is dropped half the time anyway by depeat & skipped keyup; 
		// let's not be clever about trying to catch it.  Mac users can press it again.
		if (event.key=="f" || (!event.key && event.keyCode==70)){
			SDS_ToggleFullscreen();
		}
		
		this._heap.key = _CONTROLS_QUICKKEY[event.key] || (!event.key && _CONTROLS_QUICKMAP[event.keyCode]);
		if (typeof(this._heap.key) != 'undefined'){
			this.press(controls,this._heap.key);
		}
		//else{
		//	alert(event.keyCode);
		//}
		//console.log(event.keyCode);

		if (_KEYS_NODEFAULT[event.key] || (!event.key && _CODES_NODEFAULT[event.keyCode])){
			event.preventDefault();
		}
	};
	Controls.prototype.press = function(controls,button){
		if (!controls.held[button]){
			controls.pressed[button] = true;
		}
		controls.held[button] = true;
	};

	Controls.prototype.onKeyUp = function(event,controls){
		if (event.key) this.depeat[event.key] = false;
		else this.depeat[event.keyCode] = false;
		if (document.activeElement && document.activeElement.id==="diary"){
			return;
		}
		event.preventDefault();
		this._heap.key = _CONTROLS_QUICKKEY[event.key] || (!event.key && _CONTROLS_QUICKMAP[event.keyCode]);
		if (typeof(this._heap.key) != 'undefined'){
			this.unpress(controls,this._heap.key);
		}
	};
	Controls.prototype.unpress = function(controls,button){
		if (controls.held[button]){
			controls.released[button] = true;
		}
		controls.held[button] = false;
	};

	Controls.prototype.setInputs = function(inputs){
		for (var i in inputs){
			// intentional lack of undefined checks- undefined/null will evaluate false
			// so if we need custom inputs for certain controllables, they'll work implicitly
			this.pressed[i] = inputs[i] && !this.held[i];
			this.released[i] = !inputs[i] && this.held[i];
			this.held[i] = inputs[i];
		}
	};

	// call once per frame to flush any recent presses/releases
	Controls.prototype.Update = function(){
		for (this._heap.code in this.held){
			this.pressed[this._heap.code]=false;
			this.released[this._heap.code]=false;
		}
	};

var GLOBAL_CONTROLS = new Controls();
document.addEventListener('keydown', function(event){GLOBAL_CONTROLS.onKeyDown(event,GLOBAL_CONTROLS);});
document.addEventListener('keyup', function(event){GLOBAL_CONTROLS.onKeyUp(event,GLOBAL_CONTROLS);});



var DEFINE_CONTROLS_SOFTBUTTONS = [
	"btn_left",
	"btn_right",
	"btn_up",
	"btn_down",
	"btn_A",
	"btn_B"
];
var Controls_button_elems = {};
window.addEventListener("load",function(e){
	for (var i=0; i<DEFINE_CONTROLS_SOFTBUTTONS.length; i++){
		var btn = DEFINE_CONTROLS_SOFTBUTTONS[i];
		var btnElem = document.getElementById(btn);
		//alert(btn+" "+btnElem.name);
		if (btnElem){
			btnElem.addEventListener("mousedown",Controls_ButtonPress,false);
			btnElem.addEventListener("mouseup",Controls_ButtonUnpress,false);
			btnElem.addEventListener("touchstart",Controls_ButtonPress,false);
			btnElem.addEventListener("touchend",Controls_ButtonUnpress,false);
			btnElem.addEventListener("touchenter",Controls_ButtonPress,false);
			btnElem.addEventListener("touchleave",Controls_ButtonUnpress,false);
			
			
			Controls_button_elems[btn]=btnElem;
			btnElem.addEventListener("touchmove",Controls_ButtonMove,false);
		}
	}
	Controls_button_elems["buttons_left"]=document.getElementById("buttons_left");
	Controls_button_elems["buttons_right"]=document.getElementById("buttons_right");
	document.getElementById("container").addEventListener("touchmove",Controls_ButtonMove,false);
	document.getElementById("game").addEventListener("touchmove",Controls_ButtonMove,false);

	Controls_ToggleOSC(); // onscreen controls now disabled by default
});
function Controls_ButtonPress(e){
	//alert(e.target.id+" "+e.target.name);
	GLOBAL_CONTROLS.press(GLOBAL_CONTROLS,e.target.name);
}
function Controls_ButtonUnpress(e){
	GLOBAL_CONTROLS.unpress(GLOBAL_CONTROLS,e.target.name);
}
function Controls_ButtonMove(e){
	e.preventDefault();
	
	for (var btn in Controls_button_elems){
		var btnElem = Controls_button_elems[btn];	
		var anyTouchIn=false;
		for (var i=0; i<e.changedTouches.length; i++){
			if (_Controls_IsInTarget(e.changedTouches[i],btnElem)){
				anyTouchIn=true;
				//alert(btn+" in!");
				if (!GLOBAL_CONTROLS.held[btnElem.name]){
					GLOBAL_CONTROLS.press(GLOBAL_CONTROLS,btnElem.name);
				}
			}
			//alert("touch "+i+" vs "+btnElem.name+" "+_Controls_IsInTarget(e.touches[i],btnElem)+" ("+GLOBAL_CONTROLS.held[btnElem.name]+")");
		}
		if (GLOBAL_CONTROLS.held[btnElem.name] && !anyTouchIn){
			//alert(btn+" out!");
			GLOBAL_CONTROLS.unpress(GLOBAL_CONTROLS,btnElem.name);
		}
	}
}
function _Controls_IsInTarget(touch,target){
	//var x = touch.pageX - target.offsetLeft - Controls_button_elems["buttons"].offsetLeft;
	//var y = touch.pageY - target.offsetTop - Controls_button_elems["buttons"].offsetTop;
	// duct-tape fix for the above now that buttons is 2 different elements.  Not actually tested.
	var x = touch.pageX - target.offsetLeft - target.parentElement.offsetLeft;
	var y = touch.pageY - target.offsetTop - target.parentElement.offsetTop;
	//alert(target.name+" "+x+" "+y+" "+touch.pageY+" "+target.offsetTop);
	if (x>=0 && x<target.clientWidth && y>=0 && y<=target.clientHeight) return true;
	return false;
}

function Controls_SoftButtonDown(btn){
	//alert(btn);
	GLOBAL_CONTROLS.press(GLOBAL_CONTROLS,btn);
}
function Controls_SoftButtonUp(btn){
	//alert(btn);
	GLOBAL_CONTROLS.unpress(GLOBAL_CONTROLS,btn);
}

var Controls_OSC = true;
function Controls_ToggleOSC(){
	Controls_OSC = !Controls_OSC;
	for (var control in Controls_button_elems){
		if (Controls_button_elems[control]) Controls_button_elems[control].style.display = Controls_OSC ? "block" : "none";
	}
}
