var go = new (function()
{
	
this.$ = (
	function(node, nocache)
	{
		if (typeof(node) == "object") {
			return node;
		}
		if (($eCash) && (!nocache)) {
			var e = $cash[node];
			if (e !== undefined) {
				return e;
			}
			return ($cash[node] = document.getElementById(node));
		}
		return document.getElementById(node);
	}
);	
this.$.cashEnable  = (function() {$eCash = true;}); 
this.$.cashDisable = (function() {$eCash = false;});
this.$.cashReset   = (function() {$cash = {};});   
var $cash  = {};
var $eCash = false;


this.methodExec = (
	function(method, object, args)
	{
		if (!object) {object = window;}
		if (!args)   {args = [];}
		if (typeof(method) == "function") {
			return method.apply(object, args);
		}
		if (typeof(method) != "object") {
			return _this.execCode(method);
		}
		if (method.object) {
			object = method.object; 
		}
		if (method.value !== undefined) { 
			_this.pathResolve(method.objectPath, object, method.value);
			return method.value;
		}
		if (method.objectPath) {
			object = _this.pathResolve(method.objectPath, object); 
		}
		if (typeof(method.method) == "function") { 
			var func = method.method;
		} else { 
			var func = _this.pathResolve(method.method, object);
		}
		if (method.args) { 
			args = method.args.concat(args);			
		}
		return func.apply(object, args);
	}
);

this.pathResolve = (
	function(path, object, value)
	{
		if (!object) {
			object = window;
		}
		if (typeof(path) == "string") {
			path = path.split(".");
		}
		var len = path.length;
		if (value !== undefined) {
			len--;
		}
		for (var i = 0; i < len; i++) {
			object = object[path[i]];
			if (!object) {
				return object;
			}
		}
		if (value !== undefined) {
			if (object) {
				object[path[len]] = value;
				return value;
			}
		}
		return object;
	}
);

this.execCode = (function(code) {return eval(code);});

this.inherit = (
	function(parent, proto, constr)
	{		
		if (typeof(proto) == "function") {
			proto.prototype = parent;
			proto = new proto();
		} else {
			var f = (function() {});
			f.prototype = parent;
			var p = new f();
			for (var k in proto) {
				p[k] = proto;
			}
		}
		if (constr) {
			constr.prototype = proto;
		}
		return proto;
	}
);

this.addListenerStart = (
	function(handler)
	{
		listenersStart.push(handler);
		return true;
	}
);

this.addListenerDEl = (
	function(type, handler) 
	{
		if (listenersDEls[type]) {
			listenersDEls[type].push(handler);
		} else {
			listenersDEls[type] = [handler];
		}
		return true;
	}
);

this.emptyFunction = (function() {});
this.falseFunction = (function() {return false;});

var eonload;
this.onLoad = (
	function()
	{
		if (eonload) {
			return true;
		}
		eonload = true;
		var len = listenersStart.length;
		for (var i = 0; i < len; i++) {
			_this.methodExec(listenersStart[i]);
		}
		dElements();
		if (window.start) {
			window.start();
		}
		return true;
	}
);

this.alert = (
	function(text)
	{
		alert(text);
		return true;
	}
);

this.setConsts = (
	function(owner, viewer, editor)
	{
		_this.OWNER_ID  = owner;
		_this.VIEWER_ID = viewer;
		_this.MY_PAGE   = (owner == viewer);
		_this.IS_EDITOR = editor ? true : false;
		return true;
	}
);

this.getPathToGOJS = (function() {return pathToGOJS;}); 
var pathToGOJS = document.getElementsByTagName("script");
pathToGOJS = pathToGOJS.item(pathToGOJS.length - 1).getAttribute("src").replace(/[^//\?#]*(\?.*)?(#.*)?$/, "");

/*** PRIVATE ***/

function dElements()
{
	var els = document.getElementsByTagName("EM");
	var len = els.length;
	for (var i = len - 1; i >= 0; i--) {
		var el = els.item(i);
		if (el.className != "gojsdel") {
			continue;
		}
		var types = el.firstChild.nodeValue.split("|");
		var type = types[0];
		var lst = listenersDEls[type];
		if (lst) {
			var lenj = lst.length;
			var res = false;
			for (var j = 0; j < lenj; j++) {
				var r = _this.methodExec(lst[j], el, [types, el, res]);
				if (typeof(r) == "object") {
					res = r;
				}
			}
			if (res) {
				el.parentNode.replaceChild(res, el);
			}
		}
	}
	return true;
}

var _this = this;
var listenersStart = [];
var listenersDEls  = {};

})(); 

if (window.addEventListener) {
	window.addEventListener("load", go.onLoad, false);
} else if (window.attachEvent) {
	window.attachEvent("onload", go.onLoad);
}