/*************************************
* (C) 20minuten AG - 20min.ch 

* Programmed by Jeremy A. Prescott, www.prescore.ch for 20min.ch

* This KeyBoard Class handles char/keycode<->function relationships,
* so you can bind a function to be called as soon as a char/keycode is pressed

* Usage:

Example 1: call a function
	function test(){
		//do some sick programing shit
		alert("sick stuff");
	}

	keyboard.bindChar( "b", test );
	
Example 2: create anonymouse function to call
	keyboard.bindChar( "a", function(){ alert("sick stuff"); } );
	
Example 3: use arrays..
keyboard.bindChar( [10, 20, 35, 36, 37, 38], test );


***************************************/

var keyboard=(function(){
	
	var _binding={}; //the binding object with all the char<->function relations
	
	//handles an event and gives back a corrected event object
	var _handleEvent=function(e) {
		
		/*code inspired by http://www.quirksmode.org */
		if (!e) var e = window.event;
		
		var targ;
		if (e.target) targ = e.target;
		else if (e.srcElement) targ = e.srcElement;
		if (targ.nodeType == 3) // defeat Safari bug
			targ = targ.parentNode;
			
		var keyNum=e.charCode || e.keyCode;		
		
		return {event:e,target:targ,keyCode:keyNum};
	}
	
	
	//check if char has been bound to function or not
	var _isBound=function( char ) {
		if ( typeof _binding[ char ]!=="undefined" ){
			return true;
		} 
		else {	
			return false;
		} 
	}
	
	
	
	return {
		
		//bind a char to a function, so if the key gets pressed that prints the char, the function will be fired!
		bindChar:function( chars, func ) {
			if (typeof chars==="undefined")return;
			if (typeof chars!=="object" || !chars.length){
				chars=[chars];
			}
			for (var i in chars) {
				if (_isBound( chars[i] ) === false) {
					_binding[ chars[i] ] = [];
				}
				_binding[ chars[i] ].push(func);
			}
			return true;
		},
		
		//unbinds a char<->function relationship
		unbindChar:function(chars) {
			if (typeof chars==="undefined")return;
			if (typeof chars!=="object" || !chars.length){
				chars=[chars];
			}
			for (var i in chars) {
				delete _binding[ chars[i] ];
			}
		},
		
		//the general onkeydown handler function
		handle:function(event) {
			var evt=_handleEvent(event);
			var char=String.fromCharCode( evt.keyCode ).toLowerCase();
			var code;
			if ( _isBound( evt.keyCode ) ){ //we've got a function associated with this keyCode
				code=evt.keyCode;
			}
			else if ( _isBound( char ) ){ //we've got a function associated with this char
				code=char;
			}
			
			if (typeof code!=="undefined" && code!==null){
				//Fire the function
				for (var i=0;i<_binding[ code ].length;++i) {
					_binding[ code ][ i ]();
				}
			}
			
			//document.getElementById("console").innerHTML=("Key: "+evt.keyCode+" Char:"+char+" Target:"+evt.target.id+" <br/>" )+document.getElementById("console").innerHTML;
						
		}
		
	}
	
}());

function addEvent(type, el, fn) {
  if (window.addEventListener) {
    return el.addEventListener(type, fn, false);
  } 
  else if (window.attachEvent) {
    el.attachEvent('on'+type, fn);
  }
  else{
  	return false
  }
  return true;
}


addEvent("keydown", document, keyboard.handle);

