//	Object-Extensions
Object.__message = new Object();
Object.__message.TYPE_MESSAGE = 0;
Object.__message.TYPE_DEBUG = 1;
Object.__message.TYPE_WARNING = 2;
Object.__message.TYPE_ERROR = 3;
Object.__message.hide = true;
Object.__message.hideMessage = false;
Object.__message.hideDebug = false;
Object.__message.hideWarning = false;
Object.__message.hideError = false;
Object.__message.Rows = 20;
Object.__message.Mover = null;
Object.__message.Resizer = null;
Object.__message.show = function(msg){
	if(Object.__message.hide) return;
	//var b = document.getElementsByTagName("body")[0];
	var b = document.body;
	if(typeof(b) == "undefined" || b == null){
		setTimeout("Object.__message.show('"+escape(msg)+"',"+arguments[1]+","+arguments[2]+")",250);
	}else{
		var ele = document.getElementById("debug-msgbox");
		if(typeof(ele) == "undefined" || ele == null){
			ele = document.createElement("div");
			ele.id = "debug-msgbox";
			ele.className = "debug-msgbox msgbox";
			//ele.ondblclick = this.ondblclick;
			ele.innerHTML+= "<span class='debug-msgboxHeader'></span><span class='debug-msgboxBody'></span>";
			ele.getElementsByTagName("span")[0].onclick = Object.__message.onclickHeader;
			b.appendChild(ele);
			Object.__message.Mover = new net.Widgets.Mover(ele);
			Object.__message.Resizer = new net.Widgets.Resizer(ele,"all");
		}
		if(ele) var bodyEle = ele.getElementsByTagName("span")[1];
		var flag = true;
		var msgType = (arguments[2]) ? arguments[2] : Object.__message.TYPE_MESSAGE;
		if(Object.__message.hideMessage && msgType == Object.__message.TYPE_MESSAGE) flag = false;
		if(Object.__message.hideDebug && msgType == Object.__message.TYPE_DEBUG) flag = false;
		if(Object.__message.hideWarning && msgType == Object.__message.TYPE_WARNING) flag = false;
		if(Object.__message.hideError && msgType == Object.__message.TYPE_ERROR) flag = false;
		if(bodyEle && flag){
			var date = new Date();
			var txtClass = "";
			if(msgType == Object.__message.TYPE_MESSAGE) txtClass+= " debug-msgboxTextMessage";
			else if(msgType == Object.__message.TYPE_DEBUG) txtClass+= " debug-msgboxTextDebug";
			else if(msgType == Object.__message.TYPE_WARNING) txtClass+= " debug-msgboxTextWarning";
			else if(msgType == Object.__message.TYPE_ERROR) txtClass+= " debug-msgboxTextError";
			else txtClass+= " debug-msgboxTextMessage";
			var msecs = ""+date.getMilliseconds();
			while(msecs.length < 4) msecs = "0"+msecs;
			var childs = new Array();
			for(var i=0;i<bodyEle.childNodes.length;i++){
				if(bodyEle.childNodes[i].nodeName.toLowerCase() == "span") childs.push(bodyEle.childNodes[i]);
			}
			while(childs.length > Object.__message.Rows){
				bodyEle.removeChild(childs.shift());
			}
			var msg = "<span class='debug-msgboxLine'><span class='"+txtClass+"'><span class='debug-msgboxTime'>"+msecs+"</span>"+":"+unescape(msg)+"</span></span>\n";
			if(arguments[1]) bodyEle.innerHTML= msg;
			else bodyEle.innerHTML+= msg;
		}
	}
}
Object.__message.ondblclick = function(event){
	var e = event || window.event;
	var x = getMouseX(e);
	var y = getMouseY(e);
	var obj = document.getElementById("debug-msgbox");
	var callback = function(){
		if(obj.style.display == "none"){
			obj.style.display = "block";
			var winX = getWindowX();
			var winY = getWindowY();
			var top = (y-(obj.offsetHeight/2));
			if(top < 0) top = 0;
			if(top > winY-obj.offsetHeight) top = winY-obj.offsetHeight;
			var left = (x-(obj.offsetWidth/2));
			if(left < 0) left = 0;
			if(left > winX-obj.offsetWidth) left = winX-obj.offsetWidth;
			obj.style.top = top+"px";
			obj.style.left = left+"px";
		}else obj.style.display="none";
		obj = null;
	}
	setTimeout(callback,150);
}
Object.__message.onclickHeader = function(e){
	var ele = this.parentNode.getElementsByTagName('span')[1];
	var msgbox = document.getElementById("debug-msgbox");
	if(ele){
		if(ele.style.display == 'none'){
			ele.style.display='block';
			msgbox.style.marginBottom = "0px";
		}else{
			msgbox.style.marginBottom = ele.offsetHeight+"px";
			ele.style.display='none';
		}
	}
}

Function.prototype.__extends = function(parent){
	if(arguments.length >= 2){
		for(var i=1;i<arguments.length;i++){
			var arg = arguments[i];
			if(arg instanceof Array){
				for(var ii=0;ii<arg.length;ii++){
					var prop = arg[ii];
					if(typeof(parent.prototype[prop]) == "undefined" || parent.prototype[prop] == null) continue;
					this.prototype[prop] = parent.prototype[prop];
				}
			}else if(typeof(arg) == "string"){
				if(typeof(parent.prototype[arg]) == "undefined" || parent.prototype[arg] == null) continue;
				this.prototype[arg] = parent.prototype[arg];
			}
		}
	}else if(typeof(parent) == "function"){
		var p = new parent();
		for(var prop in p) this.prototype[prop] = p[prop];
	}else if(typeof(parent) == "object"){
		var p = parent;
		for(var prop in p) this.prototype[prop] = p[prop];
	}else{
		Object.__message.show("ERROR: Can't extend class with passed arguments("+typeof(parent)+")",null,Object.__message.TYPE_ERROR);
		return false;
	}
	if(typeof(parent) == "function") this.prototype.constructor = parent;
	
	var deep = 0;
	
	this.prototype.parent = function(name){
		if(typeof(parent) != "function") return null;
		var deep2 = deep;
		if(typeof(name) == "object" || name == null){
			if(deep2){
				var v = this.constructor;
				while(deep2){
					v = v.prototype.constructor;
					deep2--;
				}
				var fnc = v;
			}else{
				var fnc = this.constructor;
			}
			if(typeof(fnc) == "function"){
				deep++;
				var r = fnc.apply(this,name);
				deep--;
				return r;
			}
			return;
		}
		if(deep2){
			var v = parent.prototype;
			while(deep2){
				v = v.constructor.prototype;
				deep2--;
			}
			if(v) var fnc = v[name];
		}else{
			if(p){
				var fnc = p[name];
				if(fnc == this[name]) fnc = parent.prototype[name];
			}else{
				var fnc = parent.prototype[name];
			}
		}
		if(typeof(fnc) == "function"){
			deep++;
			var r = fnc.apply(this,Array.prototype.slice.apply(arguments,[1]));
			deep--;
			return r;
		}
	}
}

Function.prototype.__implements = function($interface){
	if(typeof($interface) != "function") return;
	var obj = new $interface();
	for(iter in obj){
		if(iter.substr(0,2) == "__") continue;
		if(typeof(this.prototype[iter]) != "function"){
			if(typeof($interface.prototype[iter]) == "function"){
				this.prototype[iter] = $interface.prototype[iter];
				Object.__message.show("[ "+this.prototype.toClassString()+" ] use default implementation for "+iter+" from "+obj.toClassString(),null,Object.__message.TYPE_WARNING);
			}else{
				Object.__message.show("[ "+this.prototype.toClassString()+" ] doesn't implements "+obj.toClassString()+"."+iter,null,Object.__message.TYPE_ERROR);
			}
		}
	}
}
Object.prototype.toClassString = function(){
	if(this.parent){
		var str = "";
		var flag = false;
		var constr = this.constructor;
		try{
			do{
				str = constr.prototype.__className+" <= "+str;
				constr = constr.prototype.constructor;
				if(constr == constr.prototype.constructor){
					str = constr.prototype.__className+" <= "+str;
					flag = false;
				}
			}while(flag);
		}catch(e){
			Object.__message.show(this.__className+".toString: "+e,null,Object.__message.TYPE_ERROR);
		}
		return str+this.__className;
	}else{
		return this.__className;
	}
}

//	Array-Extensions
Array.prototype.indexOf = function(obj){
	var result = -1;
	for(var i=0;i<this.length;i++){
		if(this[i] == obj){ result=i; break; }
	}
	return result;
}
Array.prototype.contains = function(obj){
	return (this.indexOf(obj) >= 0);
}
Array.prototype.append = function(obj,nodup){
	if(!(nodup && this.contains(obj))) this.push(obj);
}
Array.prototype.remove = function(obj){
	var idx = this.indexOf(obj);
	if(idx >= 0) this.splice(idx,1);
}

alertObj = function(obj){
	if(typeof(obj) == "object"){
		var deep = (isNaN(arguments[2])) ? 0 : parseInt(arguments[2]);
		var prefix = "";
		for(var i=0;i<deep;i++) prefix+= "\t";
		var str = "";
		for(var iter in obj){
			if(typeof(obj[iter]) == "function") str+= prefix+iter+"=function()\n";
			else if((obj[iter] instanceof Array)){
				var strA = [];
				for(var i=0;i<obj[iter].length;i++){
					if(typeof(obj[iter][i]) == "object") strA.push("{\n"+alertObj(obj[iter][i],true,deep+1)+prefix+"}");
					else strA.push(alertObj(obj[iter][i],true,deep+1));
				}
				str+= prefix+iter+"=ARRAY["+strA.join(",")+"]\n";
				//str+= prefix+iter+"=ARRAY["+obj[iter]+"]\n";
			}else if(typeof(obj[iter]) == "object") str+= prefix+iter+"={\n"+alertObj(obj[iter],true,deep+1)+prefix+"}\n";
			else str+= prefix+iter+"="+obj[iter]+"\n";
		}
	}else str = obj;
	if(arguments[1]) return str;
	else alert(str);

}
