
var webdrivePopup = {
	
	currentPopup : null,
	
	initPopup : function(elem, event, isClicked) {
		var popup = null;
		var registerEvents = false;
		if (elem.firstChild != null && elem.firstChild.nodeType == 1/*element-node*/ && Element.hasClassName(elem.firstChild, 'popuptext')) {
			popup = eleme.firstChild;
		} else if (elem.nextSibling != null && elem.nextSibling.nodeType == 1/*element-node*/ && Element.hasClassName(elem.nextSibling, 'popuptext')) {
			popup = elem.nextSibling;
		} else {
			var relocated = webdrivePopup._relocateTitle(elem);
			if (relocated || (isClicked && elem._title)) {
				if (Element.hasClassName(elem, 'popupclick') != isClicked) return false;
				webdrivePopup._garbagePopup();
				var titlePopup = document.createElement('div');
				titlePopup.className = 'popuptext';
				webdrivePopup.currentPopup = titlePopup;
				webdrivePopup._positionPopup(event, elem);
				titlePopup.innerHTML = elem._title;
				elem.parentNode.appendChild(titlePopup);
				registerEvents = true;
			}
		}
		if (popup != null) {
			elem.title = '';
			if (Element.hasClassName(elem, 'popupclick') != isClicked) return false;
			if (popup.style.display != 'block') {
				webdrivePopup._garbagePopup();
				webdrivePopup.currentPopup = popup;
				webdrivePopup._positionPopup(event, elem);
				registerEvents = true;
			}
		}
		if (registerEvents) {
			if (Element.hasClassName(elem, 'popupmanual')) {
				Event.observe(webdrivePopup.currentPopup, 'click', webdrivePopup._garbagePopup);
			} else if (Element.hasClassName(elem, 'popupfixed')) {
				Event.observe(webdrivePopup.currentPopup, 'mouseout', webdrivePopup._garbagePopupOnLeave);
				Event.observe(webdrivePopup.currentPopup, 'click', webdrivePopup._garbagePopup);
			} else {
				Event.observe(elem, 'mousemove', webdrivePopup._repositionPopup);
				Event.observe(elem, 'mouseout', webdrivePopup._garbagePopup);
			}
		}
	},
	_relocateTitle : function(elem) {
		if (elem._title && elem._title != '') return true;
		if (elem.title && elem.title != '') {
			elem._title = elem.title;
			elem.title = '';
			return true;
		}
		return false;
	},
	_positionPopup : function(event, elem) {
		webdrivePopup.currentPopup.style.position = 'absolute';
		webdrivePopup._repositionPopup(event, elem);
		webdrivePopup.currentPopup.style.display = 'block';
	},
	_repositionPopup : function(event, elem) {
		var e = elem ? elem : this;
		var isRight = Element.hasClassName(e, 'popupright');
		if (isRight) {
			var bodyWidth = parseInt(document.getElementsByTagName('body')[0].offsetWidth);
			var posRight = bodyWidth - Event.pointerX(event);
			webdrivePopup.currentPopup.style.right = posRight+'px';
		} else {
			webdrivePopup.currentPopup.style.left = Event.pointerX(event)+'px';
		}
		var offsetY = 13;
		if (Element.hasClassName(elem, 'popupfixed')) offsetY = 5;
		webdrivePopup.currentPopup.style.top = (Event.pointerY(event)+offsetY)+'px';
	},
	_garbagePopup : function() {
		if (webdrivePopup.currentPopup != null) {
			webdrivePopup.currentPopup.style.display = 'none';
			// deregister event listeners
			webdrivePopup.currentPopup = null;
		}
	},
	_garbagePopupOnLeave : function(event) {
		var within = Position.within(this, Event.pointerX(event), Event.pointerY(event));
		if (!within) webdrivePopup._garbagePopup();
	}
}

var evtRules = {
	'.popup:mouseover' : function(elem, event) {
		webdrivePopup.initPopup(elem, event, false);
	},
	'.popup:click' : function(elem, event) {
		webdrivePopup.initPopup(elem, event, true);
	},
	'.popup[title]:mouseover': function(elem, event) {
		webdrivePopup.initPopup(elem, event, false);
	},
	'.popup[title]:click': function(elem, event) {
		webdrivePopup.initPopup(elem, event, true);
	}
};

var webdrive = {
	
	init : function() {
		EventSelectors.start(evtRules);
		
		document.getElementsByClassName('ifvForm').each(function (form) {
			form.getElements().each(function (element) {
				Event.observe(element, 'change', webdrive.ifvTrigger);
			})
		});
	},
	
	updatePopup : function(element, message) {
		$(element).title = message;
		var popup = $(element).firstChild;
		if ((popup != null) && (popup.nodeType == 1) && (Element.hasClassName(popup, 'popuptext'))) {
			Element.update(popup, message);
		}
		popup = $(element).nextSibling;
		if ((popup != null) && (popup.nodeType == 1) && (Element.hasClassName(popup, 'popuptext'))) {
			Element.update(popup, message);
		}
	},
	
	ifvTrigger : function(event) {
		if (Event.element(event).form['ifvForm']) {
			var values = {serialized: Event.element(event).form.serialize()};
			webdrive.callJsonRpc('form.InstantValidator::validate', values, webdrive.ifvHandler);
		}
	},
	
	ifvHandler : function(t) {
		var res = t.responseText.evalJSON(true);
		if (res.error) return;
		
		for (var name in res.result['errors']) {
			if (typeof(res.result['errors'][name]) == 'function' ) continue;
			var element = $('formRow'+name);
			var msg = '';
			if (res.result['errors'][name]) {
				Element.addClassName(element, 'error');
				msg = Resource.translate(res.result['errors'][name].key, res.result['errors'][name].attributes);
			} else {
				Element.removeClassName(element, 'error');
			}
			webdrive.updatePopup('formError'+name, msg);
		}
	},
	
	reapply : function() {
		EventSelectors.assign(evtRules);
	},
	
	callJsonRpc : function(method, params, handler) {
		if (!params) params = null;
		var options = {method: 'post', postBody: Object.toJSON({method: method, params: params, id: new Date().getTime()})};
		if (handler) options.onSuccess = handler;
		new Ajax.Request(getAdmRoot()+'jsonrpc.do', options);
		return true;
	}
	
}

Event.observe(window, 'load', webdrive.init);

var Resource = new Object();
Object.extend(Resource, {
	
	resource: {},
	
	addBundle : function(bundle) {
		for (var key in bundle) {
			var value = bundle[key];
			if (typeof value == 'function') continue;
			this.resource[key] = value;
		}
	},
	
	translate: function(key, attributes) {
		if (this.resource[key] == undefined) {
			var str = '['+key;
			for (var k in attributes) {
				var value = attributes[k];
				if (typeof value == 'function') continue;
				str += ' '+k+':'+value;
			}
			return str+']';
		}
		var str = this.resource[key];
		
		str = str.replace(/\[b\](.*)\[\/b\]/ig, '<b>$1</b>');
		str = str.replace(/\[i\](.*)\[\/i\]/ig, '<i>$1</i>');
		str = str.replace(/\[u\](.*)\[\/u\]/ig, '<u>$1</u>');
		
		for (var k in attributes) {
			var pattern = '{' + k + '}';
			var value = attributes[k];
			var l = pattern.length;
			var p = str.indexOf(pattern);
			while (p != -1) {
				var q = p + l;
				str = str.substr(0, p) + value + str.substr(q);
				p = str.indexOf(pattern, q);
			}
		}
		return str;
	},
	
	hasKey: function(key) {
		return this.resource[key] != undefined;
	}
	
});

var Sitemap = new Object();
Object.extend(Sitemap, {
	
	mapping: {},
	devSrv: false,
	webBase: '',
	webAbsBase: '',
	base: '',
	prefix: '',
	
	setMapping : function(map) {
		for (var key in map) {
			var value = map[key];
			if (typeof value == 'function') continue;
			this.mapping[key] = value;
		}
	},
	
	setDevSrv : function(mode) {
		this.devSrv = mode;
	},
	
	setWebBase : function(base) {
		this.webBase = base;
	},
	
	setWebAbsBase : function(base) {
		this.webAbsBase = base;
	},
	
	setBase : function(base) {
		this.base = base;
	},
	
	setPrefix : function(prefix) {
		this.prefix = prefix;
	},
	
	getAbsLink : function(url) {
		if ((url != '') && (url.substr(0, 1) == '/')) url = url.substr(1);
		
		var extern = false;
		var pos = url.indexOf('/');
		if (!this.devSrvMode && pos != -1) {
			var prefix = url.substr(0, pos);
			if (this.mapping[prefix] != undefined) {
				var domain = this.mapping[prefix];
				url = 'http://'+domain+url.substr(pos);
				extern = true;
			}
		}
		if (!extern) {
			url = this.webAbsBase+url;
		}
		return url;
	},
	
	getRelLink : function(url) {
		var a = this.base.split('/');
		a.pop();
		
		var b = url.split('/');
		var i = 0;
		for (i = 0; i < b.length; i++) {
			if (b[i] == '..') a.pop();
			else if (b[i] != '.') a.push(b[i]);
		}
		
		var b = this.webBase;
		if (!this.devSrv) {
			var p = a.shift();
			if (p != this.prefix) {
				b = 'http://'+this.mapping[p]+'/';
			}
		}
		
		url = b + a.join('/');
		return url;
	}
	
});

Sitemap.setBase(getAdmRoot());

function formatSize(size) {
	var i = 0;
	while (size > 1024) {
		size = size / 1024;
		i++;
	}
	
	var q = 100;
	if (size > 100) q = 1;
	else if (size > 10) q = 10;
	size = parseInt(Math.round(size * q)) / q;
	
	var suffix = ' B';
	if (i == 1) suffix = ' KB';
	else if (i == 2) suffix = ' MB';
	else if (i == 3) suffix = ' GB';
	else if (i == 4) suffix = ' TB';
	
	return size + suffix;
}

function decodeBase64Id(str) {
	var cs = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
	str = str.replace(/:/g, '');
	var length = str.length;
	var d = '';
	var i = 0;
	while (i < length) {
		var e1 = cs.indexOf(str.charAt(i++));
		var e2 = cs.indexOf(str.charAt(i++));
		var e3 = cs.indexOf(str.charAt(i++));
		var e4 = cs.indexOf(str.charAt(i++));
		d += String.fromCharCode((e1 << 2) | (e2 >> 4));
		d += String.fromCharCode(((e2 & 15) << 4) | (e3 >> 2));
		d += String.fromCharCode(((e3 & 3) << 6) | (e4));
	}
	if (length % 4 == 2) d = d.substr(0, d.length - 2);
	else if (length % 4 == 3) d = d.substr(0, d.length - 1);
	return d;
}

function encodeBase64Id(str) {
	var cs = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
	var length = str.length;
	var d = '';
	var i = 0;
	while (length >= i + 3) {
		var b = (str.charCodeAt(i++) & 0xff) << 16 | (str.charCodeAt(i++) & 0xff) << 8  | str.charCodeAt(i++) & 0xff;
		d += cs.charAt((b & 0xfc0000) >> 18);
		d += cs.charAt((b & 0x03f000) >> 12);
		d += cs.charAt((b & 0x000fc0) >> 6);
		d += cs.charAt((b & 0x00003f));
	}
	if (length - i > 0) {
		var dual = (length - i) == 2;
		var b = ((str.charCodeAt(i++) & 0xff) << 16) | (dual ? (str.charCodeAt(i) & 0xff) << 8 : 0);
		d += cs.charAt((b & 0xfc0000) >> 18);
		d += cs.charAt((b & 0x03f000) >> 12);
		if (dual) d += cs.charAt((b & 0x000fc0) >> 6);
	}
	return d;
}

function xmlentities(str) {
	return str.replace(/&/g, '&amp;').replace(/"/g,'&quot;').replace(/'/g,'&apos;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

function confirmForward(msg, url) {
	if (confirm(msg)) location.href = url;
	return false;
}

