/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/

var Base64 = {

	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;

		input = Base64._utf8_encode(input);

		while (i < input.length) {

			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

		}

		return output;
	},

	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;

		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		while (i < input.length) {

			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}

		}

		output = Base64._utf8_decode(output);

		return output;

	},

	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while ( i < utftext.length ) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}

}


var CheckForm = {
	
	toNameValueDict: function(formData) {
		var out = {}
		for (var key = 0; key < formData.length; key++) {
			name = formData[key].name;
			if (formData[key].type == 'checkbox') {
				val = formData[key].checked;
			} else if (formData[key].type == 'radio') {
				if (typeof(out[name]) == 'undefined') {
					out[name] = '';
				}
				if (formData[key].checked) {
					val = formData[key].value;
				} else {
					continue;
				}
			} else {
				val = formData[key].value;
			}
			out[name] = val;
		}
		return out;
	},
	
	getData: function(id, cls) {
		var node = document.getElementById(id);
		var list = getElementsByClassName(node, '*', cls)
		return list;
	},
	
	// vraci seznam klicu, ktere jsou spatne
	checkTypes: function(formData, typeList) {
		var key, name, val;
		var out = []
		for (var key = 0; key < typeList.length; key++) {
			name = key;
			val = new String(trim(formData[name]));
			if (! typeList[name].call(null, val)) {
				out.push(name);
			}
		}
		return out;
	},
	
	
	checkMandatory: function(formData, mandatoryList) {
		var name;
		var out = []
		for (key = 0; key < mandatoryList.length; key++) {
			name = mandatoryList[key];
			val = new String(trim(formData[name]));
			if (val.length == 0) {
				out.push(name);
			}
		}
		return out;
	},
	
	
	getErrorMsg: function(badKeys, titles, template) {
		out = '';
		for (key = 0; key < badKeys.length; key++) {
			var titleKey = badKeys[key];
			if (typeof(titles[titleKey]) == 'undefined') {
				window.alert('CheckForm.getErrorMsg() - v titles neni klic [' + titleKey + ']');
			}
			var data = {
				'name': titles[titleKey]
			}
			out += WSmarty.compile(template, data) + "\n";
		}
		return out;

	}
}

function dump(val) {
	var out = '';
	for (var key in val) {
		alert(typeof(key));
		out += key + ':' + val[key] + "\n";
	} 
	alert(out);
}

function __postUrl(args) {
	var code = args[0];
	var parVal = []
	parVal.push(CODE_LIST[code]);
	args[0] = null;
	for (var i = 0; i < args.length; i++) {
		var _key = args[i];
		if (_key === null) {
			continue;
		}
		parVal.push(_key);
	}
	
	linkPar = []
	for (var i = 0; i < parVal.length; i++) {
		linkPar.push(encodeURIComponent(parVal[i]));
	}
	var link = PHP_SELF;
	if (linkPar.length) {
		link += linkPar.join("/");
	}
	return link + '/';
}


function makeUrl() {
	var args = makeUrl.arguments;
	var link = __postUrl(args);
	return link + '?client=1';
}


function postUrl() {
	var args = postUrl.arguments;
	return __postUrl(args);
}


function redirUrl() {
	var args = redirUrl.arguments;
	return __postUrl(args) + URL_HASH;
}

function pageUrl() {
	var args = pageUrl.arguments;
	var last = args.length - 1;
	var page = args[last];
	args[last] = null;
	return __postUrl(args) + '?page=' + page;
}

function isNull(variable) {
	return (typeof(variable) == 'undefined' || variable === null);
}

function getElementsByClassName(oElm, strTagName, oClassNames){
	var arrElements = (strTagName === '*' && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = new Array();
	var arrRegExpClassNames = new Array();
	if(typeof oClassNames == "object"){
		for(var i=0; i<oClassNames.length; i++){
			arrRegExpClassNames.push(new RegExp("(^|\s)" + oClassNames[i].replace(/-/g, "\-") + "(\s|$)"));
		}
	}
	else{
		arrRegExpClassNames.push(new RegExp("(^|\s)" + oClassNames.replace(/-/g, "\-") + "(\s|$)"));
	}
	var oElement;
	var bMatchesAll;
	for(var j=0; j<arrElements.length; j++){
		oElement = arrElements[j];
		bMatchesAll = true;
		for(var k=0; k<arrRegExpClassNames.length; k++){
			if(!arrRegExpClassNames[k].test(oElement.className)){
				bMatchesAll = false;
				break;
			}
		}
		if(bMatchesAll){
			arrReturnElements.push(oElement);
		}
	}
	return (arrReturnElements)
}


function trim(stringToTrim) {
	return stringToTrim;
	//return stringToTrim.replace('/^\s+|\s+$/g',"");
}


function isSet(val) {
	return ! isNull(val);
}



function Dict(arr) {
	var dict;
	var list;
	var dictList;
	var position;
	
	this.__construct = function(arr) {		
		this.dict = new Array();
		this.list = new XList();
		this.dictList = new Array();
		this.reset();
		
		if (! isNull(arr)) {
			this.update(arr);
		}
		
	}
	
	this.set = function(key, value) {
		if (isNull(key)) {
			throw "Undefined parameter [key]";
		}
		
		if (isNull(this.dictList[key]) ) {
			this.dictList[key] = this.list.length();
			this.list.set(key);
		}
		this.dict[key] = value;
	}
	
	
	this.get = function(key, defaultValue) {
		if (this.hasKey(key)) {
			return this.dict[key];
		}
		if (! isNull(defaultValue)) {
			return defaultValue;
		}
		throw "Class Dict: Key [" + key + "] doesnt exists";
	}
	
	this.hasKey = function(key) {
		return ! isNull(this.dict[key]);
	}
	
	
	this.update = function(arr) {
		var key;
		for (key in arr) {
			this.set(key, arr[key]);
		}
	}
	
	this.length = function() {
		return this.list.length();
	}

	
	this.toString = function() {
		var index;
		var data = this.dict;
		var out = '';
		for (key in data) {
			out += key + ':' + data[key] + "\n";
		}
		return out;
	}
	
	
	this.getKeys = function() {
		var out = new XList();
		var origPosition = this.position;
		var keyValue;
		
		this.reset();
		while (this.hasNext()) {
			keyValue = this.nextItem();
			out.set(keyValue[0]);
		}
		this.position = origPosition;
		return out;
	}
	
	
	this.__export = function() {
		return this.dict;
	}
	
	this.hasNext = function() {		
		return this.position < this.list.length();
	}

	
	this.next = function() {
		var key = this.list.get(this.position);
		this.position ++;
		return key;
	}
	
	
	this.nextItem = function() {
		var key = this.next();
		return new Array(key, this.dict[key]);
	}
	
	
	this.reset = function() {
		this.position = 0;
	}
	
	
	this.sortValues = function() {
		var keys = new Array();
		var list = this.list.__export();
		
		for (key in list) {
			this.keys.push(key);
		}
		keys.sort();
		alert(keys.toString());
		
	}
	

	this.__construct(arr);
}





var InputCheck = {
	types: {
		decimal: function(val) {
			var re = new RegExp("^-?\\d+\\(.|,)\\d*$");
  			return re.test(trim(value));
		},
		emailDue: function(val) {
			var re = new RegExp("^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}$");
			return re.test(trim(val));
		},
		url: function(val) {
			var re = new RegExp('^([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)?((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.[a-zA-Z]{2,4})(\:[0-9]+)?(/[^/][a-zA-Z0-9\.\,\?\'\\/\+&%\$#\=~_\-@]*)*$');
			return re.test(val);
		},
		postalCode: function(val) {
			var re = new RegExp('^\\d{3} ?\\d{2}$');
			return re.test(trim(val));
		},
		phoneNumber: function(val) {
			var _val = trim(val);
			if (! val.length) {
				return true;
			}
			var re = new RegExp('^(\\+420)? ?[0-9]{3} ?[0-9]{3} ?[0-9]{3}$');
			return re.test(trim(val));
		},
		userName: function(val) {
			var re = new RegExp('^[a-zA-Z0-9._]{5,50}$');
			return re.test(trim(val));
		}
	},
	setEventCallback: function(idDom, events, func) {
		var evn;
		var element = document.getElementById(idDom);
		var help;
		for (var i = 0; i < events.length; i++) {
			help = events[i];
			//alert("element." + events[evn] + " = " + func + ";");
			eval("element." + help + " = " + func);
		}
	}
}



function XList() {
	var xl;
	var position;


	this.__construct = function() {
		this.xl = new Array();
		this.reset();
	}


	this.set = function(value) {
		if (isNull(value)) {
			throw "Undefined parameter [value] - Xlist";
		}
		this.xl[this.length()] = value;
	}


	this.reset = function() {
		this.position = 0;
	}


	this.hasNext = function() {
		return this.position < this.length();
	}


	this.next = function() {
		var key = this.position;
		this.position ++;
		return key;
	}
	
	
	this.nextItem = function() {
		var key = this.next();
		return new Array(key, this.xl[key]);
	}

	
	this.length = function() {
		return this.xl.length;
	}
	
	
	this.get = function(index, defaultValue) {
		if (this.exist(index)) {
			return this.xl[index];
		}
		if (! isNull(defaultValue)) {
			return defaultValue;
		}
		throw "Index doesnt exists";
	}
	
	this.exist = function(index) {
		return ! isNull(this.xl[index]);
	}
	
	
	this.has = function(value) {
		var index;
		
		for (index in this.xl) {
			if (this.xl[index] == value) {
				return true;
			}
		}
		return false;
	}
	
	
	this.toString = function() {
		var index;
		var out = '';
		for (index in this.xl) {
			out += index + ':' + this.xl[index] + "\n";
		}
		return out;
	}
	
	
	this.__export = function() {
		return this.xl;
	}
	
	
	this.__construct();
}


function HttpJsonResponse(conn) {
	var conn;
	var responseData;
	var errorMessage;
	
	this.__init = function(conn) {
		this.setConn(conn);
	}
	
	
	this.setConn = function(conn) {
		this.conn = conn;
		this.responseData = null;
	}
	
	
	this.load = function() {
		var responseData;
		try {
			responseData = eval('(' + this.responseText() + ')');
			this.responseData = new Dict(responseData);
			return true;
		} catch (err) {
			this.errorMessage = err.toString();
			return false;
		}
	}
	
	
	this.getResponseData = function() {
		return this.responseData;
	}
	
	
	this.responseText = function() {
		return this.conn.responseText;
	}
	
	
	this.doWhen = function(key, value, action) {
		if (this.responseData.hasKey(key)) {
			if (this.responseData.get(key) == value) {
				eval(action);
			}
		}
	}
	
	
	this.__init(conn);
}


var WSmarty = {}

WSmarty.compile = function (tpl, dict) {
	var re = new RegExp("{\\$[a-zA-Z0-9]+}", 'g');
	var keys;
	var key, baseKey;
	var i = 0;
	var out = new String(tpl);
	
	while(key = re.exec(tpl)) {
		baseKey = key[0];
		key = baseKey.substring(2, baseKey.length - 1);
		if (typeof(dict[key]) == 'undefined') {
			window.alert('Chyba WSmarty.compile: TPL obsahuje klic [' + key + '], ale ten neni v dict');
			return '';
		}
		out = out.replace(baseKey, dict[key]);
		i ++;
		if (i > 200) {
			window.alert('Asi zacykleni v WSmarty.compile');
			return;
		}
	}
	return out;
}


WSmarty.putInto = function(idDom, tpl, dict) {
	document.getElementById(idDom).innerHTML = this.compile(tpl, dict);
}

WSmarty.__error = function(message) {
	window.alert('CHYBA: ' + message);
}

var WHttp = {
	
}


WHttp.__callback = function(data) {
	var key = 'success';
	if (data['upload']) {
		key = 'upload';
	}
	var out = {
		'failure': function (response) {
			window.alert('HTTP ERROR');
		}
	}
	out[key] = data['success'];
	return out;
}


WHttp.get = function(data) {
	return YAHOO.util.Connect.asyncRequest("GET", data['url'], this.__callback(data));
}


WHttp.post = function(data, idDom) {
	var upload = (data['upload'] ? true : false);
	if (data['preLoadAction']) {
		data['preLoadAction'].apply();
	}
	YAHOO.util.Connect.setForm(document.getElementById(idDom), upload);
	return YAHOO.util.Connect.asyncRequest("POST", data['url'], this.__callback(data));
}

