/**
 * Minimal set of javascript utility functions used by all higher level apis (unbluAPI, jstk, unbluOfflineUI...)
 * 
 * 
 * @preserveIdentifier window
 * @preserveIdentifier slice
 * @preserveIdentifier Array

 * @preserveIdentifier addEventListener
 * @preserveIdentifier attachEvent
 * @preserveIdentifier event
 */

function createUtil() {
	var $_jsutil = {};
	$_jsutil.__dom_window = window;
	$_jsutil.slice = Array.prototype.slice;
	$_jsutil.__prototype_array_update = function(array, args) {
		var arrayLength = array.length, length = args.length;
		while (length--) array[arrayLength + length] = args[length];
		return array;
	}
	$_jsutil.__prototype_array_merge = function(array, args) {
		array = $_jsutil.slice.call(array, 0);
		return $_jsutil.__prototype_array_update(array, args);
	}	
	
	$_jsutil.function_bind = function(fkt, context) {
		if (typeof fkt != "function") {
			throw "not a function: " + fkt;
		} 
	    if (arguments.length < 2 && (typeof arguments[0] === "undefined")) return this;
	    var __method = fkt, args = $_jsutil.slice.call(arguments, 2);
	    var bound = function() {
	    	var a = $_jsutil.__prototype_array_merge(args, arguments);
	    	return __method.apply(context, a);
	    }
	    // TODO might impact performance
	    // should be removed in prod environments
	    bound.toString = function() {
	    	return "[bound method context: " + context + " method: " + __method + "]";
	    }
	    return bound;
	}
	// low level event handler registration
	$_jsutil.dom_addEventListener = function(node, type, listener) {
		if (node.addEventListener) {	
			node.addEventListener(type, listener, false);
		} else if (node.attachEvent) {
			var proxy = new $_jsutil.__ieEventListenerProxy(listener);
			//node.attachEvent("on" + type, proxy.callback);
			node.attachEvent("on" + type, listener);
		}
	}
	$_jsutil.__ieEventListenerProxy = function(listener) {
		this.listener = listener;
	
		this.callback = function() {		
			listener($_jsutil.__dom_window.event);	
		}
	}
	return $_jsutil;
}
var $_jsutil = createUtil();
delete(createUtil);