
(function () {

	jsSuite = Suite = Jss = JSS = {

		themePath		: 'themes/',
		iconPath		: 'icons/',
		configPath		: 'config/',
		componentsPath	: 'components/',
		
		index		: 200,
		conf		: 'system',
		theme		: 'blue',

		ONREADY		: [],
		INI			: [],
		
		CACHE		: {},
		COMPS		: {},
		ELEMENTS	: {},
		ERRORS		: {},
		CONFIG		: {},
			
		isIE	: (navigator.appName == "Microsoft Internet Explorer"),
		isIE6	: navigator.userAgent.indexOf('MSIE 6') != -1,
		isIE7	: navigator.userAgent.indexOf('MSIE 7') != -1,
		isGk	: navigator.userAgent.indexOf('Gecko') != -1,
		isFF	: navigator.userAgent.indexOf('Firefox') != -1,
		isFF2	: navigator.userAgent.indexOf('Firefox/2') != -1,
		isFF3	: navigator.userAgent.indexOf('Firefox/3') != -1,
		isSf	: navigator.userAgent.indexOf('Safari') != -1,
		isOp	: navigator.userAgent.indexOf('Opera') != -1,
		
		location : (function () {
			var scripts = document.getElementsByTagName('script');
			for (var i=0; i<scripts.length; i++) {
				var src = scripts[i].getAttribute('src');
				if (src&&src.indexOf('jsSuite.js')>=0) return src.replace('jsSuite.js', '');
			}
		})(),
		
		set : function ()
		{
			return this.System.set.apply(this, arguments);
		},
		
		textSelect : function (flag)
		{
			try {
				if (flag) {
					this.body.uncls('no-select');
					document.ondragstart = null;
					document.body.onselectstart = null;
				} else {
					this.body.cls('no-select');
					document.ondragstart = Jss.returnFalse;
					document.body.onselectstart = Jss.returnFalse;
				}
			} catch (e) {
			}
		},
		
		returnFalse : function () { return false },
		
		component : function (comp)
		{
			this.js(this.componentsPath + comp+'.js');
		},
		
		registre : function (comp, execute)
		{
			if (!this.loaded) {
				var name = comp.name;
				if (execute) comp.execute = execute;
				this.COMPS[name] = comp;
				if (comp.require) this.set({ components : comp.require});
				if (comp.css) this.css(this.themePath+this.theme+'/'+name+'/'+name+'.css');
			} else {
				// if (this[])
			}
		},

		onready : function (fn)
		{
			this.ONREADY.push(fn);
		},

		js : function (src)
		{
			if (this.CACHE['script::'+src]) return false;
			if (!this.loaded) {
				document.write('\n<script src = "'+this.location+src+'" type="text/javascript"></script>');
			} else {
				el('SCRIPT').set({
					attributes : {
						type : 'text/javascript',
						src : this.location + src
					},
					parent : document.getElementsByTagName('HEAD')[0]
				});
			}
			this.CACHE['script::'+src] = true;
			return true;
		},

		css : function (src)
		{
			if (!this.loaded) {
				if (this.CACHE['css::'+src]) return false;
				document.write('\n<link rel="stylesheet" type="text/css" href = "'+this.location+src+'" />');
				this.CACHE['css::'+src] = true;
			} else if (o) {
				el('LINK').set({
					rel : 'stylesheet',
					type : 'text/css',
					href : this.location + src,
					parent : document.getElementsByTagName('HEAD')[0]
				});
			}
			return true;
		},
		
		pageSize : function () {

			if (window.innerHeight && window.scrollMaxY) {
				var xScroll = document.body.scrollWidth;
				var yScroll = window.innerHeight + window.scrollMaxY;
			} else if (document.body.scrollHeight > document.body.offsetHeight) { // all but Explorer Mac
				var xScroll = document.body.scrollWidth;
				var yScroll = document.body.scrollHeight;
			} else if (document.documentElement && document.documentElement.scrollHeight > document.documentElement.offsetHeight) { // Explorer 6 strict mode
				var xScroll = document.documentElement.scrollWidth;
				var yScroll = document.documentElement.scrollHeight;
			} else { // Explorer Mac...would also work in Mozilla and Safari
				var xScroll = document.body.offsetWidth;
				var yScroll = document.body.offsetHeight;
			}

			if (self.innerHeight) { // all except Explorer
				var bodyWidth = self.innerWidth;
				var bodyHeight = self.innerHeight;
			} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
				var bodyWidth = document.documentElement.clientWidth;
				var bodyHeight = document.documentElement.clientHeight;
			} else if (document.body) { // other Explorers
				var bodyWidth = document.body.clientWidth;
				var bodyHeight = document.body.clientHeight;
			}

			// for small pages with total height less then height of the viewport
			if (yScroll < bodyHeight) {
				var pageHeight = bodyHeight;
			} else {
				var pageHeight = yScroll;
			}

			// for small pages with total width less then width of the viewport
			if (xScroll < bodyWidth) {
				var pageWidth = bodyWidth;
			} else {
				var pageWidth = xScroll;
			}
			
			return {
				scrollX		: xScroll,
				scrollY		: yScroll,
				bodyHeight	: bodyHeight,
				bodyWidth	: bodyWidth,
				pageHeight	: pageHeight,
				pageWidth	: pageWidth
			}
		},
		
		ready : function ()
		{
			this.loaded = true;

			for (var name in this.COMPS) this.execute(name);
			// this.head = new this.Elm(document.getElementsByTagName('HEAD')[0]);
			// this.body = new this.Elm(document.body);
			// this.body.event('mousedown', function () { 	Jss.focus();	});
			// this.pageSize();
			for (var i=0; i<this.ONREADY.length; i++) this.ONREADY[i](this);
			this.onload();
		},
		
		config : function (conf)
		{
			if (typeof(conf) == 'object') {
				this.CONFIG[this.conf] = conf;
				for (var comp in conf) {
					this.js(this.configPath + this.conf + '/' + comp.toLowerCase() + '.js');
				}
			} else {
				if (conf) this.conf = conf;
				this.js(this.configPath + this.conf + '/ini.js');
			}
		},
		
		execute : function (name)
		{
			var comp = this.COMPS[name];
			if (comp) {
				if (!this.CACHE['comp::'+name]) {
					if (comp.require) for (var i=0; i<comp.require.length; i++)
					{
						var require = comp.require[i];
						if (this.CACHE['comp::'+require]) continue;
						if (!this.execute(require)) {
							alert('Fatal error! Can\'t find component {' + require + '} required in {'+name+'} !!!');
							return true;
						}
					}
					if (comp.execute) {
						comp.execute.apply(this, [this]);
						// if (comp.extn) {
							// var Extn = name.capitalize();
							// Jss[comp.extn].prototype[name.toLowerCase()] = 
								// function (set)
								// {
									// if (!this[Extn]) this[Extn] = new Jss[Extn](this);
									// var rset = {};
										// rset[name] = set;
									// this.set(rset);
								// }
						// }
						Jss[name].prototype.name = name;
					}

					if (this.CONFIG[this.conf]) {
						var conf = this.CONFIG[this.conf][name.toLowerCase()];
						if (conf) this[name].prototype.CONFIG = conf;
					}
					
					this.CACHE['comp::'+name] = true;
				}
				return true;
			}
			return false;
		},
		
		error : function (code)
		{
			if (this.ERRORS[code]) {
				var error = this.ERRORS[code];
				if (error.message) {
					var message = error.message.show ? error.message : window[error.message];
					if (message) {
						message.e = error;
						message.show();
					} else
						a("Message: " + error.message + " not inited or can't show")
				}
				return true;
			}
			return false;
		},

		regError : function (error)
		{
			if (error.code) this.ERRORS[error.code] = error;
		},
		
		copy : function (from, to)
		{
			for (var key in from) to[key] = from[key];
		},

		onload : function () {},

		System : {
		
			set : function (set)
			{
				for (var prop in set) {
					var setProp = 'set' + prop.capitalize();
					var props = prop.charAt(prop.length-1) == 's' ? prop.substring(0, prop.length-1) : false;

					if (typeof(this[setProp]) == 'function') {
						// if (typeof(this[prop]) != 'function') this[prop] = set[prop];
						this[setProp](set[prop]);
					}
					else if (typeof(this[prop]) == 'function') {
						// if (prop.indexOf('on') === 0) {
							// this[prop] = set[prop];
						// } else
							this[prop](set[prop]);
					}
					else if (typeof(this[prop])=='object'&&this[prop].set&&!set[prop].set) {
						if (typeof(set[prop]) == 'string' && this[prop][setProp]) {
							var rset = {};
								rset[prop] = set[prop];
								set[prop] = rset;
						};
						this[prop].set(set[prop]);
					}
					else if (props&&typeof(this[props]) == 'function')
						for (var i=0; i<set[prop].length; i++) this[props](set[prop][i]);
					else {
						this[prop] = set[prop];
					}
				};
				return this;
			}
			
			// extend : function (expand)
			// {
				// Jss.copy(expand, this);
			// }
			
		},
		
		node : function (node)
		{
			if (node) {
				if (node.tagName || node == window || node == document)
					return node
				else if (typeof(node) == 'string') {
					if (node.charAt(0) == '#') {
						node = document.getElementById(node.substr(1));
						return node ? node : document.createElement('DIV');
					}
					if (node.charAt(0) == '@')
						return el(node.substr(1)).append(document.createElement('DIV'));
					if (node == node.toUpperCase())
						return document.createElement(node);
				}
			}
			return document.createElement('DIV')
		},
		
		stopPropagation : function (e)
		{
			e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);
		}
	}
	
	document.write('<style type="text/css"> body.no-select, body.no-select * { -moz-user-select:none; -o-user-select:none; -khtml-user-select:none;}</style>');

	String.prototype.capitalize = function() {
		var chr = this.charAt(0);
		return this.replace(chr, chr.toUpperCase());
	}

	Function.prototype.extend = function(parent, methods) {
		var protot = this.prototype;
		var Inheritance = function(){};
		Inheritance.prototype = parent.prototype ? parent.prototype : parent;
		
		this.prototype = new Inheritance();
		this.prototype.constructor = this;
		this.prototype.parentClass = parent.prototype;
		this.parentClass = parent;

		for (var key in protot) this.prototype[key] = protot[key];
		for (var key in methods) this.prototype[key] = methods[key];
	}

	// domReady( function () { Jss.ready() });
	// dom ready not work when css not load jet (border comp)
	if (window.addEventListener) {
		window.addEventListener('load', function () { Jss.ready() }, false);
	} else {
		window.attachEvent('onload', function () { Jss.ready() })
	}
	
})();


function a ()
{
	if (!arguments.length) alert('empty');
	if (arguments.length == 1) {
		if (typeof(arguments[0])=='object') {
			var arg = '';
			for (var key in arguments[0])
				if (typeof(arguments[0][key]) == 'string' || typeof(arguments[0][key]) == 'number')
					arg += key + ' : ' + arguments[0][key] + '\n';
			alert(arg)
		} else
			alert(arguments[0]);
	} else if (arguments.length > 1) {
		var arg = [];
		for (var i=0; i<arguments.length; i++) arg[i] = arguments[i];
		alert(arg);
	}
}

function w (text)
{
	if (!document.body) return onload = function () {w(text)};
	if (!text) {
		t.node.value = '<html>' + document.getElementsByTagName('html')[0].innerHTML + '</html>';
	} else if (typeof(text) == 'object') {
		var arg = [];
		for (var i in text) arg.push(i + ' : ' + text[i]);
		t.node.value = arg.join("\n");
	} else {
		t.node.value = text;
	}
}

function log ()
{
	var text = [];
	for (var i=0; i<arguments.length; i++) text.push(arguments[i]);
	text = text.join(", ");
	if (!Jss.Log) {
		Jss.Log = obj('PRE').set({
			style		: 'position:absolute; background:#f2f4ff; zIndex:1000; top:0; right:0; width:50%; minHeight:100%; border:none; borderLeft:1px dotted red; padding:0 5px; margin:0; zIndex:5000',
			appendTo	: document.body,
			index		: 0,
			lognames	: {},
			clocknames	: {},
			fns			: {},
			clockFn		: {}
		});
	}

	var fn = log.caller.toString();
	var length = Jss.Log.fns[fn];
	if (!length) {
		Jss.Log.fns[fn] = fn.split('log(').length-1;
		Jss.Log.clockFn[fn] = 0;
	}
	var index = Jss.Log.clockFn[fn]++;
	if (Jss.Log.clockFn[fn] == Jss.Log.fns[fn]) Jss.Log.clockFn[fn] = 0;
	var logs = fn.split('log(');
	var logname = logs[index+1].split(')')[0];
	
	
	// if (!Jss.Log.lognames[logname]) {
		// Jss.Log.lognames[logname] = fn.split('log(').length-1;
		// Jss.Log.clocknames[logname] = 0;
	// }
	
	// Jss.Log.clocknames[logname]++;	// need fix, fn[logname] - right
	// var sep = '&#8594;';
	
	// if (Jss.Log.clocknames[logname] > Jss.Log.lognames[logname]) {
		// sep = '&#8230;';
		// Jss.Log.clocknames[logname] = 0;
	// }
	
	
	// if (Jss.Log.caller == log.caller) {		
		// if (Jss.Log.logname == logname) {				
			// Jss.Log.write(' ' + sep + ' <span style="color:#008080"><b>' + text + '</b></span>');
		// } else { // … 	
			
		// }
	// } else {
		if (Jss.Log.html()) Jss.Log.write('<br>');
		Jss.Log.write(
			'<b>' + Jss.Log.index ++ + '</b>. ' +
			'<span style="color:#008080">' + 
			(logname != text ? logname + 
			'<span style="color:#B82619"> : </span>' : '') +
			'<b>' + text + '</b></span>'
		);
	// }
	// Jss.Log.logname = logname;
	// Jss.Log.caller = log.caller;
}


function int (int)
{
	if (typeof(int) == 'string'){
		if (int.indexOf('px')>0) return parseInt(int.replace('px', ''));
		if (int == 'auto') return 0;
		if (int == 'medium') return 0;
	}
	if (int == undefined) return 0;
	return parseInt(int);
}


function obj (obj)
{
	if (obj) {
		if (obj.node)
			return obj;
		else if (typeof(obj) == 'string')
			return new Jss.Elm(Jss.node(obj))
		else if (obj.tagName || obj == window || obj == document)
			return new Jss.Elm(obj)
		else if (obj.type)
			return new Jss[obj.type]().set(obj);
		else
			return new Jss.Elm().set(obj);
	} else
		return new Jss.Elm;
}

function eObj (e)
{
	return obj(document.all ? event.srcElement : e.target);
}

function domReady (handler)
{
	var called = false;
	
	function ready() {
		if (called) return;
		called = true;
		handler();
	}

	if (document.addEventListener) {
		document.addEventListener("DOMContentLoaded", function() { ready() }, false )
	} else if (document.attachEvent) {
		
		if (document.documentElement.doScroll && window == window.top) {
			function tryScroll() {
				if (called) return
				if (!document.body) return
				try {
					document.documentElement.doScroll("left")
					ready()
				} catch(e) {
					setTimeout(tryScroll, 0)
				}
			}
			tryScroll()
		}
		
		document.attachEvent("onreadystatechange", function(){
			if ( document.readyState === "complete" ) {
				ready()
			}
		})
		
	}

    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready);
}
