var fwDebug = false;

function myAlert(s) {
	if(fwDebug) {
		alert(s);
	}
}

//pro dedeni
function mix(parent, obj) {
	for(i in parent.prototype) {
		if(i in obj.prototype) continue;
		obj.prototype[i] = parent.prototype[i];
	}
}

//useful functions
var FunctionLibrary = function() {
}

//vyhledavani elementu podle ruznych kriterii
FunctionLibrary.prototype.getElementById = function(aID) {
	var elem = document.getElementById(aID);
	if(elem !== null) {
		return elem;
	} else {
		myAlert("Element of id: " + aID + " not found");
		return null;
	}
}
	
FunctionLibrary.prototype.deleteElementById = function(aID) {
	var remElem = this.getElementById(aID);
	this.deleteElement(remElem);
}
	
FunctionLibrary.prototype.deleteElement = function(remElem) {
	var parElem = remElem.parentNode;
	if(remElem !== null && parElem !== null) {
		parElem.removeChild(remElem);
	}
}
	
FunctionLibrary.prototype.getElementsByClassName = function(findClass) {
	var elems = document.body.getElementsByTagName("*");
	var ret = new Array();
	var i, j, classes;
	for(i = 0; i < elems.length; i++) {
		classes = elems[i].className.split(" ");
		for(j = 0; j < classes.length; j++) {
			if(classes[j] == findClass) {
				ret.push(elems[i]);
				break;
			}
		}
	}
	return ret;
}
	
FunctionLibrary.prototype.getElementsByClassNamePreg = function(findClass, all) {
	if(all !== false) {
		all = true;
	}
	var elems = document.body.getElementsByTagName("*");
	var ret = new Array();
	var i, j, matches, classes;
	for(i = 0; i < elems.length; i++) {
		classes = elems[i].className.split(" ");
		for(j = 0; j < classes.length; j++) {
			matches = classes[j].match(findClass);
			if(matches != null) {
				if(matches[0] == classes[j]) {
					ret.push(elems[i]);
					if(!all) {
						return ret;
					}
					break;
				}
			}
		}
	}
	return ret;
}

//--------------------------------------------------------------------------
	
FunctionLibrary.prototype.appendElem = function(aElem, aElemName) {
	var child = document.createElement(aElemName);
	aElem.appendChild(child);
	return child;
}
	
FunctionLibrary.prototype.swapElemetnts = function(aNew, aOld) {
	var parElem = aOld.parentNode;
	if(parElem !== null) {
		parElem.replaceChild(aNew, aOld);
		return aNew;
	} else {
		myAlert("Element requested to be replaced has no parent!");
	}
}
	
FunctionLibrary.prototype.clone = function(cloneID, insertID) {
	var cloneNode = this.getElementById(cloneID);
	var insertNode = this.getElementById(insertID);
	
	var elems = cloneNode.cloneNode(true);
	var i;
	var inputs = elems.getElementsByTagName("input");
	for(i in inputs) {
		inputs[i].value = "";
	}
	
	if(cloneNode !== null && insertNode !== null) {
		insertNode.appendChild(elems);
	}
}
	
FunctionLibrary.prototype.removeChildren = function(elem) {
	while(elem.childNodes.length >= 1) {
		elem.removeChild(elem.firstChild);       
	}
}
	
FunctionLibrary.prototype.moveChildren = function(elemOld, elemNew) {
	while(elemOld.firstChild != null) {
		elemNew.appendChild(elemOld.firstChild);
	}
}

//--------------------------------------------------------------------------
	
//round to certain number of decimal numbers
FunctionLibrary.prototype.roundNumber = function(num, dec) {
	var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
	return result;
}
	
//insert spaces afrer 3 nums
FunctionLibrary.prototype.formatNumber = function(nStr) {
	nStr += "";
	var rgx = /(\d+)(\d{3})/;
	while(rgx.test(nStr)) {
		nStr = nStr.replace(rgx, "$1" + " " + "$2");
	}
	return nStr;
}
	
/* TODO: dodelat max */
FunctionLibrary.prototype.getNumValById = function(aID, aMin) {
	var elem;
	if((elem = this.getElementById(aID)) !== null) {
		return this.getNumVal(elem, aVal);
	}	
}
	
FunctionLibrary.prototype.getNumVal = function(elem, aMin) {
	var val = obj.value;
		
	if(this.isNumeric(val)) {
		if(elem.value >= aMin) {
			return elem.value;
		} else {
			elem.value = aMin;
			return aMin;
		}
	} else {
		elem.value = aMin;
		return aMin;
	}	
}
	
FunctionLibrary.prototype.isNumeric = function(v) {
	return typeof v != "boolean" && v !== null && !isNaN(+ v);
}
	
FunctionLibrary.prototype.setValueById = function(aID, aVal) {
	var elem;
	if((elem = this.getElementById(aID)) !== null) {
		this.setValue(elem, aVal);
	}
}
	
FunctionLibrary.prototype.setValue = function(elem, aVal) {
	elem.value = aVal;
}
	
FunctionLibrary.prototype.setDisabledById = function(aID, aDisabled) {
	var elem;
	if((elem = this.getElementById(aID)) !== null) {
		this.setDisabled(elem, aDisabled);
	}
}
	
FunctionLibrary.prototype.setDisabled = function (elem, aDisabled) {
	if(aDisabled) {
		elem.disabled = "disabled";
	} else {
		elem.disabled = "";
	}
}

//prida do prvku select prvek option s value a title
FunctionLibrary.prototype.addOption = function(select, value, title) {
	var opt = document.createElement("option");
	opt.value = value;
	opt.innerHTML = title;
	select.appendChild(opt);
	return opt;
}
	
//prida do prvku select prvek option s value a title
FunctionLibrary.prototype.removeOptions = function(select, value, title) {
	var opt = document.createElement("option");
	opt.value = value;
	opt.innerHTML = title;
	select.appendChild(opt);
	return opt;
}
	
FunctionLibrary.prototype.removeOptions = function(select) {
	removeChildren(select);
}

//--------------------------------------------------------------------------
	
FunctionLibrary.prototype.postData = function(client, url, data, StateChange) {
	client.open('POST', url, true);
	client.onreadystatechange = StateChange;

	client.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	client.setRequestHeader("Content-length", data.length);
	client.send(data);
}
	
FunctionLibrary.prototype.parseJSON = function(data) {
	return eval('(' + data + ')');
}
	
//--------------------------------------------------------------------------
	
FunctionLibrary.prototype.setOpacity = function(elem, opac) {
	if(browser.isIE) {
		elem.style.filter = "alpha(opacity=" + opac + ")";
	} else {
		elem.style.opacity = opac / 100;
	}
}
	
FunctionLibrary.prototype.fadeElement = function(aElem, aOpacityStart, aOpacityEnd, aStep, aTimeStep, aCallback) {
	function doStep(aStart, aEnd, aStep) {
		if(aStart == aEnd) {
			return false;
		}
		return (aStart > aEnd) ? aStart - aStep : aStart + aStep;
	}
	
	function opacityStep() {
		if((newOpacity = doStep(current, aOpacityEnd, aStep)) !== false) {
			fLib.setOpacity(aElem, newOpacity);
			//myAlert(newOpacity)
			current = newOpacity;
			setTimeout(opacityStep, aTimeStep);
		} else {
			//uz je konec prechodu
			if(aCallback !== undefined) {
				aCallback();
			}
		}
	}
	
	setTimeout(opacityStep, aTimeStep);
	var current = aOpacityStart;
}
	
//nastavi vlastnost display a prepina ji mezi 2ma hodnotami
FunctionLibrary.prototype.toggleDisplayById = function(aID, aDefault, aNew) {
	var elem;
	if((elem = this.getElementById(aID)) !== null) {
		this.toggleDisplay(elem, aDefault, aNew);
	}
}
	
FunctionLibrary.prototype.toggleDisplay = function(elem, aDefault, aNew) {
	if(elem.style.display == "") {
		elem.style.display = aDefault;
	}
	if(elem.style.display == aDefault) {
		elem.style.display = aNew;
	} else {
		elem.style.display = aDefault;
	}
}
	
//nastavi vlastnost display
FunctionLibrary.prototype.setDisplayById = function(aID, aDisplay) {
	var elem;
	if((elem = this.getElementById(aID)) !== null) {
		this.setDisplay(elem, aDisplay);
	}
}
	
FunctionLibrary.prototype.setDisplay = function(elem, aDisplay) {
	elem.style.display = aDisplay;
}
	
FunctionLibrary.prototype.getStyle = function(elem, strCssRule) {
	var ret = "";
	if(document.defaultView && document.defaultView.getComputedStyle) {
		ret = document.defaultView.getComputedStyle(elem, null).getPropertyValue(strCssRule);
	} else if(elem.currentStyle) {
		strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1) {
			return p1.toUpperCase();
		});
		ret = elem.currentStyle[strCssRule];
	}
	return ret;
}
	
FunctionLibrary.prototype.getStyleById = function(aID, strCssRule) {
	var elem;
	if((elem = this.getElementById(aID)) !== null) {
		this.getStyle(elem, strCssRule);
	}
}

/**
 * vrati z CSS zapisu NNNpx ciselnou cast
 * 
 */
FunctionLibrary.prototype.getSizeInPx = function(s) {
	var matches = s.match(/([0-9\.]+)px/i);
	if(matches != null) {
		return Math.round(matches[1]);
	} else {
		return 0;
	}
}

FunctionLibrary.prototype.getElemWidth = function(elem) {
	var val = this.getSizeInPx(this.getStyle(elem, "width"));
	if(val == 0) {
		var bwidthL = parseInt(this.getSizeInPx(this.getStyle(elem, "border-left-width")));
		var bwidthR = parseInt(this.getSizeInPx(this.getStyle(elem, "border-right-width")));
		var paddingL = parseInt(this.getSizeInPx(this.getStyle(elem, "padding-left")));
		var paddingR = parseInt(this.getSizeInPx(this.getStyle(elem, "padding-right")));
		val = elem.offsetWidth - bwidthL - bwidthR - paddingL - paddingR;
		if(val < 0) {
			val = 0;
		}
	}
	return parseInt(val) + "px";
}
	
FunctionLibrary.prototype.getElemHeight = function(elem) {
	var val = this.getSizeInPx(this.getStyle(elem, "height"));
	//alert("CSS: " + this.getStyle(elem, "height") + " CSS H: " + val + " Offset: " + elem.offsetHeight);
	if(val == 0) {
		var bwidthT = parseInt(this.getSizeInPx(this.getStyle(elem, "border-top-width")));
		var bwidthB = parseInt(this.getSizeInPx(this.getStyle(elem, "border-bottom-width")));
		var paddingT = parseInt(this.getSizeInPx(this.getStyle(elem, "padding-top")));
		var paddingB = parseInt(this.getSizeInPx(this.getStyle(elem, "padding-bottom")));
		val = elem.offsetHeight - bwidthT - bwidthB - paddingT - paddingB;
		if(val < 0) {
			val = 0;
		}
	}
	return parseInt(val);
}

FunctionLibrary.prototype.getElemPadding = function(elem, dir) {
	return parseInt(this.getSizeInPx(this.getStyle(elem, "padding-" + dir)));
}
	
//--------------------------------------------------------------------------
	
//height of document
FunctionLibrary.prototype.getDocumentHeight = function() {
	return document.documentElement.scrollHeight;
}

//width of document
FunctionLibrary.prototype.getDocumentWidth = function() {
	return document.documentElement.scrollWidth;
}
	
//return scroll position
FunctionLibrary.prototype.getTopScroll = function() {
	if(window.pageYOffset) {
		return window.pageYOffset;
	} else {
		return document.documentElement.scrollTop;
	}
}
	
//height of viewport
FunctionLibrary.prototype.getWindowHeight = function() {
	if(window.innerHeight) {
		return window.innerHeight;
	} else {
		return document.documentElement.clientHeight;
	}
}
	
FunctionLibrary.prototype.getWindowWidth = function() {
	if(window.innerWidth) {
		return window.innerWidth;
	} else {
		return document.documentElement.clientWidth;
	}
}
	
FunctionLibrary.prototype.findPos = function(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}

//adds event to element
FunctionLibrary.prototype.addEvent = function(eventName, handler, object) {
	if(object.addEventListener) {
		object.addEventListener(eventName, handler, false);
	} else {
		object.attachEvent("on" + eventName, handler);
	}
}
	
//removes event from element
FunctionLibrary.prototype.removeEvent = function(eventName, handler, object) {
	if(object.removeEventListener) {
		object.removeEventListener(eventName, handler, false);
	} else {
		object.detachEvent("on" + eventName, handler);
	}
}
	
//mouse position
FunctionLibrary.prototype.getMousePositionX = function(e) {
	return e.clientX + document.documentElement.scrollLeft + document.body.scrollLeft;
}
	
FunctionLibrary.prototype.getMousePositionY = function(e) {
	return e.clientY + document.documentElement.scrollTop + document.body.scrollTop;
}
	
FunctionLibrary.prototype.getEventTarget = function(e) {
	if(!e)
		var e = window.event;

	if(e.target) {
		return e.target;
	} else if(e.srcElement) {
		return e.srcElement;
	}
}
	
FunctionLibrary.prototype.getEventCurrentTarget = function(e) {
	if(!e)
		var e = window.event;

	if(e.currentTarget) {
		return e.currentTarget;
	} else if(e.srcElement) {
		return null
	}
}
	
FunctionLibrary.prototype.stopPropagation = function(e) {
	if(!e)
		var e = window.event;
    e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; 
}
	
FunctionLibrary.prototype.arIndexOf = function(aArr, aElem) {
	var i = 0;
	for(i = 0; i < aArr.length; i++) {
		if(aArr[i] == aElem) {
			return i;
		}
	}
	return -1;
}
	
FunctionLibrary.prototype.strReplace = function(aSrc, aTar, s) {
	while(s.indexOf(aSrc) >= 0) {
		s = s.replace(aSrc, aTar);
	}
	return s;
}

FunctionLibrary.prototype.addClassName = function(elem, cl) {
	elem.className += " " + cl;
}

FunctionLibrary.prototype.addClassNameById = function(aID, cl) {
	this.findElemAndApply(aID, this.addClassName, [cl]);
}

FunctionLibrary.prototype.removeClassName = function(elem, cl) {
	var classes = elem.className.split(" ");
	var i;
	elem.className = "";
	for(i in classes) {
		if(classes[i] != cl) {
			elem.className += " " + classes[i];
		}
	}
}

FunctionLibrary.prototype.removeClassNameById = function(aID, cl) {
	return this.findElemAndApply(aID, this.removeClassName, [cl]);
}

FunctionLibrary.prototype.hasClassName = function(elem, cl) {
	var classes = elem.className.split(" ");
	return this.arIndexOf(classes, cl) != -1;
}

FunctionLibrary.prototype.hasClassNameById = function(aID, cl) {
	return this.findElemAndApply(aID, this.hasClassName, [cl]);
}

//------------------------------------------------------------------------------

FunctionLibrary.prototype.findElemAndApply = function(aID, fun) {
	var elem;
	var args = new Array();
	var i;
	if((elem = this.getElementById(arguments[0])) !== null) {
		args.push(elem);
		for(i = 2; i < arguments.length; i++) {
			args.push(arguments[i]);
		}
		return arguments[1].apply(this, args);
	}
}

//------------------------------------------------------------------------------

var Browser = function() {
	this.isIE = false;
	this.isNS = false;
	this.version = 0;
	
	if(navigator.appName == "Microsoft Internet Explorer") {
		this.isIE = true;
		
		var ua = navigator.userAgent;
		var re  = new RegExp("MSIE ([0-9]\{1,\}[\.0-9]\{0,\})");
	
		if((matches = re.exec(ua)) != null) {
			this.version = parseFloat(matches[1]);
		}
	}
	
	if(navigator.appName == "Netscape") {
		this.isNS = true;
		
		var ua = navigator.userAgent;
		var re = new RegExp("Firefox/([0-9].[0-9])");
		
		if((matches = re.exec(ua)) != null) {
			this.version = parseFloat(matches[1]);
		}
	}
	
}

//------------------------------------------------------------------------------

var browser = new Browser();
var fLib = new FunctionLibrary();