  //////////////////////////
 // The global variables //
//////////////////////////
var is = new function() {
	var agent = navigator.userAgent.toLowerCase();
	this.ns = ((agent.indexOf('mozilla') != -1) && ((agent.indexOf('spoofer') == -1) && (agent.indexOf('compatible') == -1) && agent.indexOf('like gecko') == -1));
	this.ie = (agent.indexOf("msie") != -1);
	this.o = (agent.indexOf("opera") != -1);
	this.safari = (agent.indexOf("safari") != -1);
	var nav = navigator.appVersion.toLowerCase();
	this.ie6 = (this.ie && (nav.indexOf('msie 6.0') != -1));
	this.ie7 = (this.ie && (nav.indexOf('msie 7.0') != -1));
	this.ie8 = (this.ie && (nav.indexOf('msie 8.0') != -1));
	this.ie9 = (this.ie && (nav.indexOf('msie 9.0') != -1));
	this.dom = this.ns || this.o || this.safari || this.ie9;
};

  ///////////////////////////
 // Nagyon Common rutinok //
///////////////////////////
function nop() {
}

var jgtc = {
	rootURL: null,
	rootImgURL: null,

	openPopup: function(htmname, winname, w, h, params) { throw "not implemented yet."; },
	setCookie: function(name, value, days, path, domain, secure) { setCookie(name, value, days, path, domain, secure); },
	getCookie: function(name, defVal) { getCookie(name, defVal); },

	getBounds: function(element) {
		var x = 0;
		var y = 0;
		var w = element.offsetWidth;
		var h = element.offsetHeight;

		do {
			x += element.offsetLeft;
			y += element.offsetTop;
//			console.log("e: %o, (%d;%d) - %o / %o", element, element.offsetLeft, element.offsetTop, element.offsetParent, element.parentNode);
		} while((element = element.offsetParent) != null);

		return { "x": x, "y": y, "w": w, "h": h };
	},

	safeGetAttribute: function(element, attrName) {
		try {
			return element.getAttribute(attrName);
		} catch(err) {
			console.warn("Error while getting attribute '%s': %o, %s", attrName, element, err.message);
		}
		return null;
	},

	clone: function(obj, deep) {
		var o = new obj.constructor();
		for(i in obj) {
			var e = obj[i];
			var t = typeof e;
			if(t == 'function' && o.constructor.prototype[i]) continue;
			else if(deep && t == 'object') o[i] = e.clone();
			else o[i] = e;
		}
		return o;
	},

	jsonML: function() {
		var doc = document;
		var userTags = false;
		var userAttrs = false;

		function _build(jsonml) {
			if(jsonml instanceof Array && jsonml.length > 0) {
				// Element
				var tag = jsonml[0];
				var e, u, ui, uprefix;
				if(userTags !== false && (ui = tag.indexOf(':')) > 0 && (uprefix = tag.substr(0, ui)) in userTags) {
					tag = tag.substr(ui + 1);
					if((e = userTags[uprefix](uprefix, tag, jsonml)) == null) {
						return null;
					}
				} else {
					e = doc.createElement(tag.toUpperCase());
				}
				if(jsonml.length > 1) {
					var i = 1;
					var ad = jsonml[1];
					if(typeof ad == 'object' && !(ad instanceof Array)) {
						// attr
						for(var a in ad) {
							if(userAttrs !== false && (ui = a.indexOf(':')) > 0 && (uprefix = a.substr(0, ui)) in userAttrs) {
								var v = ad[a];
								a = a.substr(ui + 1);
								u = userAttrs[uprefix];
								userAttrs[uprefix](e, uprefix, a, v, jsonml);
/*								if(typeof u == 'function') {
									u(e, uprefix, a, v, jsonml);
								} else {
									u[a](e, uprefix, a, v, jsonml);
								}
*/
							} else if(a == 'element') {
								if(ad.element != null && typeof ad.element == 'object') {
									ad.element[typeof ad.elementId != 'undefined' ? ad.elementId : 'element'] = e;
								} else {
									ad.element = e;
								}
							} else if(a == 'elementId') {
								// Az "element" property feldolgozásánál kell.
							} else if(a == 'class') {
								e.className = ad[a];
							} else if(a == 'style') {
								if(is.ie) e.style.cssText = ad[a];
								else e.setAttribute('style', ad[a]);
							} else if(typeof ad.constructor.prototype[a] == 'undefined') {
								e[a] = ad[a];
							}
						}
						i = 2;
					}

					for(; i < jsonml.length; i++) {
						var e1 = _build(jsonml[i]);
						if(e1 != null) e.appendChild(e1);
					}
				}
				return e;
			} else {
				// Text
				return doc.createTextNode(String(jsonml));
			}
		}

		return {
			build: _build,

			setDocument: function(_doc) {
				doc = _doc;
				return this;
			},

			addUserTag: function(prefix, handler) {
				var th = typeof handler;
				var _h;
				if(th == 'object') {
					_h = function(prefix, tagName, jsonml) {
						if(tagName in handler) {
							handler[tagName](prefix, tagName, jsonml);
						} else {
							console.warn("jsonML user tag not handled: %s.%s", prefix, tagName);
						}
					}
				} else if(th == 'function') {
					_h = handler;
				} else {
					console.error("Invalid jsonML user tag handler type: %s", handler);
				}

				if(userTags === false) {
					userTags = {};
				}

				userTags[prefix] = _h;
				return this;
			},

			addUserAttribute: function(prefix, handler) {
				var th = typeof handler;
				var _h;
				if(th == 'object') {
					_h = function(element, prefix, attrName, attrValue, jsonml) {
						if(attrName in handler) {
							handler[attrName](element, prefix, attrName, attrValue, jsonml);
						} else {
							console.warn("jsonML user attribute not handled: %s.%s", prefix, attrName);
						}
					}
				} else if(th == 'function') {
					_h = handler;
				} else {
					console.error("Invalid jsonML user attribute handler type: %s", handler);
				}

				if(userAttrs === false) {
					userAttrs = {};
				}

				userAttrs[prefix] = _h;
				return this;
			}
		};
	},

	/**
	 * validator [ [ <param name>, <param type>, <default value> ], ... ]
	 */
	validateObject: function(params, validator, strict) {
		var p1 = strict ? new Object() : params;
		for(var i = 0; i < validator.length; i++) {
			var v = validator[i];
			var valid = true;
			if(typeof v[1] == 'function') {
				p1[v[0]] = (v[1])(params, v);
				continue;
			} else if(v[1] == "fixed" || typeof params[v[0]] != v[1]) {
				valid = false;
			}

//			console.log("valid: %s %s %o", v[0], valid, v[2]);

			if(valid) {
				if(strict) p1[v[0]] = params[v[0]];
			} else {
				p1[v[0]] = v[2];
			}
		}

		return p1;
	},

	/**
	 * Objektumleszármaztatást segítő funkció.
	 */
	__extends: function(_class, _superClass) {
		for(var k in _superClass.prototype) {
			if(typeof _class.prototype[k] == 'undefined') {
				_class.prototype[k] = _superClass.prototype[k];
			}
		}
	},

	_init: function() {
		with(document.getElementsByTagName("script")) {
			for(var i = 0; i < length; i++) {
				var s = item(i);
				var r = s.src.match(/^(.*\/)?common\.js$/);
				if(r != null) {
					jgtc.rootURL = (r[1] == '' || r[1] == null) ? './' : r[1];
					jgtc.rootImgURL = jgtc.rootURL + '../admin/img/';
					console.log("ir: %s", jgtc.rootImgURL);
					break;
				}
			}
		}
	}
}

if(is.ie) {
	jgtc.getComputedStyle = function(e) { return window.getComputedStyle(e, null); };
	jgtc.captureEvent = function(element, event, fn, useCapture) { element.attachEvent("on" + event, fn); };
	jgtc.releaseEvent = function(element, event, fn, useCapture) { element.detachEvent("on" + event, fn); };
	jgtc.discardEvent = function(event) { event.returnValue = false; };
} else {
	jgtc.getComputedStyle = function(e) { return e.currentStyle; };
	jgtc.captureEvent = function(element, event, fn, useCapture) { element.addEventListener(event, fn, useCapture); };
	jgtc.releaseEvent = function(element, event, fn, useCapture) { element.removeEventListener(event, fn, useCapture); };
	jgtc.discardEvent = function(event) { event.preventDefault(); };
}

function GetComputedStyle(e) {
	console.warn('Deprecated function. Use jgtc.GetComputedStyle() instead.');
	return jgtc.GetComputedStyle(e);
}

function GetBounds(e) {
	console.warn('Deprecated function. Use jgtc.GetBounds() instead.');
	return jgtc.getBounds(e);
}

/*
function OverElement(ss, x, y) {
	var pos = GetBounds(ss);
	var x0 = pos.x
	var x1 = x0 + pos.w;
	var y0 = pos.y;
	var y1 = y0 + pos.h;
	return x > x0 && x < x1 && y > y0 && y < y1;
}
*/

function openPopup(htmname, winname, xs, ys, plus) {
	return window.open(htmname, winname, "width="+xs+",height="+ys+",screenX=1,screenY=1,status=0,resizable=0"+plus);
}

function openPopupN(htmname, winname, xs, ys, plus) {
	var w = window.open(htmname, winname, "width="+xs+",height="+ys+",screenX=1,screenY=1,status=0,resizable=0"+plus);
	w.focus();
}

function setCookie(name, value, days, path, domain, secure) {
	var c = name + "=" + escape(value);
	if(days && days >= 0) {
		var d = new Date();
		d.setTime(d.getTime()+(days*24*60*60*1000));
		c += "; expires=" + d.toGMTString();
	}
	if(path) c += "; path=" + path;
	if(domain) c += "; domain=" + domain;
	if(secure) c += "; secure";
	document.cookie = c;
}

function getCookie(name, defVal) {
	if(typeof defVal == "undefined") defVal = null;

	var idx = document.cookie.indexOf(name + '=');
	if(idx == -1) return defVal;
	value = document.cookie.substring(idx + name.length + 1);
	var end = value.indexOf(';');
	if(end == -1) end = value.length;
	value = unescape(value.substring(0, end));
	return value;
}

function CaptureEvent(element, event, fn, useCapture) {
	console.warn('Deprecated function. Use jgtc.captureEvent() instead.');
	jgtc.captureEvent(element, event, fn, useCapture);
}

function ReleaseEvent(element, event, fn, useCapture) {
	console.warn('Deprecated function. Use jgtc.releaseEvent() instead.');
	jgtc.releaseEvent(element, event, fn, useCapture);
}

function DiscardEvent(event) {
	console.warn('Deprecated function. Use jgtc.discardEvent() instead.');
	jgtc.discardEvent(event);
}

if(!String.prototype.trim) {
	String.prototype.trim = function() {
		return this.replace(/^\s+|\s+$/g, '');
	};
}

String.prototype.printf = function() {
	return this.vprintf(arguments);
};

String.prototype.vprintf = function(_argv) {
	var _argc = 0;

	/* rsign: '+'
	 * rpad:  ' ', '0', '\'<ch>'
	 * ralign: '-'
	 * rwidth: '<num>', ahol a <num> egy 0-nál nagyobb egész szám.
	 * rprec: '.<num>', ',<num>' ahol a <num> egy nem negatív egész szám.
	 * rtype: tipus
	 */
	return this.replace(/%(\+)?( |0|\'.)?(\-)?([1-9][0-9]*)?([\.,][0-9]+)?([dbufescoxX]|%)/g, function(r0, rsign, rpad, ralign, rwidth, rprec, rtype) {
//		console.log("r0: %s, rsign: %s, rpad: %s, ralign: %s, rwidth: %s, rprec: %s, rtype: %s", r0, rsign, rpad, ralign, rwidth, rprec, rtype);

		if(rtype == '%') {
			return '%';
		} else if(_argc >= _argv.length) {
			return r0;
		}

		var arg = _argv[_argc++];
		var d = '';

		switch(rtype) {
			case 'f':
				d = Number(arg);
				if(!rprec) rprec = '.6';
				var rt = rprec.substr(0, 1);
				rprec = Number(rprec.substr(1));
				d = d.toFixed(rprec);
				if(rt != '.') d = d.replace('.', rt);
				rprec = false;
				break;
			case 'd':
				arg = Math.round(Number(arg));
				d = String(arg);
				if(arg > 0 && rsign) d = '+' + arg;
				rprec = false;
				break;
			case 'u':
				d = String(Math.round(Math.abs(Number(arg))));
				rprec = false;
				break;
			case 's':
				d = String(arg);
				break;
			case 'c':
				d = String.fromCharCode(arg);
				break;
			case 'x':
				d = Number(arg).toString(16);
				break;
			case 'X':
				d = Number(arg).toString(16).toUpperCase();
				break;
			case 'o':
				d = Number(arg).toString(8);
				break;
			case 'b':
				d = Number(arg).toString(2);
				break;
			case 'e':
				d = Number(arg).toExponential();
				break;
		}

		if(rwidth && d.length < rwidth) {
			var p = rpad || ' ';
			if(p.length == 2) p = p.charAt(1);
			var ps = '';
			for(var i = 0, imax = rwidth - d.length; i < imax; i++) ps += p;
			if(ralign == '-') d = d + ps;
			else d = ps + d;
		}

		if(rprec && d.length > rprec) {
			d = d.substr(0, rprec.substr(1));
		}

		return d;
	});
}

if(!Array.prototype.indexOf) {
	Array.prototype.indexOf = function(src, fromIdx) {
		for(var max = this.length, i = fromIdx ? (fromIndex < 0 ? Math.max(max - fromIndex, 0) : fromIndex) : 0; i < max; i++) {
			if(this[i] === src) return i;
		}
		return -1;
	}
}

if(is.ie) jgtc._init();
else jgtc.captureEvent(window, "load", jgtc._init, true);

/**
 * JSONML funkciók, némi kiegészítéssel.
 */
function jsonML(jsonml, doc) {
	if(typeof doc == 'undefined') doc = document;

	if(jsonml instanceof Array && jsonml.length > 0) {
		// Element
		var tag = jsonml[0].toUpperCase();
		var e;
		e = doc.createElement(tag);
		if(jsonml.length > 1) {
			var i = 1;
			var ad = jsonml[1];
			if(typeof ad == 'object' && !(ad instanceof Array)) {
				// attr
				for(var a in ad) {
					if(a == 'element') {
						if(ad.element != null && typeof ad.element == 'object') {
							ad.element[typeof ad.elementId != 'undefined' ? ad.elementId : 'element'] = e;
						} else {
							ad.element = e;
						}
					} else if(a == 'elementId') {
						// Az "element" property feldolgozásánál kell.
					} else if(a == 'class') {
						e.className = ad[a];
					} else if(a == 'style') {
						if(is.ie) e.style.cssText = ad[a];
						else e.setAttribute('style', ad[a]);
					} else if(typeof ad.constructor.prototype[a] == 'undefined') {
//						e.setAttribute(a, ad[a]);
						e[a] = ad[a];
//						wxlog.log("attr0: " + a + ": " + e[a]);
					}
				}
				i = 2;
			}

			var e1;
			if(tag == "TABLE") {
				e1 = doc.createElement("TBODY");
				e.appendChild(e1);
			} else {
				e1 = e;
			}

			for(; i < jsonml.length; i++) {
				e1.appendChild(jsonML(jsonml[i]));
			}
		}
		return e;
	} else {
		// Text
		return doc.createTextNode(String(jsonml));
	}
}

/*
 * Tween segító osztály
 *
 *  eventfn = function(x, mode);
 *    x - az érték a pillanatnyi időpontban
 *    mode - 0: tick, 1: első tick, 2: utolsó tick
 */
function HTTween(eventFn, tween, time, step) {
	this.tstep = step || 40; // 25fps
	this.ttime = time || 200;
	this.eventFn = eventFn;
	this._tween = typeof tween == 'function' ? tween : (HTTween.tweens[tween] || HTTween.tweens.linear);
	this._x1 = false;
}

HTTween.tweens = {
	'linear': function(x) { return x; },
	'sinoidal': function(x) { return 0.5 - Math.cos(x * Math.PI) / 2; }
};

HTTween.T_START = 1;
HTTween.T_END = 2;
HTTween.T_TWEEN = 0;
HTTween.T_USER = -1;

HTTween.prototype = {
	_timer: false,

	_event: function(now, mode) {
		now = this._tween(now);
		now = this._x0 + (this._x1 - this._x0) * now;

//		console.log('now: %d %d', now, mode);

		this.eventFn(now, mode);
	},

	init: function(start, time) {
		if(this.isRunning()) {
			console.error("Hibás állapot. Nem lehet a HTTween.init() metódust meghívni.");
			return;
		}

		this._x1 = start;
		if(time) this.ttime = time;

		return this;
	},

	start: function(start, end, time) {
		var _this = this;

		time = time || this.ttime;

		if(this.isRunning()) {
			var n = this._x0 + (this._x1 - this._x0) * _now();
			if(n < start && n < end || n > start && n > end) {
				console.error("invalid now value: %d, %d, %d -> %d, %d, %d at %d / %d", this._x0, this._x1, this.ttime, start, end, time, _now(), this._tnow - this._t0);
				return;
			}
			this._t0 = this._tnow - time * (n - start) / (end - start);
		}

		this.ttime = time;
		this._x0 = start;
		this._x1 = end;

		if(this.isRunning()) {
			return this;
		}

		this._t0 = this._tnow = new Date().getTime();

		function _now() {
			var now = (_this._tnow - _this._t0) / _this.ttime;
			if(now < 0) {
				console.error("invalid now value: %d at %d / %d, t1: %d, t0: %d", now, this._tnow - this._t0, _this.ttime, this._tnow, this._t0);
				return;
			}
			return now > 1 ? 1 : now;
		}

		this._event(0, 1);
		this._timer = window.setInterval(function() {
			if(!_this.isRunning()) {
				console.warn("HTTween belső hiba: timer event kikapcsolt timernél.");
				return; // cancelled...
			}

			_this._tnow = new Date().getTime();
			var now = _now();

			if(now == 1) {
				_this._cancel();
			} else {
				_this._event(now, 0);
			}
		}, this.tstep);

		return this;
	},

	cont: function(end, time) {
		if(this._x1 === false) {
			console.error("Hibás állapot. Nem lehet a HTTween.cont() metódust meghívni.");
			return;
		}

		return this.start(this._x1, end, time);
	},

	isRunning: function() {
		return this._timer !== false;
	},

	_cancel: function() {
		window.clearInterval(this._timer);
		this._timer = false;
		this._event(1, 2);
	},

	cancel: function() {
		if(this.isRunning()) {
			this._cancel();
		}

		return this;
	},

	kill: function() {
		if(this.isRunning()) {
			window.clearInterval(this._timer);
			this._timer = false;
		}

		return this;
	}
}

