/***************************************
	Utility functions contained in a static class
****************************************/
var tool = new function(){}

tool.isFunction = function(a){
	return typeof a == 'function';
};	
tool.isObject = function(a) {
	return (a && typeof a == 'object') || isFunction(a);
};
tool.createNewElement = function(type,property,style){
	var el = document.createElement(type);
	if(property && property != null){
		for(var prop in property){
			el[prop] = property[prop];
		}
	}
	if(style && style!=null){
		for(var stl in style){
			el.style[stl] = style[stl];
		}
	}
	return el;
};
tool.getPosition = function(theElement){
	var positionX = 0;
	var positionY = 0;
 	while (theElement != null){
		positionX += theElement.offsetLeft;
		positionY += theElement.offsetTop;
		theElement = theElement.offsetParent;
	}
	return [positionX, positionY];
};
tool.registerEvent = function(obj,evt,handler){
	if(obj.attachEvent)	obj.attachEvent("on"+evt,handler);
	else obj.addEventListener(evt,handler,false);
};

tool.contains_ns6 = function(a, b) {
	while (b.parentNode)
	if ((b = b.parentNode) == a)
	return true;
	return false;
};
tool.inArray = function(arr, val){
	for(var i=0;i<arr.length;i++){
		if(arr[i] == val){
			return true;
			break;
		}
	}
	return false;
}
tool.isObjectPropertyValueExists = function(obj, val){
	for(var property in obj){
		if(obj[property] == val){
			return true;
		}
	}
	return false;
}
tool.isObjectPropertyExists = function(obj, key){
	for(var property in obj){
		if(property == key){
			return true;
		}
	}
	return false;
}
tool.isInstanceOf = function(obj, _constructor) {
	while (obj != null) {
    	if (obj == _constructor.prototype)return true;
		obj = obj.__proto__;
  	}
  	return false;
}

tool.getObjectLen=function(obj){
	var i = 0;
	for(var prop in obj){i++;}
	return i;
}
/***************************************
The 2 functions below are taken the script made by John Resig
Added a minor modification, setting the obj to null in the addEvent function
updated April 2, 2008 (fixed a bug for IE, I changed obj to this since the scope of the function will change that moment that it will run.)
***************************************/
tool.AddEvent = function( obj, type, fn ) {
	if(obj.addEventListener){
		obj.addEventListener( type, fn, false );
	}
	else if(obj.attachEvent){
		obj['e'+type+fn] = fn;
        obj[type+fn] = function(){
			this['e'+type+fn]( window.event );
		}
		obj.attachEvent( 'on'+type, obj[type+fn] );
	}
	obj = null;		
};

tool.RemoveEvent = function( obj, type, fn ) {
   	if ( obj.detachEvent ) {
  		obj.detachEvent( 'on'+type, obj[type+fn] );
  		obj[type+fn] = null;
	} 
	else obj.removeEventListener( type, fn, false );
};

tool.isObject = function(obj) { return (obj && typeof obj == 'object') || tool.isFunction(obj)};
tool.isArray = function(obj) { return tool.isObject(obj) && obj.constructor == Array };
tool.isBoolean = function(obj) {return typeof obj == 'boolean'};
tool.isFunction = function(obj){ return typeof obj == 'function'};
tool.isNull = function(obj) { return typeof obj == 'object' && !obj};
tool.isNumber=function(obj) { return typeof obj == 'number' && isFinite(obj)};
tool.isString = function(obj) { return typeof obj == 'string' }
tool.isUndefined = function(obj) { return typeof obj == 'undefined'; }

/**
**  UTF-8 data encode / decode
*  http://www.webtoolkit.info/
**/
tool.utf8Encode = function (string) {
	string = string.replace(/\r\n/g,"\n");
	var utftext = "";
	for (var n = 0; n < string.length; n++) {
		var c = string.charCodeAt(n);
		if (c < 128) {
			utftext += String.fromCharCode(c);
		}
		else if((c > 127) && (c < 2048)) {
			utftext += String.fromCharCode((c >> 6) | 192);
			utftext += String.fromCharCode((c & 63) | 128);
		}
		else {
			utftext += String.fromCharCode((c >> 12) | 224);
			utftext += String.fromCharCode(((c >> 6) & 63) | 128);
			utftext += String.fromCharCode((c & 63) | 128);
		}

	}
	return utftext;
}

tool.utf8Decode = function (utftext) {
	var string = "";
	var i = 0;
	var c = c1 = c2 = 0;
	while ( i < utftext.length ) {
		c = utftext.charCodeAt(i);
		if (c < 128) {
			string += String.fromCharCode(c);
			i++;
		}
		else if((c > 191) && (c < 224)) {
			c2 = utftext.charCodeAt(i+1);
			string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
			i += 2;
		}
		else {
			c2 = utftext.charCodeAt(i+1);
			c3 = utftext.charCodeAt(i+2);
			string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
			i += 3;
		}
	}
	return string;
}


/***************************************
	Misc functions
****************************************/
if (!tool.isFunction(Function.apply)) {
    Function.method('apply', function (o, a){
        var r, x = '____apply';
        if (!tool.isObject(o)) { o = {};}
        o[x] = this;
        switch ((a && a.length) || 0) {
	        case 0: r = o[x](); break;
	        case 1: r = o[x](a[0]);  break;
	        case 2: r = o[x](a[0], a[1]); break;
	        case 3: r = o[x](a[0], a[1], a[2]); break;
	        case 4: r = o[x](a[0], a[1], a[2], a[3]); break;
	        case 5: r = o[x](a[0], a[1], a[2], a[3], a[4]); break;
	        case 6: r = o[x](a[0], a[1], a[2], a[3], a[4], a[5]); break;
	        default: alert('Too many arguments to apply.');
	    }
        delete o[x];
        return r;
    });
};
Function.prototype.bind = function(object){
	 var __method = this;
	 return function() {
	 __method.apply(object, arguments);
	 }
};
if (!$) {
	var $ = function(id) {
		return document.getElementById(id);
	}
}
