/**
 * SJF - Simple Javascript Framework by Ikeris
 * This file contains common utilities and basic javascript functions
 * Some functions are carried out by other authors and contain appropriate description
 * Use this free for any non-commercial and commercial products
 *
 * @version 0.23
 */


/**
 * Events add, remove and find event target
 */
function addEvent(obj, type, fn){
	if (obj.addEventListener){
		obj.addEventListener( type, fn, false );
	}
	else if (obj.attachEvent){
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); };
		obj.attachEvent( "on"+type, obj[type+fn] );
	}
}

function removeEvent(obj, type, fn){
	if (obj.removeEventListener){
		obj.removeEventListener( type, fn, false );
	}
	else if (obj.detachEvent){
		obj.detachEvent( "on"+type, obj[type+fn] );
		obj[type+fn] = null;
		obj["e"+type+fn] = null;
	}
}
function eventTarget(event){
	var elem;
	if (window.event) {
		elem = window.event.srcElement;
	} else if (event) {
		elem = event.target;
	}
	if (elem.nodeType == 3) {
		elem = elem.parentNode;
	}
	return elem;
}
/**
 * Function isEventSupported
 * Detecting event support without browser sniffing
 * 
 * @author Juriy Zaytsev
 * @example isEventSupported(mousedown) return true, if supported by browser 
 */
var isEventSupported = (function(){
	var TAGNAMES = {
		'select':'input','change':'input',
		'submit':'form','reset':'form',
		'error':'img','load':'img','abort':'img'
	}
	function isEventSupported(eventName){
		var el = document.createElement(TAGNAMES[eventName] || 'div');
		eventName = 'on' + eventName;
		// IE skips "unload" and WebKit - "unload" and "resize" - when using "setAttribute" "in" catches these offenders
		var isSupported = (eventName in el);
			if (!isSupported){
				el.setAttribute(eventName, 'return;');
				isSupported = typeof el[eventName] == 'function';
			}
		el = null;
		return isSupported;
	}
	return isEventSupported;
})();

/**
 * Function: DOMinnerHTML is an alternative function to innerHTML. Since
 * it's not a standard, it isn't terribly future proof. It's not supposed to
 * work under the application/xhtml+xml MIME type that XHTML documents are
 * supposed to be served under.
 * innerHTML is a string. The DOM is not a string, it's a hierarchal object
 * structure. Shoving a string into an object is impure and similar to wrapping
 * a spaghetti noodle around an orange and calling it lunch.
 * $param $element - the DOM element where the HTML will be loaded
 * $param $HTML - the string of valid HTML code
 * $param $firstclear - is an optional argument - set it to false to keep the existing child nodes and append the new HTML below them
 */
function DOMinnerHTML(element, HTML, firstclear) {

	// load the HTML as XML
	function Load(xmlString) {
		var xml;
		if (typeof DOMParser != "undefined"){
			xml = (new DOMParser()).parseFromString(xmlString, "application/xml");
		}
		else {
			var ieDOM = [ "MSXML2.DOMDocument", "MSXML.DOMDocument",
					"Microsoft.XMLDOM" ];
			for ( var i = 0; i < ieDOM.length && !xml; i++) {
				try {
					xml = new ActiveXObject(ieDOM[i]);
					xml.loadXML(xmlString);
				} catch (e) {
				}
			}
		}
		return xml;
	}

	// recursively copy the XML into the DOM
	function Copy(domNode, xmlDoc, level) {

		if (typeof level == "undefined") {
			level = 1;
		}
		if (level > 1) {

			if (xmlDoc.nodeType == 1) {

				// element node
				var thisNode = document.createElement(xmlDoc.nodeName);

				// attributes
				for ( var a = 0, attr = xmlDoc.attributes.length; a < attr; a++) {
					var aName = xmlDoc.attributes[a].name, aValue = xmlDoc.attributes[a].value, evt = (aName.substr(0, 2) == "on");
					if (!evt) {
						switch (aName) {
						case "class":
							thisNode.className = aValue;
							break;
						case "for":
							thisNode.htmlFor = aValue;
							break;
						default:
							thisNode.setAttribute(aName, aValue);
						}
					}
				}

				// append node
				domNode = domNode.appendChild(thisNode);

				// attach event
				if (evt){
					domNode[aName] = function() {
						eval(aValue);
					};
				}
			} else if (xmlDoc.nodeType == 3) {
				// text node
				var text = (xmlDoc.nodeValue ? xmlDoc.nodeValue : "");
				var test = text.replace(/^\s*|\s*$/g, "");
				if (test.length < 7 || (test.indexOf("<!--") !== 0 && test.indexOf("-->") != (test.length - 3))){
					domNode.appendChild(document.createTextNode(text));
				}
			}
		}

		// do child nodes
		for ( var i = 0, j = xmlDoc.childNodes.length; i < j; i++){
			Copy(domNode, xmlDoc.childNodes[i], level + 1);
		}
	}

	// load the XML and copies to DOM
	HTML = "<root>" + HTML + "</root>";
	var xmlDoc = Load(HTML);
	if (element && xmlDoc) {
		if (firstclear !== false){
			while (element.lastChild){
				element.removeChild(element.lastChild);
			}
		}
		Copy(element, xmlDoc.documentElement);
	}
}

/**
 * Get URL from string and add parameters
 */
// Adding parameters to current URL
function addParamToCurrentURL(param) {
	var currentURL = location.protocol + "//" + location.host + location.pathname + location.search;
	return (location.search !== '') ? currentURL + "&" + param + location.hash : currentURL + "?" + param + location.hash;
}

// Create new current URL + params
function addParamMakeNewURL(param) {
	var currentURL = location.protocol + "//" + location.host + location.pathname;
	return currentURL + "?" + param + location.hash;
}

// Adding parameters to the URL
function addParamToURL(url, params) {
	return (url.indexOf("?") > 0) ? url + "&" + params : url + "?" + params;
}

// Create new URL without any filenames, but with current URL, path, no files and add params
function addParamMakeNewURL2(param) {
	var currentURL = location.protocol + "//" + location.host + location.pathname.slice(0,location.pathname.lastIndexOf('/')+1);
	return currentURL + "?" + param + location.hash;
}

function getValueFromURLparam(name, url){
	name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]"+name+"=([^&#]*)";
	var regex = new RegExp( regexS );
	var results = regex.exec(url);
	return (results === null) ? "" : results[1];
}

// do weryfikacji!!!
function getURL(aUrl) {
	var param;
	if (aUrl.indexOf("?") > 0) {
		param = aUrl + '&';
	} else {
		param = aUrl + '?';
	}
	return param;
}

/**
 * Cookies: set, get, delete and test if cookies enabled
 *
 * Set
 * @param $name name of cookie
 * @param $value value of cookie
 * @param $days expiration days
 *
 * Get
 * @param $name name of cookie
 *
 * Erase
 * @param $name name of cookie
 *
 * Enabled
 * @param none, return null, if cookies are not enabled
 */
var Cookie = {
	set : function(name, value, days) {
		var expires;
		if (days) {
			var date = new Date();
			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
			expires = "; expires=" + date.toGMTString();
		} else {
			expires = "";
		}
		document.cookie = name + "=" + value + expires + "; path=/";
	},
	get : function(name) {
		name += "=";
		var s = document.cookie.split("; ");
		for ( var i = 0; i < s.length; i++) {
			var c = s[i];
			if (c.indexOf(name) === 0) {
				return unescape(c.substring(name.length, c.length));
			}
		}
		return null;
	},
	erase : function(name) {
		this.set(name, "", -1);
	},
	enabled : function() {
		this.set("cookietest", "cookietest");
		return this.get("cookietest") !== null;
	}
};

/**
 * Cross browser detect internet browser name and version
 */
var Browser = {
	userAgent :navigator.userAgent,
	appName :navigator.appName,

	IE :!!(window.attachEvent && !window.opera),
	OP :!!window.opera,
	FF :navigator.userAgent.indexOf("Gecko") > -1 && navigator.userAgent.indexOf("KHTML") == (-1) && navigator.userAgent.indexOf("Firefox") > 0,
	NN :navigator.appName == "Netscape",
	SF :navigator.userAgent.indexOf("Safari") > 0,
	Gecko :navigator.userAgent.indexOf("Gecko") > -1 && navigator.userAgent.indexOf("KHTML") == (-1),

	// Get name
	getBrowserName : function() {
		if (this.IE) {
			return "IE";
		} else if (this.OP) {
			return "OP";
		} else if (this.FF) {
			return "FF";
		} else if (this.SF) {
			return "SF";
		} else if (this.Gecko) {
			return "GK";
		}
		return false;
	},
	// IE version
	getIEVersion : function() {
		if (this.IE) {
			var IEVer = this.userAgent.substring(this.userAgent.indexOf(
					"MSIE ", 0));
			IEVer = IEVer.substring(5, IEVer.indexOf(";"));
			return parseFloat(IEVer);
		} else {
			return false;
		}
	}
};

/**
 * DOM functions
 * The DOM Level 2 supports XML namespaces [Namespaces] by augmenting several
 * interfaces of the DOM Level 1 Core to allow creating and manipulating
 * elements and attributes associated to a namespace.
 *
 * The new methods, such as createElementNS and createAttributeNS
 * of the Document interface, are meant to be used by namespace aware applications.
 * Simple applications that do not use namespaces can use the DOM Level 1 methods,
 * such as createElement and createAttribute. Elements and attributes created in this way
 * do not have any namespace prefix, namespace URI, or local name.
 *
 * @link http://www.w3.org/TR/DOM-Level-2-Core/core.html#Namespaces-Considerations
 */
function createElement(element){
	if (typeof document.createElementNS != 'undefined') {
		return document.createElementNS('http://www.w3.org/1999/xhtml', element);
	}
	if (typeof document.createElement != 'undefined') {
		return document.createElement(element);
	}
	return false;
}

function setAttribute(element, name, value){
	if (typeof element.setAttributeNS != 'undefined'){
		return element.setAttributeNS('http://www.w3.org/1999/xhtml', name, value);
	}
	else if (typeof element.setAttribute != 'undefined'){
		return element.setAttribute(name, value);
	}
	return false;
}

/**
 * Function findElement
 * Automatically find the element, regardless of whether they provide an object id, or it will have a reference to the object.
 *
 * @param  $elementId name or reference to element
 * @return reference to element or false if the object does not exist
 */
function _getElementById(elementId){
	var n = (typeof elementId == "string") ? document.getElementById(elementId) : elementId;
	return n;
}

/**
 * Function removeElement
 * Function remove fast element with all childs
 *
 * @param  $element name or reference to element
 * @return remove all child elements and element
 */
function removeElement(element) {
	var elm = _getElementById(element);
	if(!elm){ return false; }
	var e = elm.cloneNode(false);
	elm.parentNode.replaceChild(e, elm);
	elm = e;
	elm.parentNode.removeChild(elm);
}

/**
 * Function removeElementNodes
 * Function fast remove all nodes in element
 *
 * @param  element name or reference to element
 * @return clear all nodes in element
 */
function removeElementNodes(element) {
	var elm = _getElementById(element);
	if(!elm){ return false; }
	var e = elm.cloneNode(false);
	elm.parentNode.replaceChild(e, elm);
	elm = e;
}
/**
 * Function follows closely in the DOM tree at the top and is given an element parentTagName.
 * @param element A name of element or reference to element
 * @param parentTagName A tag name of parent element
 */
function findParentElement(element, parentTagName){
	var elm = _getElementById(element);
	if(!elm){ return false; }
	while(elm.nodeName.toLowerCase() !== parentTagName){
		elm = elm.parentNode;
	}
	return elm;
}

/**
 * Function replaceHtml
 * Fast adding (x)html content using standard Document Object Model instead innerHTML
 * @param content param must be a DOM content
 */
function replaceHtml(el, html) {
	var oldEl = typeof el === "string" ? document.getElementById(el) : el;
	/*@cc_on // Pure innerHTML is slightly faster in IE
		oldEl.innerHTML = html;
		return oldEl;
	@*/
	var newEl = oldEl.cloneNode(false);
	newEl.innerHTML = html;
	oldEl.parentNode.replaceChild(newEl, oldEl);
	/* Since we just removed the old element from the DOM, return a reference
	to the new element, which can be used to restore variable references. */
	return newEl;
}

/**
 * Function getInnerText
 * Get inner text from element
 * @param $elem the element from which you want to get text
 */
function getInnerText(elem){
	return (elem.innerText || elem.textContent);
}
/**
 * Function setInnerText
 * Get inner text from element
 * @param $elem the element to which you want to set text
 * @param $text the text
 */
function setInnerText(elem, text){
	if(typeof(elem.innerText) != 'undefined'){
		elem.innerText = text;
	}
	else if(typeof(elem.textContent) != 'undefined'){
		elem.textContent = text;
	}
}

/**
 * Function insertAfter
 * Add new element after selected element
 * @param newElement element to be added
 * @param targetElement the element after which you want to add a new element
 */
function _insertAfter(newElement,targetElement){
	//target is what you want it to go after. Look for this elements parent.
	var parent = targetElement.parentNode;
	
	//if the parents lastchild is the targetElement...
	if(parent.lastchild == targetElement){
		//add the newElement after the target element.
		parent.appendChild(newElement);
	}
	else {
		// else the target has siblings, insert the new element between the target and it's next sibling.
		parent.insertBefore(newElement, targetElement.nextSibling);
	}
}

/**
 * Function addStyleSheet
 * Adding dynamically styles
 * @param href url to stylesheet
 * @param media specify media type
 */
function addStyleSheet(href, media) {
	var headElement = document.getElementsByTagName('head')[0];
	var linkElement = document.createElement('link');
	media = (media === undefined ? 'all' : media);
	linkElement.setAttribute('type', 'text/css');
	linkElement.setAttribute('rel', 'stylesheet');
	linkElement.setAttribute('href', href);
	linkElement.setAttribute('media', media);
	headElement.appendChild(linkElement);
}

/**
 * Function findLabel
 * Find label by ID element
 * @param inputElementID id of element, eg. input
 */
function findLabel(element) {
	var elm = _getElementById(element);
	if(!elm){ return false; }

	var findLabels = document.getElementsByTagName('label');
	if (!findLabels) { return false; }
	var i = findLabels.length;
	while (i--) {
		if((findLabels[i].getAttribute("for") || findLabels[i].htmlFor) === elm.id){
			return findLabels[i];
		}
	}
	return false;
}
/**
 * Function trim
 * Fast strip whitespace from the beginning and end of a string
 * @param str string
 * @author Luca Guidi
 */
function trim(str) {
	if (String(str) == "undefined" || str === "") {
		return "";
	}
	var ws = /\s/, _start = 0, end = str.length;
	while(ws.test(str.charAt(_start++)));
	while(ws.test(str.charAt(--end)));
	return str.slice(_start - 1, end + 1);
}
/**
 * Function isEmpty
 * Check, if object is emtpy
 * @param obj object
 * @return true, if object is empty
 */
function isEmpty(obj) {
	var p;

	if(!obj || typeof obj !== "object") {
		return true;
	}
	for(p in obj) {
		if(obj.hasOwnProperty(p)) {
			return false;
		}
	}
	return true;
}
/**
 * Function htmlspecialchars
 * @param str string
 */
function htmlspecialchars(str) {
	if (typeof str != 'string') {
		return;
	}
	return str.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\&/g, '&amp;').replace(/"/g, '&quot;'); // "
}

/**
 * Corrected getElementById, that returns incorrect objects in IE and Opera
 * fix both IE and Opera (adjust when they implement this method properly)
 * http://www.sixteensmallstones.org/ie-javascript-bugs-overriding-internet-explorers-documentgetelementbyid-to-be-w3c-compliant-exposes-an-additional-bug-in-getattributes
 */
if ((Browser.getBrowserName() == 'OP') || (Browser.getBrowserName() == 'IE')) {
	document.nativeGetElementById = document.getElementById;
	document.getElementById = function(id) {
		var elem = document.nativeGetElementById(id);
		if (elem) {
			// make sure that it is a valid match on id
			if (elem.attributes.id.value == id) {
				return elem;
			} else {
				// otherwise find the correct element
				var i = 1;
				var len = document.all[id].length;
				while(i<len){
					if (document.all[id][i].attributes.id.value == id) {
						return document.all[id][i];
					}
					i++;
				}
			}
		}
		return null;
	};
}

/**
 * Function str_replace
 * This function returns a string or an array with all occurrences of
 * [search] in [subject] replaced with the given [replace] value.
 * 
 * @param $search search for string
 * @param $replace replace to string
 * @param $subject complete input string
 *
 * @example str_replace(' ', '.', 'This is framework'); returns: 'This.is.framework'
 * @example str_replace(['{name}', 'l'], ['hello', 'm'], '{name}, lars'); returns: 'hemmo, mars'
 */

function str_replace (search, replace, subject){
	var result = "";
	var oldi = 0;
	for(i = subject.indexOf (search); i > -1; i = subject.indexOf(search, i)){
		result += subject.substring (oldi, i);
		result += replace;
		i += search.length;
		oldi = i;
	}
	return result + subject.substring (oldi, subject.length);
}

// Full clone node
/*
 * Element.implement({
 *
 * clone: function(contents, keepid){ contents = contents !== false; var clone =
 * this.cloneNode(contents); var clean = function(node, element){ if (!keepid)
 * node.removeAttribute('id'); if (Browser.Engine.trident){
 * node.clearAttributes(); node.mergeAttributes(element);
 * node.removeAttribute('uid'); if (node.options){ var no = node.options, eo =
 * element.options; for (var j = no.length; j--;) no[j].selected =
 * eo[j].selected; } } var prop = props[element.tagName.toLowerCase()]; if (prop &&
 * element[prop]) node[prop] = element[prop]; };
 *
 * if (contents){ var ce = clone.getElementsByTagName('*'), te =
 * this.getElementsByTagName('*'); for (var i = ce.length; i--;) clean(ce[i],
 * te[i]); }
 *
 * clean(clone, this); return $(clone); } });
 */

/**
 * Function redirect
 * @param url new URL
 * @param params parameters in URL
 * @param anchor
 */
var redirect = {
	tourl : function(url,params,anchor){
		document.location.href = redirect.buildNewUrl(url,params)+(anchor?anchor:'');
	},
	buildNewUrl : function(url,params){
		var pairs = [];
		var result = url;
		if(params){
			for(var key in params){
				pairs.push(key+"="+encodeURIComponent(params[key].toString()));
			}
			if(pairs.length){
				result += "?"+pairs.join("&");
			}
		}
		return result;
	}
};

// **** CSS functions ****

//************************************************************************
// Check if object have class name
//************************************************************************
/**
 * Check, if object have a class name
 * @param element element id or object
 */
function hasClass(element, className){
	var elm = _getElementById(element);
	if(!elm){ return false; }

	if (typeof elm.className != "undefined" || elm.getAttribute("class") !== null && elm) {
		return new RegExp('(^|\\s)' + className + '(\\s|$)').test(elm.className || elm.getAttribute("class"));
	}
	return false;
}
/**
 * Function remove class name from object
 * @param e object
 * @param name class name
 */
function delClass(e, name) {
	return e && (e.className = e.className.replace(new RegExp('^' + name + '\\b\\s*|\\s*\\b' + name + '\\b', 'g'), ''));
}
/**
 * Function add class name to object
 * @param e object
 * @param name class name
 */
function addClass(e, name) {
	if (typeof e == "string") {
		e = document.getElementById(e);
	}
	if(!new RegExp(("(^|\\s)" + name + "(\\s|$)"), "i").test(e.className)){
		return e && (e.className += (e.className ? ' ' : '') + name);
	}
}
/**
 * Function replaceClass
 * If there is a class1, to replace it for class2. If not, do not do anything.
 * @param e object
 * @param class1 first class name
 * @param class2 second class name
 */
function replaceClass(e, class1, class2) {
	if (typeof e == "string") {
		e = document.getElementById(e);
	}
	if (hasClass(e, class1)) {
		delClass(e, class1);
		addClass(e, class2);
		return true;
	} else {
		return false;
	}
}
/**
 * Function toggle class in object
 * @param e object
 * @param nameOfClass name of new class
 */
function toggleClass(e, nameOfClass) {
	if (typeof e == "string") {
		e = document.getElementById(e);
	}
	if (hasClass(e, nameOfClass)) {
		delClass(e, nameOfClass);
	} else {
		addClass(e, nameOfClass);
	}

	return true;
}
/**
 * Function swapClass
 * Replacing classes at the facility. If you are class1, remove it and save class2. If it is class2, remove it and save class1.
 * @param class1 name of class1
 * @param class2 name of class2
 */
function swapClass(e, class1, class2) {
	e = _getElementById(e);
	if(!e){ return false; }
	if (hasClass(e, class1)) {
		delClass(e, class1);
		addClass(e, class2);
		return class2;
	} else {
		delClass(e, class2);
		addClass(e, class1);
		return class1;
	}
}

/**
 * Function get style from object
 * @param element object
 * @param styleProp define style, for example "width"
 */
function getStyleProp(element, styleProp) {

	// Check type of object
	var el;
	if(typeof element === "string"){ el = document.getElementById(element); }
	else if(typeof element === "object" && element !== null){ el = element; }
	else { return false; }

	var y;
	if (el.currentStyle) {
		y = el.currentStyle[styleProp];
	} else if (window.getComputedStyle) {
		y = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
	}
	return y;
}
/**
 * Function set style properties
 * @param el object
 * @param style defined style
 * @param value value of defined style
 */
function setStyleProp(el, style, value){
	if (el.filters && (typeof style === "string"? /opacity/i.test(style) : style.opacity)) {
		el.style.filter = "alpha(opacity=" + (value || style.opacity || 1) * 100 + ")";
	}
	if (typeof el.style.cssText !== "undefined") {
		var styleToSet = el.style.cssText;
		if (typeof style === "object") {
			for (var i in style) {
				if (typeof i === "string") {
					styleToSet += ";" + i + ":" + style[i];
				}
			}
		}
		else {
			styleToSet += ";" + style + ":" + value;
		}
		el.style.cssText = styleToSet;
	}
	return el;
}
/**
 * Function setOpacity
 *
 */
function setOpacity(obj){
	// IE/Win
	obj.style.filter = "alpha(opacity=" + (obj.oOpacity * 100) + ")";
	// Safari<1.2, Konqueror
	obj.style.KHTMLOpacity = obj.oOpacity;
	// Older Mozilla and Firefox
	obj.style.MozOpacity = obj.oOpacity;
	// Safari 1.2, newer Firefox and Mozilla, CSS3
	obj.style.opacity = obj.oOpacity;
}

/**
 * Function getElementsByClassName
 * Utilize native getElementsByClassName support if its available. Utilize
 * native XPath support if its available. Support multiple class names in the
 * same call, in any order specified. Return an actual array to work with,
 * instead of just the native nodelists.
 *
 * Parameters
 *
 * @param className One or several class names, separated by space. Multiple class
 * names demands that each match have all of the classes specified. Mandatory.
 * @param tag Specifies the tag name of the elements to match. Optional. @elm
 * Reference to a DOM element to look amongst its children for matches.
 * Recommended for better performance in larger documents. Optional.
 *
 * Call examples
 *
 * To get all elements in the document with a "info-links" class.
 * getElementsByClassName("info-links"); To get all div elements within the
 * element named "container", with a "col" class. getElementsByClassName("col",
 * "div", document.getElementById("container")); To get all elements within in
 * the document with a "click-me" and a "sure-thang" class.
 * getElementsByClassName("click-me sure-thang");
 *
 * Code by Robert Nyman
 */
var getElementsByClassName = function(className, tag, elm) {
	if (document.getElementsByClassName) {
		getElementsByClassName = function(className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className), nodeName = (tag) ? new RegExp("\\b" + tag + "\\b", "i") : null, returnElements = [], current;
			var i = elements.length;
			while (i--)
			{
				current = elements[i];
				if (!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	} else if (document.evaluate) {
		getElementsByClassName = function(className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "), classesToCheck = "", xhtmlNamespace = "http://www.w3.org/1999/xhtml", namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace) ? xhtmlNamespace : null, returnElements = [], elements, node;
			for ( var j = 0, jl = classes.length; j < jl; j += 1) {
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			} catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	} else {
		getElementsByClassName = function(className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "), classesToCheck = [], elements = (tag === "*" && elm.all) ? elm.all : elm.getElementsByTagName(tag), current, returnElements = [], match;
			for ( var k = 0, kl = classes.length; k < kl; k += 1) {
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for ( var l = 0, ll = elements.length; l < ll; l += 1) {
				current = elements[l];
				match = false;
				for ( var m = 0, ml = classesToCheck.length; m < ml; m += 1) {
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};

/**
 * Function getElementsByAttribute
 *
 * @param oElm Param is mandatory. This is element in whose children you will look for the attribute
 * @param strTagName Mandatory. This is the name of the HTML elements you want to look in. Use wildcard (*) if you want to look in all elements.
 * @param strAttributeName Mandatory. The name of the attribute youre looking for.
 * @param strAttributeValue: Optional. If you want the attribute youre looking for to have a certain value as well.
 */
function getElementsByAttribute(oElm, strTagName, strAttributeName, strAttributeValue) {
	var arrElements = (strTagName == "*" && oElm.all) ? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = [];
	var oAttributeValue = (typeof strAttributeValue != "undefined") ? new RegExp("(^|\\s)" + strAttributeValue + "(\\s|$)") : null;
	var oCurrent;
	var oAttribute;
	for ( var i = 0; i < arrElements.length; i++) {
		oCurrent = arrElements[i];
		oAttribute = oCurrent.getAttribute && oCurrent.getAttribute(strAttributeName);
		if (typeof oAttribute == "string" && oAttribute.length > 0) {
			if (typeof strAttributeValue == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))) {
				arrReturnElements.push(oCurrent);
			}
		}
	}
	return arrReturnElements;
}
/**
 * Function getElementsByTagNames
 * @param list list of objects separated by comma (,)
 * @param obj root object, if none then will be document
 * @return array with objects
 *
 * @example var e = getElementsByTagNames("h1,h2");
 */
function getElementsByTagNames(list, obj) {
	if (!obj){ obj = document; }
	var tagNames = list.split(',');
	var resultArray = [];
	var j, i = tagNames.length;
	while (i--) {
		var tags = obj.getElementsByTagName(tagNames[i]);
		for ( var j = 0; j < tags.length; j++) {
			resultArray.push(tags[j]);
		}
	}
	var testNode = resultArray[0];
	if (!testNode){
		return [];
	}
	if (testNode.sourceIndex) {
		resultArray.sort( function(a, b) {
			return a.sourceIndex - b.sourceIndex;
		});
	} else if (testNode.compareDocumentPosition) {
		resultArray.sort( function(a, b) {
			return 3 - (a.compareDocumentPosition(b) & 6);
		});
	}
	return resultArray;
}
/**
 * Function getElementsByTagNameAndClass
 *
 * @param tag tag name
 * @param className class name
 * @param parentEl parent element; if none, then will be document
 * @return array with objects
 * @example getElementsByTagNameAndClass('DIV','mainmenu',content);
 */
function getElementsByTagNameAndClass(tag,className,parentEl){
	var elms = (parentEl?parentEl:document).getElementsByTagName(tag);
	var results = [];
	var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
	for(var i=0;i<elms.length;i++){
		if(re.test(elms[i].className)){
			results.push(elms[i]);
		}
	}
	return results;
}

//************************************************************************
// Arrays utilities
//************************************************************************
/**
 * Function in_array
 * Checks if the given key or index exists in the array
 * 
 * @example in_array('crm', {'crm': 'helpdesk'}); returns true
 */
function in_array(needle, haystack, argStrict){
    var found = false, key, strict = !!argStrict;

    for (key in haystack) {
        if ((strict && haystack[key] === needle) || (!strict && haystack[key] == needle)) {
            found = true;
            break;
        }
    }
    return found;
}

//************************************************************************
//	Window utilities
//************************************************************************

/**
 * Function getElementPosition
 * Get element position
 * @param element object or id of object
 * @return array of x,y position or false, if object not exists
 */
function getElementPosition(element){
	var elm;

	if(typeof element === "string"){ elm = document.getElementById(element); }
	else if(typeof element === "object" && element !== null){ elm = element; }
	else { return false; }

	var leftCoord = 0;
	var topCoord = 0;
	if (elm.offsetParent) {
		do
		{
			leftCoord += elm.offsetLeft;
			topCoord += elm.offsetTop;
		}
		while (elm == elm.offsetParent);
		return [leftCoord, topCoord];
	}
}
/**
 * Function findCenterPosition
 * Find center position for element
 * @param element object or object id
 * @return array of top and left position of positioned element
 */
function findCenterPosition(element) {
	var elm;

	if(typeof element === "string"){ elm = document.getElementById(element); }
	else if(typeof element === "object" && element !== null){ elm = element; }
	else { return false; }

	var viewport = getPageSize();
	var left = (viewport[2] === 0) ? 50 : parseInt((viewport[2] - elm.offsetWidth) / 2, 10);
	var top = (viewport[3] === 0) ? 50 : parseInt((viewport[3] - elm.offsetHeight) / 2, 10);
	return [top, left];
}

/**
 * Function getPageSize
 * Get page size of viewport. Viewport is the space within the browser window.
 * @return: array with page width, height and window width, height
 */
function getPageSize() {

	var xScroll, yScroll, pageWidth, pageHeight;
	var arrayPageSize = [];

	if (window.innerHeight && window.scrollMaxY) {
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight) { // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}

	var windowWidth, windowHeight;
	if (self.innerHeight) { // all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}

	// for small pages with total height less then height of the viewport
	if (yScroll < windowHeight) {
		pageHeight = windowHeight;
	} else {
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if (xScroll < windowWidth) {
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}

	arrayPageSize = [ pageWidth, pageHeight, windowWidth, windowHeight ];
	return arrayPageSize;
}
/**
 * Function dragLayer
 * @param none Just add class "dragdrop" do element to make them draggable.
 */
var dragdrop = {
	i		:	0,
	isIE	:	/*@cc_on!@*/false,
	xDelta	:	0,
	yDelta	:	0,
	xStart	:	0,
	yStart	:	0,
	tar		:	null,
	elems	:	[],
	elemsize	:	[],

	init : function(elm){
		var elms = (elm !== null || elm !== '') ? [document.getElementById(elm)] : getElementsByClassName("dragdrop");
		i = elms.length;
		var dragel;

		if(i < 1){ return false; } // there is no elements with class "dragdrop"
		var curleft, curtop;
		while(i--){
			//elms[i].onmousedown = dragdrop.drag; // A mouse button is pressed
			addEvent(elms[i], 'mousedown', dragdrop.drag);

			dragdrop.elems.push(elms[i]); // save reference to object
			//dragdrop.elemsize.push(elms[i].offsetWidth); // save width of current object method #1
			dragdrop.elemsize.push(getStyleProp(elms[i],"width")); // save width of current object method #2
			//dragdrop.elemsize.push(elms[i].offsetHeight); // save height of current object method #1
			dragdrop.elemsize.push(getStyleProp(elms[i],"height")); // save height of current object method #1

			// create element to drag
			dragel = document.createElement("span");
			elms[i].appendChild(dragel);
		}
	},

	// mouse button is pressed
	drag : function(e){
		//tar = eventTarget(e);
		tar = dragdrop.elems[0];
		tar.style.cursor = "-moz-grabbing";
		tar.style.position = "absolute";
		tar.style.width = dragdrop.elemsize[0]+"px";
		tar.style.height = dragdrop.elemsize[1]+"px";

		var e = e || window.event;
		dragdrop.xStart = parseInt(e.clientX);
		dragdrop.yStart = parseInt(e.clientY);

		tar.style.top = tar.offsetTop + "px";
		tar.style.left = tar.offsetLeft + "px";

		addEvent(document, 'mousemove', dragdrop.move);
		addEvent(document, 'mouseup', dragdrop.drop);

		//document.onmousemove = dragdrop.move; // The mouse is moved
		//document.onmouseup = dragdrop.drop; // A mouse button is released

		// focus used for accessibility improve
		tar.focus();

		return false;
	},

	move : function(e){
		//tar = eventTarget(e); // get target element from event
		tar = dragdrop.elems[0];
		e = e || window.event;

		dragdrop.xDelta = dragdrop.xStart - parseInt(e.clientX);
		dragdrop.yDelta = dragdrop.yStart - parseInt(e.clientY);
		dragdrop.xStart = parseInt(e.clientX);
		dragdrop.yStart = parseInt(e.clientY);
		tar.style.top = (parseInt(tar.style.top) - dragdrop.yDelta) + "px";
		tar.style.left = (parseInt(tar.style.left) - dragdrop.xDelta) + "px";
	},

	drop : function(e){
		tar = dragdrop.elems[0];
		tar.style.cursor = "auto";

		//removeEvent(tar, 'mousedown', dragdrop.drag);
		removeEvent(document, 'mousemove', dragdrop.move);
		removeEvent(document, 'mouseup', dragdrop.drop);

		//document.onmouseup = null;
		//document.onmousemove = null;
	}
};
/**
 * Function getScrollXY
 * Finding how far the window has been scrolled
 * @return array with scroll of X and Y
 */
function getScrollXY() {
	var scrOfX = 0, scrOfY = 0;
	if (typeof (window.pageYOffset) == 'number') {
		// Netscape compliant
		scrOfY = window.pageYOffset;
		scrOfX = window.pageXOffset;
	} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
		// DOM compliant
		scrOfY = document.body.scrollTop;
		scrOfX = document.body.scrollLeft;
	} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
		// IE6 standards compliant mode
		scrOfY = document.documentElement.scrollTop;
		scrOfX = document.documentElement.scrollLeft;
	}
	return [ scrOfX, scrOfY ];
}

//************************************************************************
// 	Forms and elements
//************************************************************************

//************************************************************************
// Function to make text size increase and decrease
//************************************************************************
// Params: none

// Initialise font size from cookies, if exists
function setInitTextSize() {
	if (!document.body || !document.body.style) {
		return;
	}
	if (Cookie.get("fontvalue") !== null && Cookie.get("fontsize") !== null) {
		document.getElementsByTagName('body')[0].style.fontSize = Cookie.get("fontvalue") + Cookie.get("fontsize");
	}
}
// Resize body text
function textSize(size) {

	if (!document.body || !document.body.style) {
		return;
	}
	var SizeCurrent;
	var CurrentValue;
	var CurrentUnit;
	var x;
	var body = document.getElementsByTagName('body')[0];

	if (body.style && body.style.fontSize) {
		SizeCurrent = body.style.fontSize;
	} else if (typeof (getComputedStyle) != 'undefined') {
		SizeCurrent = getComputedStyle(body, '').getPropertyValue('font-size');
	} else if (body.currentStyle) {
		SizeCurrent = body.currentStyle.fontSize;
	}

	x = /([\d.]+)(.+)/.exec(SizeCurrent);
	CurrentValue = x[1];
	CurrentUnit = x[2];

	// Zoom in
	if (size == "bigger") {
		switch (CurrentUnit) {
		case '%':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		case 'em':
			CurrentValue = parseFloat(CurrentValue) + 0.1;
			break;
		case 'ex':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		case 'pc':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		case 'pt':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		case 'px':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		case 'in':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		case 'mm':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		case 'cm':
			CurrentValue = parseFloat(CurrentValue) + 1;
			break;
		}
	}
	if (size == "smaller") {
		switch (CurrentUnit) {
		case '%':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		case 'em':
			CurrentValue = parseFloat(CurrentValue) - 0.1;
			break;
		case 'ex':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		case 'pc':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		case 'pt':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		case 'px':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		case 'in':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		case 'mm':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		case 'cm':
			CurrentValue = parseFloat(CurrentValue) - 1;
			break;
		}

	}
	// Save font settings: value and size
	if (Cookie.enabled()) {
		Cookie.set("fontvalue", CurrentValue);
		Cookie.set("fontsize", CurrentUnit);
	}
	body.style.fontSize = CurrentValue + CurrentUnit;
	return;
}

// Zoom
function textplus() {
	var tp;
	tp = document.getElementById('text-increase');
	if (!tp || !document.body || !document.body.style) {
		return;
	}
	tp.onclick = function() {
		textSize('bigger');
		return false;
	};
}
function textminus() {
	var tm;
	tm = document.getElementById('text-decrease');
	if (!tm || !document.body || !document.body.style) {
		return;
	}
	tm.onclick = function() {
		textSize('smaller');
		return false;
	};
}

//************************************************************************
// Keeping Compact Forms Accessible
// Based on code Roger Johansson (http://www.456bereastreet.com/)
//	@params:
//	overlabel - a classname for <label>
//	for parentNode from <label> set position:relative;
//************************************************************************
function hideLabel(field_id, hide) {
	var field_for;
	var labels = document.getElementsByTagName('label');
	for ( var i = 0; i < labels.length; i++) {
		field_for = labels[i].htmlFor || labels[i].getAttribute('for');
		if (field_for == field_id) {
			labels[i].style.textIndent = (hide) ? '-2000px' : '0px';
			return true;
		}
	}
	return false;
}

function overFocus() {
	hideLabel(this.getAttribute('id'), true);
}
function overBlur() {
	if (this.value === '') {
		hideLabel(this.getAttribute('id'), false);
	}
}
function overHandleClick() {
	var id, field;
	id = this.getAttribute('for');
	if (id && (field = document.getElementById(id))) {
		field.focus();
	}
}

function initOverLabels() {
	if (!document.getElementById) {
		return;
	}

	var labels, id, field;

	// Set focus and blur handlers to hide and show
	// LABELs with 'overlabel' class names.
	labels = document.getElementsByTagName('label');
	if (!labels) {
		return false;
	}
	var i = labels.length;
	while (i--) {

		if (hasClass(labels[i], "overlabel")) {

			// Skip labels that do not have a named association
			// with another field.
			id = labels[i].htmlFor || labels[i].getAttribute('for');
			if (!id || !(field = document.getElementById(id))) {
				continue;
			}

			// Change the applied class to hover the label
			// over the form field.
			addClass(labels[i], "overlabel-apply");
			// Hide any fields having an initial value.
			if (field.value !== '') {
				hideLabel(field.getAttribute('id'), true);
			}
			// Set handlers to show and hide labels.
			field.onfocus = overFocus;
			field.onblur = overBlur;

			// Handle clicks to LABEL elements (for Safari).
			labels[i].onclick = overHandleClick;
		}
	}
}

/**
 * Function externalLinks
 * Set attribute and value to element to make site open in new window.
 * You can set a width and height of window by add params to url.
 * @param $wwidth set wwidth param to set width of window opening
 * @param $wheight set wheight param to set height of window opening
 * @example <a class="external" href="...&wwidth=300&wheight=400">Open in new window</a>
 */
var externalLinks = {
	openWin : function(e) {
		var event = (!e) ? window.event : e;
		if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) {
			return true;
		} else {
			
			// Get params of width and height from URL, if exists
			var oWidth = getValueFromURLparam("wwidth",this.href);
			var oHeight = getValueFromURLparam("wheight",this.href);
			
			if(getValueFromURLparam("center",this.href) == "true"){
				var left = (oWidth === null) ? "" : ",left="+((window.screen.width/2) - parseInt(oWidth/2, 10));
				var top = (oHeight === null) ? "" : ",top="+((window.screen.height/2) - parseInt(oHeight/2, 10));
			}
			var oWidth = (oWidth === null) ? "" : ",width="+oWidth;
			var oHeight = (oHeight === null) ? "" : ",height="+oHeight;

			var tools = "resizable,toolbar=no,location=no,scrollbars=no"+oWidth+oHeight+left+top;
			
			//alert(tools);
			var oWin = window.open(this.getAttribute('href'), '_blank', tools);
			if (oWin) {
				if (oWin.focus) {
					oWin.focus();
				}
			}
			return false;
		}
		oWin = null;
		return true;
	},
	init : function(attr, val) {
		var d = document;
		if (!d.getElementById || !d.createElement || !d.appendChild) { return false; }
		var strAttr = ((typeof attr == 'undefined') || (attr === null)) ? 'class' : attr;
		var strVal = ((typeof val == 'undefined') || (val === null)) ? 'non-html' : val;
		var strWarning = ((typeof warning == 'undefined') || (warning === null)) ? ' (nowe okno)' : warning;

		var oWarning;
		var arrLinks = document.links;
		var oLink;
		var oRegExp = new RegExp("(^|\\s)" + strVal + "(\\s|$)");
		for ( var i = 0; i < arrLinks.length; i++) {
			oLink = arrLinks[i];
			if ((strAttr == 'class') && oRegExp.test(oLink.className) || oRegExp.test(oLink.getAttribute(strAttr))) {
				oWarning = document.createElement("em");
				addClass(oWarning,"external_link_info");
				oWarning.appendChild(document.createTextNode(strWarning));
				//oLink.appendChild(oWarning); // insert text to link
				oLink.parentNode.insertBefore( oWarning, oLink.nextSibling ); // insert text after link
				oLink.onclick = externalLinks.openWin;
			}
		}
	}
};

//************************************************************************
// Zebra tables
//************************************************************************
// Find elements table with "zebra" class and make zebra styles on table
// In CSS specify class even for even tr color
function zebraTables() {
	var tables = getElementsByClassName("zebra", "table");
	if (tables.length < 1) {
		return false;
	}

	for ( var x = 0; x != tables.length; x++) {
		var table = tables[x];

		var tbodies = table.getElementsByTagName("tbody");
		for ( var h = 0; h < tbodies.length; h++) {
			var even = false;
			var trs = tbodies[h].getElementsByTagName("tr");
			for ( var i = 0; i < trs.length; i++) {
				if (even) {
					if (!hasClass(trs[i], "even")) {
						addClass(trs[i], "even");
					}
				}
				even = !even;
			}
		}
	}
}
//************************************************************************
// Zebra lists
//************************************************************************
// Find elements ol, ul with "zebralist" class and make zebra styles on list
// In CSS specify class even for even li color
function zebraLists() {
	var d = document;
	if (!d.getElementById || !d.getElementsByTagName) {
		return;
	}

	var lists = getElementsByTagNames('ol,ul');
	for ( var i = 0; i < lists.length; i++) {

		if (hasClass(lists[i], "zebralist")) {
			var j = 0;
			var itemCount = 0;
			var end = lists[i].childNodes.length;
			var even = false;

			while (j < end) {
				if (lists[i].childNodes[j].nodeName.toLowerCase() == "li") {
					if(even === true){
						addClass(lists[i].childNodes[j], "even");
					}
					even = !even;
					itemCount++;
				}
				j++;
			}
		}
	}
}

/**
 * Add automatically resizer for textarea
 */
var textareaResizer = {
	i	:	0,
	init : function() {
		var taelms = getElementsByClassName("resizer","textarea");
		var i = taelms.length;
		if (i < 1) { return false; } // no elements and exit
		var events = ['keydown','paste','cut','focus','dragend','drop'];

		// Attach events
		var events = ['keydown','paste','cut','focus','dragend','drop'];
		var j = events.length;

		while(i--){
			var k = j;
			while(k--){
				addEvent(taelms[i], events[k], textareaResizer.doresize);
			}
			addClass(taelms[i], "resizer"); // We don't want scrollbars flashing in and out, so we add some style for hide them.
		}
	},

	doresize : function(e){
		var tar = eventTarget(e);
		setTimeout(function() {
			textareaResizer.resize(tar);
		}, 50);
	},

	resize : function(tar){
		//shrink to fit
		if (tar.clientHeight >= tar.scrollHeight && tar.clientHeight > tar.defaultMinHeight){
			tar.style.height = tar.defaultMinHeight + 'px';
		}

		//grow
		if(tar.clientHeight < tar.scrollHeight){
			tar.style.height = tar.scrollHeight + "px";
		}
	}
};

//************************************************************************
// Add unobtrusive print link
//************************************************************************
// Give target element (targetEl) and target (targetText) text for print button
// The function generate <li><a href="#">Print text</li>
function addPrintLink(targetEl, targetText) {
	if (!document.getElementById || !document.createTextNode) {
		return;
	} // Check for DOM support
	if (!document.getElementById(targetEl)) {
		return;
	} // Check that the target element actually exists
	if (!window.print && (typeof window.print != "function")) {
		return;
	} // Check that the browser supports window.print
	var targetElement = document.getElementById(targetEl).getElementsByTagName(
			"li")[2];

	var li = document.createElement('li');
	var oLink = document.createElement('a');
	var oB = document.createElement('b');
	var oB2 = document.createElement('b');
	li.id = 'printbutton'; // Give the link an id to allow styling
	oLink.href = '#'; // Make the link focusable for keyboard users

	oLink.appendChild(oB2);
	oB2.appendChild(oB);
	oB.appendChild(document.createTextNode(targetText));

	oLink.onclick = function() {
		window.print();
		return false;
	}; // Return false prevents the browser from following the link and jumping to the top of the page after printing
	li.appendChild(oLink);
	targetElement.parentNode.insertBefore(li, targetElement);
}

//************************************************************************
// Check NIP, REGON, PESEL, Passport value
//************************************************************************
/**
 * Functions checkNIP, checkRegon, checkPeselNo, checkPassportNo
 */

var verificator_nip = [ 6, 5, 7, 2, 3, 4, 5, 6, 7 ];
var verificator_regon = [ 8, 9, 2, 3, 4, 5, 6, 7 ];
var verificator_pesel = [ 1, 3, 7, 9, 1, 3, 7, 9, 1, 3 ];

function checkNIP(a) {
	a = a.replace(/[^0-9]/g, '');
	if (a.length != 10) {
		return false;
	}
	var i, n;
	for (i = n = 0; i < 9; i++) {
		n += a.charAt(i) * verificator_nip[i];
	}
	n %= 11;
	return (n == a.charAt(9));
}

function checkRegon(a) {
	if (a.search(/[^0-9]/) >= 0 || a.length != 9) {
		return false;
	}
	var i, n;
	for (i = n = 0; i < 8; i++) {
		n += a.charAt(i) * verificator_regon[i];
	}
	n %= 11;
	return (n == a.charAt(8));
}

function checkPeselNo(a) {
	if (a.search(/[^0-9]/) >= 0 || a.length != 11) {
		return false;
	}
	var i, n;
	for (i = n = 0; i < 10; i++) {
		n += a.charAt(i) * verificator_pesel[i];
	}
	n %= 10;
	return ((10 - n) % 10 == a.charAt(10));
}

function checkPassportNo(value) {
	var result = false;
	var valid = /^[a-zA-Z]{2,2}[0-9]{7,12}$/;
	if (value.match(valid) && value.length < 15) {
		result = true;
	} else {
		result = false;
	}
	return result;
}

//************************************************************************
// Date and time functions
//************************************************************************

//************************************************************************
// Get current date
// @result: return current date informat dd-mm-yyyy
//************************************************************************
function getCurrentDate() {
	var result = '';
	var currDate = new Date();
	if (currDate.getDate() < 10) {
		result += '0';
	}
	result += currDate.getDate() + '-';
	if (currDate.getMonth() < 9) {
		result += '0';
	}
	result += (currDate.getMonth() + 1) + '-';
	result += currDate.getFullYear();
	return result;
}

//************************************************************************
// Get current time
// @result: return current time in array
//************************************************************************
function getCurrentTime(){
	var result = new Date();
	var curr_hour = result.getHours();
	var curr_min = result.getMinutes();
	return [curr_hour, curr_min];
}

//************************************************************************
//	Get next day
//	Params:
//	@gdate: the date of gdate in format dd-mm-yyyy
//	@days: parameter for how many days to add or decrease the date.
//	@result: return date for increased or reduced, given the number of days.
//************************************************************************
function getNewDate(gdate,days){
	if(!gdate.match(/(\d{1,2}).(\d{1,2}).(\d{4})/)){ return false; } // if date format dd-mm-yyyy is not valid then exit

	var d = new Date(gdate.replace(/(\d{1,2}).(\d{1,2}).(\d{4})/, "$3/$2/$1"));
		d.setDate(d.getDate()+days);
		d.toLocaleString();
		return	(
					((d.getDate())<10 ? "0" : "")+(d.getDate())+"-"+
					((d.getMonth())<10 ? "0" : "")+(d.getMonth()+1)+"-"+
					d.getFullYear()
				);
}

//************************************************************************
// Get timestamp from date. Timestamp jest formatem przedstawiajacym ile sekund
// uplynelo od 1 stycznia 1970 00:00:00.
//************************************************************************
function getTimeStamp(text) {
	var result = -1;
	if ((text !== null) && (text.length > 0)) {
		var dateElements = text.split('-');
		if ((dateElements !== null) && (dateElements.length == 3)) {
			var day = dateElements[0];
			if (isNaN(day)) {
				day = -1;
			}
			var month = dateElements[1];
			if (isNaN(month)) {
				month = -1;
			} else {
				month -= 1;
			}
			var year = dateElements[2];
			if (isNaN(year)) {
				year = -1;
			}
			if (((day >= 1) && (day <= 31)) && ((month >= 0) && (month <= 11))) {
				var tempDate = new Date(year, month, day);
				result = tempDate.getTime();
			}
		}
	}
	return result;
}

//************************************************************************
// Check date format dd-mm-yyyy
// @return: false, if not valid
//************************************************************************
function checkDate(dateText) {
	var result = true;
	if (dateText !== null && dateText !== '') {
		if (getTimeStamp(dateText) != -1) {
			var dateElements = dateText.split('-');
			if ((dateElements !== null) && (dateElements.length == 3)) {
				var day = dateElements[0];
				var month = dateElements[1];
				var year = dateElements[2];
				if (((day.length < 10) && (day.length != 2)) || ((month.length < 10) && (month.length != 2)) || (year.length != 4)) {
					result = false;
				}
				var testDate = new Date(year, (month - 1), day);
				if (!((testDate.getMonth() == (month - 1)) && (testDate.getDate() == day) && (testDate.getFullYear() == year))) {
					result = false;
				}
			} else {
				result = false;
			}
		} else {
			result = false;
		}
	} else {
		result = false;
		return result;
	}
	return result;
}

//************************************************************************
// Check if user have more than 18 years old
// @return: false if have more than 18 years old
//************************************************************************
function checkIsAdult(pesel) {

	if (pesel === null || pesel === '' || pesel.length != 11 || !isNaN(pesel)) {
		return true;
	}

	var currDate = getCurrentDate();
	var birthYear = parseInt(pesel.substr(0, 2), 10);
	var birthMon = parseInt(pesel.substr(2, 2), 10);
	var birthDay = parseInt(pesel.substr(4, 2), 10);
	var currDay = parseInt(currDate.substr(0, 2), 10);
	var currMon = parseInt(currDate.substr(3, 2), 10);
	var currYear = parseInt(currDate.substr(6, 4), 10);

	if (birthYear > currYear - 2000) {
		birthYear = 1900 + birthYear;
	} else {
		birthYear = 2000 + birthYear;
	}

	if (birthYear + 18 > currYear) {
		return false;
	} else if (birthYear + 18 == currYear) {
		if (birthMon > currMon) {
			return false;
		} else if (birthMon == currMon) {
			if (birthDay > currDay) {
				return false;
			}
		}
	}
	return true;
}

//************************************************************************
// Check e-mail address
// @return: false, if not valid
//************************************************************************
function checkValidEmail(value) {
	var reg = new RegExp("[^@]{1,}[@]{1}[^@.]{1,}[.]{1}[^@]{1,}", "gi");
	if (null === value.match(reg)) {
		return false;
	}
	return true;
}

//************************************************************************
// Check postal code in XX-YYY format
// @return: false, if not valid
//************************************************************************
function checkPostalCode(postalCode) {
	var result = true;
	if (postalCode !== null || postalCode !== '' && (postalCode.length == 6)) {
		var sep = postalCode.indexOf('-');
		if (sep == -1) {
			result = false;
		} else {
			if (!isNaN(postalCode.substring(0, sep)) && !isNaN(postalCode.substring(sep + 1, postalCode.length))) {
				result = true;
			} else {
				result = false;
			}
		}
	} else {
		result = false;
	}
	return result;
}

//************************************************************************
// Given a keyCode value, this function checks against the known keyCodes for
// Special
// Keys as described in the Quirksmode article Javascript - Detecting keystrokes
// http://www.quirksmode.org/js/keys.html (as of 19 September 2007).
//************************************************************************
function keyup_specialKey(code) {
	if (0 === code) {
		return true;
	} // f1 - f12 (Opera Mac)
	if (5 == code || 6 == code) {
		return true;
	} // help (Mac only. Firefox/Safari give different values.)
	if (8 == code) {
		return true;
	} // backspace
	if (9 == code) {
		return true;
	} // tab
	if (12 == code) {
		return true;
	} // num lock (Mac)
	if (13 == code) {
		return true;
	} // enter
	if (16 <= code && code <= 18) {
		return true;
	}// shift, ctrl (also cmd on Opera Mac), alt
	if (20 == code) {
		return true;
	} // caps lock
	if (27 == code) {
		return true;
	} // escape (also num lock on Opera Mac)
	if (33 <= code && code <= 40) {
		return true;
	}// page up, page down, end, home, arrow keys
	if (45 == code) {
		return true;
	} // insert (also help on Opera Mac)
	if (46 == code) {
		return true;
	} // delete
	if (91 == code) {
		return true;
	} // start
	if (112 <= code && code <= 123) {
		return true;
	} // f1 - f12
	if (144 == code) {
		return true;
	} // num lock
	return false;
}

//************************************************************************
// Given a keyCode value, this function checks against the known keyCodes for
// Numeric
// Keys on both the keyboard and key pad.
//************************************************************************
function keyup_numericKey(code) {
	if (48 <= code && code <= 57) {
		return true;
	} // number keys (top of keyboard)
	else if (96 <= code && code <= 105) {
		return true;
	} // number keys (on key pad)
	else {
		return false;
	}
}

//************************************************************************
//Check Enter Key function
//************************************************************************
function checkEnter(e) { // e is event object passed from function invocation
	var characterCode; // literal character code will be stored in this
						// variable

	if (e && e.which) { // if which property of event object is supported (NN4)
		e = e;
		characterCode = e.which; // character code is contained in NN4's
									// which property
	} else {
		e = event;
		characterCode = e.keyCode; // character code is contained in IE's
									// keyCode property
	}

	if (characterCode == 13) { // if generated character code is equal to ascii
								// 13 (if enter key)
		document.forms[0].submit(); // submit the form
		return false;
	} else {
		return true;
	}
}

//Get key code
function GetKeyCode(event) {
	var code;
	if (event.keyCode) {
		code = event.keyCode;
	} else if (event.which) {
		code = event.which;
	}
	return code;
}

//************************************************************************
// Given an element, this function attempts to give that element the browser's focus.
//************************************************************************
function focusOn(elm) {
	if (elm === null) {
		return;
	}

	try {
		elm.focus();
	} catch (ex) {
		// Catch Mozilla exception when new focus field has autocomplete data.
	}
}

//************************************************************************
// Toggle classes on specified element with href
// @The function find element with href, then element with id="from href"
// and then make toggle visibility switching classes "hide" and "view"
// @note: in CSS You have to define class "hide" and "view" with params display
//************************************************************************

var toggleElement = {
		i : "",
		ids : "",
		targetURL : "",

		init: function(){
			var anch = getElementsByClassName("toggle");
			if (anch.length < 1) {
				return false;
			} // check, if exits any element with "toggle" class
			for (i = 0; i < anch.length; i++) {
				if (anch[i].href !== null) {
					ids = anch[i].href.split("#");
					targetURL = document.getElementById(ids[1]);
					if (!hasClass(targetURL, "hide")) {
						addClass(targetURL, "hide");
					}
					anch[i].onclick = toggleElement.doToggle;
				}
			}
		},

		doToggle : function(){
			var elem = this;
			if (elem && (elem.href !== null)) {
				elem.blur();
				var getid = elem.href.split('#');
				var id = document.getElementById(getid[1]);
				toggleClass(id, "hide", "view");
			}
			return false;
		}
};

//************************************************************************
// Pullquote function. Use "pullquote" class name to generale pullquote
// Function by Roger Johansson, www.456bereastreet.com
//************************************************************************
var pullquote = {
	init : function() {
		// Check that the browser supports the methods used
		if (!document.getElementById || !document.createElement || !document.appendChild) {
			return false;
		}
		var oElement, oPullquote, oPullquoteP, oQuoteContent, i, j;
		// Find all span elements with a class name of pullquote
		var arrElements = document.getElementsByTagName('span');
		var oRegExp = new RegExp("(^|\\s)pullquote(\\s|$)");
		for (i = 0; i < arrElements.length; i++) {
			// Save the current element
			oElement = arrElements[i];
			if (oRegExp.test(oElement.className)) {
				// Create the blockquote and p elements
				oPullquote = document.createElement('blockquote');
				oPullquote.className = oElement.className;
				oPullquoteP = document.createElement('p');
				// Insert the pullquote text
				for (j = 0; j < oElement.childNodes.length; j++) {
					oPullquoteP.appendChild(oElement.childNodes[j]
							.cloneNode(true));
				}
				oPullquote.appendChild(oPullquoteP);
				// Insert the blockquote element before the span elements parent
				// element
				oElement.parentNode.parentNode.insertBefore(oPullquote,
						oElement.parentNode);
			}
		}
	}
};

//************************************************************************
// Go to top - scrolling version
// Show "Go to top" when you move down/up content more than 20% from top of page
//************************************************************************

var goToTopOfPage = {
	intervalID : '',

	init: function(){
		var backelem = document.getElementById('backtotop');
		if (!backelem) {
			return false;
		}

		backelem.style.visibility = "hidden";
		backelem.onclick = goToTopOfPage.goToTop;
	},

	goToTop: function() {
		var x1, x2, x3 = 0;
		var y1, y2, y3 = 0;

		if (document.documentElement) {
			x1 = document.documentElement.scrollLeft || 0;
			y1 = document.documentElement.scrollTop || 0;
		}
		if (document.body) {
			x2 = document.body.scrollLeft || 0;
			y2 = document.body.scrollTop || 0;
		}
		x3 = window.scrollX || 0;
		y3 = window.scrollY || 0;

		var x = Math.max(x1, Math.max(x2, x3));
		var y = Math.max(y1, Math.max(y2, y3));

		window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));

		window.clearInterval(intervalID);
		if (x > 0 || y > 0) {
			intervalID = window.setInterval(goToTopOfPage.goToTop, 60);
		}
		return false;
	},

	showHideBackToTop: function() {
		var getScrollTop = getScrollXY();
		var pageSize = getPageSize();
		var backelem = document.getElementById('backtotop');

		if (getScrollTop[1] > (pageSize[3] * 0.2).toFixed(0)) {
			backelem.style.visibility = "visible";
		} else {
			backelem.style.visibility = "hidden";
		}
	}
};

// Preventing a double-click submit form, thereby sending accidental n times the same data
function enableSubmit(e, dValue) {
	for (f = 0; f < e.elements.length; f++) {
		var elem = e.elements[f];
		// We have to check if type of submit button exists and isn't locked. If
		// locked, then unclock.

		if ((elem.getAttribute("type") === "button") || (elem.getAttribute("type") === "submit") || (elem.getAttribute("type") === "image")) {
			if (elem.getAttribute("disabled") !== null) {
				elem.removeAttribute("disabled");
			}
			elem.setAttribute("value", dValue);
			delClass(elem, "disabled");
		}
	}
	document.body.style.cursor = 'default';
	e.submit();
}
function submitform_once() {
	eform = this;
	for ( var j = 0; j < eform.elements.length; j++) {

		// check if type of button is: button, submit or image
		if ((eform[j].getAttribute("type") === "button") || (eform[j].getAttribute("type") === "submit") || (eform[j].getAttribute("type") === "image")) {

			// if type of submir button is not image, then change value of this
			// button to wait text
			if (eform[j].getAttribute("type") !== "image") {
				var dValue = eform[j].getAttribute("value");
				eform[j].setAttribute("value", "Czekaj...");
			}
			eform[j].blur();
			eform[j].setAttribute("disabled", "disabled");
			addClass(eform[j], "disabled");
			document.body.style.cursor = 'wait';
			var self = this;
			window.setTimeout("function (){enableSubmit(self,dValue);}", 1000);
		}
	}
	return false;
}
function submitform_once_init() {
	for ( var i = 0; i < document.forms.length; i++) {
		// Check, if form has disabled submit buttons: submit, button or image
		// Cache browser can memorize the status of the blocked button and here
		// we have to protect itself against that after pressing the back button
		// every type of browser submit button unclock had the opportunity
		// click.
		for (j = 0; j < document.forms[i].length; j++) {
			// We have to check if type of submit button exists and isn't
			// locked. If locked, then unclock.
			if (((document.forms[i][j].type !== undefined) && (document.forms[i][j].type === "submit") || (document.forms[i][j].type === "button") || (document.forms[i][j].type === "image")) && (document.forms[i][j].getAttribute("disabled") !== null)) {
				document.forms[i][j].removeAttribute("disabled");
				delClass(document.forms[i][j], "disabled");
			}
		}
		// addEvent(document.forms[i], 'submit', submitform_once);
		document.forms[i].onsubmit = submitform_once;
	}
}

// Asynchroniczny sposob wywolywania trackera Google Analytics, tj. ogolnie odnoszenie sie do
// ich skryptow bez opozniania ladowania strony przez ladowanie zewnetrznego pliku JS.
function addGoogleStats(GAID) {
	var head = document.getElementsByTagName("head")[0];
	var scr = document.createElement("script");
	    scr.setAttribute("type", "text/javascript");
	    scr.setAttribute("src", (location.protocol == 'http:' ? 'http://www.' : 'https://ssl.') + 'google-analytics.com/' + 'ga.js');
	var once = 0;

	function runMe() {
		if (scr.readyState == 'loading' || _gat === undefined || once) {
			return;
		}
		clearInterval(timer);
		once++;

		var pageTracker = _gat._getTracker(GAID);
		pageTracker._initData();
		pageTracker._trackPageview();
	}

	var timer = setInterval(runMe, 2000);
	scr.onload = runMe;
	scr.onreadystatechange = runMe;
	head.appendChild(scr);
}

// * * * * * * * * * * * * * * * * * * * * *
// Check the strength of password
function checkStrengthPassword(e) {
	var target = eventTarget(e);

	// Create DIV for password meter bar
	var loginformDiv = document.getElementById("password-section");
	if (!loginformDiv) {
		return false;
	}
	var pwdbarname = "password-meter-bar";
	var pwdDiv;
	if (!document.getElementById(pwdbarname)) {
		pwdDiv = loginformDiv.appendChild(document.createElement("div"));
		pwdDiv.id = pwdbarname;
	} else {
		pwdDiv = document.getElementById(pwdbarname);
	}

	var passwd = trim(target.value); // Removing the white spaces from the beginning and end of the password
	var points = 0;
	var level = 0;

	// Recurring characters
	passwd = passwd.replace(/(.)\1+/g, '$1');

	// Review scoring for the length of your password
	if (!passwd.length) {
		points = -1;
	} else if (passwd.length < 4) {
		points += 3;
	} else if (passwd.length < 6) {
		points += 8;
	} else if (passwd.length < 12) {
		points += 12;
	} else {
		points += 18;
	}

	var numbers = passwd.match(/\d/g); // matches a character that is a digit;
										// to indicate a global search we use
										// the g flag
	var plowercase = passwd.match(/[a-z]/g); // matches any lower letter
	var puppercase = passwd.match(/[A-Z]/g); // matches any upper letter
	var specialChar = passwd.match(/[\W_]/g); // matches a character that is
												// not a digit - special char

	numbers = numbers ? numbers.length : 0;
	plowercase = plowercase ? plowercase.length : 0;
	puppercase = puppercase ? puppercase.length : 0;
	specialChar = specialChar ? specialChar.length : 0;

	// Check to see if there are any numbers (0-9)
	if (numbers) {
		points += 6;
		// 2+
		if (numbers >= 2) {
			points += 5;
		}
	}
	// Check to see if there are any lower letters (a-z)
	if (plowercase) {
		points += 1;
	}
	// Check to see if there are any upper letters (A-Z)
	if (puppercase) {
		points += 5;
	}
	// Check to see if there are any non-word character.
	if (specialChar) {
		points += 5;
		if (specialChar >= 2) {
			points += 6;
		}
	}
	// Check whether the letters are at the same time lower and upper (a-z and
	// A-Z)
	if (plowercase && puppercase) {
		points += 2;
	}
	// Check whether they are at the same time letters and numbers (a-z and A-Z
	// and 0-9)
	if ((plowercase || puppercase) && numbers) {
		points += 2;
	}
	// Check whether they are at the same time letters, numbers and special
	// characters (a-z and A-Z and 0-9 and %#...)
	if ((plowercase || puppercase || numbers) && specialChar) {
		points += 3;
	}

	var pwdDivClass = ''; // Clear class name of element

	// Review scoring allocated for the password
	if (points < 0) {
		level = 0;
		pwdDivClass = "level0"; // Class name for level 0
	} else if (points < 15) {
		level = 1;
		pwdDivClass = "level1";
	} else if (points < 25) {
		level = 2;
		pwdDivClass = "level2";
	} else if (points < 35) {
		level = 3;
		pwdDivClass = "level3";
	} else if (points < 45) {
		level = 4;
		pwdDivClass = "level4";
	} else {
		level = 5;
		pwdDivClass = "level5";
	}

	// Show scores for the strength of password
	if (pwdDiv.firstChild !== null && pwdDiv.firstChild.nodeType === 3) {

		// Clear all nodes
		var e = pwdDiv.cloneNode(false);
		pwdDiv.parentNode.replaceChild(e, pwdDiv);
		pwdDiv = e;

		pwdDiv.appendChild(document.createTextNode(level));
		pwdDiv.style.width = (level * 2) + 1 + "em";
		pwdDiv.className = ''; // Clear all classes
		addClass(pwdDiv, pwdDivClass); // The addition of a proper class
	} else {
		pwdDiv.appendChild(document.createTextNode(level));
	}
}

function hidePasswordBarMeter() {
	var pwdbarname = document.getElementById("password-meter-bar");
	if (!pwdbarname) {
		return false;
	}
	// Remove password meter bar layer & layer childs
	removeElement(pwdbarname);
}

function checkStrengthPass() {
	var passelem = document.getElementById("pass");
	if (!passelem) {
		return;
	}
	passelem.onkeyup = checkStrengthPassword;
	passelem.onblur = hidePasswordBarMeter;
}

// * * * * * * * * * * * * * * * * * * * * *
// Check if passwords are match
function checkMatchPasswords(passelem, passreelem) {
	if (passelem.value !== passreelem.value) {
		alert('Hasła w obu polach muszą być identyczne.');
	}
}
function checkMatchPass() {
	var passelem = document.getElementById("pass");
	var passreelem = document.getElementById("passre");
	if (passelem == null || passreelem == null) { return false; }
	addEvent(passreelem, 'blur', function() {
		checkMatchPasswords(passelem, passreelem);
	});
}

// * * * * * * * * * * * * * * * * * * * * *
// Find all the elements associated with the label and set them to focus "focus"
// class, while the blur remove "focus" class.
// This allows the backlight is a label.

function labelOn(e) {
	var tar = findLabel(eventTarget(e).id);
	if(!tar){ return false; }
	addClass(tar, "focus");
	// Go up and find <div>
	if(tar.parentNode.nodeName.toLowerCase() === "div"){
		addClass(tar.parentNode, "focusparent");
		delClass(tar.parentNode, "input-error-field-parent");
		return true;
	}
	return false;
}
function labelOff(e) {
	var tar = findLabel(eventTarget(e).id);
	if(!tar){ return false; }
	// Go up and find <div>
	if(tar.parentNode.nodeName.toLowerCase() === "div"){
		delClass(tar, "focus");
		delClass(tar.parentNode, "focusparent");
		return true;
	}
	return false;
}

function labelfocus() {
	var labels = document.getElementsByTagName("label");
	var i, elem;
	for (i = 0; i < labels.length; i++) {
		var FieldName = labels[i].getAttribute("for") || labels[i].getAttribute("htmlFor"); // first is for IE6,7
		elem = document.getElementById(FieldName);
		if (elem !== null) {
			addEvent(elem, 'focus', labelOn);
			addEvent(elem, 'blur', labelOff);
		}
	}
}
/**
 * Function TableSorting
 * 
 * @param just add class "sortable" to table
 */
var TableSorting = {
		// Some variables
		that: false,
		isOdd: false,
		sortColumnIndex : -1,
		lastAssignedId : 0,
		newRows: -1,
		lastSortedTable: -1,
		i : 0,
		j : 0,
		spanEl : '',

		// Initialises the Standardista Table Sorting module
		init : function() {
			
			this.that = this;
			// Make sortable all tables with class name "sortable"
			var tables = document.getElementsByTagName("table");
			i = tables.length;
			while(i--) {
				if (hasClass(tables[i], "sortable")) {
					this.makeSortable(tables[i]);
				}
			}
		},

		// Makes the given table sortable
		makeSortable : function(table) {

			// First, check if the table has an id. If it doesn't, give it one.
			if (!table.id){
				table.id = 'sortableTable'+this.lastAssignedId++;
			}

			// If this table does not have a thead, we don't want to know about it.
			if (!table.tHead || !table.tHead.rows || 0 === table.tHead.rows.length) {
				return;
			}

			// We'll assume that the last row of headings in the thead is the row that wants to become clickable.
			var row = table.tHead.rows[table.tHead.rows.length - 1];

			var i = row.cells.length;
			while(i--) {
				// create a link with an onClick event which will
				// control the sorting of the table
				var linkEl = createElement('a');
				linkEl.href = '#';
				linkEl.onclick = this.headingClicked;
				linkEl.setAttribute('columnId', i);
				linkEl.title = 'Kliknij, aby posortować';

				// Move the current contents (first child) of the cell that we're hyperlinking into the hyperlink
				linkEl.appendChild(row.cells[i].firstChild.cloneNode(true));
				removeElementNodes(row.cells[i]);
				row.cells[i].appendChild(linkEl);
				
				//var innerEls = row.cells[i].childNodes;
				//j = innerEls.length;
				//while(j--) {
				//	linkEl.appendChild(innerEls[j]);
				//}

				// and finally add the new link back into the cell
				//row.cells[i].appendChild(linkEl);

				/*
				spanEl = createElement('span');
				addClass(spanEl, "tableSortArrow");
				spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
				//row.cells[i].appendChild(spanEl);
				//row.cells[i].firstChild.appendChild(spanEl);
				*/

			}

			if (hasClass(table, "autostripe")){
				this.isOdd = false;
				var rows = table.tBodies[0].rows;

				// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones.
				for (i=0;i<rows.length;i++) {
					this.doStripe(rows[i]);
				}
			}
		},

		headingClicked: function(e) {
			var that = TableSorting.that;
			//alert("sort");

			// linkEl is the hyperlink that was clicked on which caused this method to be called
			var linkEl = eventTarget(e);
			//linkEl.style.whiteSpace = "nowrap";

			// Directly outside it is a td, tr, thead and table
			var td     = linkEl.parentNode;
			var tr     = td.parentNode;
			var thead  = tr.parentNode;
			var table  = thead.parentNode;
			var arrows, newRows;

			// If the table we're looking at doesn't have any rows
			// (or only has one) then there's no point trying to sort it
			if (!table.tBodies || table.tBodies[0].rows.length <= 1) {
				return false;
			}

			// The column we want is indicated by td.cellIndex
			var column = linkEl.getAttribute('columnId') || td.cellIndex;

			// Find out what the current sort order of this column is
			arrows = getElementsByAttribute(table, "span", "sortOrder");

			var previousSortOrder = '';
			i = arrows.length;
			while(i--)
			{
				if(arrows[i].getAttribute("sortOrder") !== '' || arrows[i].getAttribute("sortOrder") !== "undefined"){
					previousSortOrder = arrows[i].getAttribute("sortOrder");
				}
			}

			// Work out how we want to sort this column using the data in the first cell
			// but just getting the first cell is no good if it contains no data
			// so if the first cell just contains white space then we need to track
			// down until we find a cell which does contain some actual data
			var itm = '';
			var rowNum = 0;
			while (itm === '' && rowNum < table.tBodies[0].rows.length){
				itm = that.getInnerText(table.tBodies[0].rows[rowNum].cells[column]);
				rowNum++;
			}
			var sortfn = that.determineSortFunction(itm);

			// if the last column that was sorted was this one, then all we need to
			// do is reverse the sorting on this column
			if (table.id == that.lastSortedTable && column == that.sortColumnIndex) {
				newRows = that.newRows;
				newRows.reverse();
			// otherwise, we have to do the full sort
			} else {
				that.sortColumnIndex = column;
				newRows = [];

				j = table.tBodies[0].rows.length;
				while(j--)
				{
					newRows[j] = table.tBodies[0].rows[j];
				}
				newRows.sort(sortfn);
			}

			that.moveRows(table, newRows);
			that.newRows = newRows;
			that.lastSortedTable = table.id;

			// Now, give the user some feedback about which way the column is sorted
			// First, get rid of any arrows in any heading cells
			arrows = getElementsByClassName("tableSortArrow","span");

			j = arrows.length;
			while (j--)
			{
				arrows[j].parentNode.removeChild(arrows[j]);
			}

			// now, add back in some feedback
			spanEl = createElement('span');
			spanEl.className = 'tableSortArrow';

			if (previousSortOrder === null || previousSortOrder === '' || previousSortOrder == 'DESC') {
				spanEl.appendChild(document.createTextNode(' \u2191'));
				spanEl.setAttribute('sortOrder', 'ASC');
			} else {
				spanEl.appendChild(document.createTextNode(' \u2193'));
				spanEl.setAttribute('sortOrder', 'DESC');
			}

			linkEl.appendChild(spanEl);
			linkEl.blur(); // remove blur
			return false;
		},

		getInnerText : function(el) {

			if (typeof el === "string" || typeof el === undefined) {
				return el;
			}

			if (el.innerText){
				return el.innerText;  // Not needed but it is faster
			}

			var str = el.getAttribute('TableSortingInnerText');
			if (str !== null && str !== ''){
				return str;
			}
			str = '';

			var cs = el.childNodes;
			var l = cs.length;
			for (i = 0; i < l; i++) {
				// 'if' is considerably quicker than a 'switch' statement,
				// in Internet Explorer which translates up to a good time
				// reduction since this is a very often called recursive function
				if (cs[i].nodeType === 1) { // ELEMENT NODE
					str += this.getInnerText(cs[i]);
					break;
				} else if (cs[i].nodeType === 3) { //TEXT_NODE
					str += cs[i].nodeValue;
					break;
				}
			}

			// set the innertext for this element directly on the element
			// so that it can be retrieved early next time the innertext
			// is requested
			el.setAttribute('TableSortingInnerText', str);
			return str;
		},

		determineSortFunction : function(itm) {

			var sortfn = this.sortCaseInsensitive;

			if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) {
				sortfn = this.sortDate;
			}
			if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) {
				sortfn = this.sortDate;
			}
			if (itm.match(/^[ÂL$]/)) {
				sortfn = this.sortCurrency;
			}
			if (itm.match(/^\d?\.?\d+$/)) {
				sortfn = this.sortNumeric;
			}
			if (itm.match(/^[+-]?\d*\.?\d+([eE]-?\d+)?$/)) {
				sortfn = this.sortNumeric;
			}
	    		if (itm.match(/^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/)) {
	        		sortfn = this.sortIP;
	   		}

			return sortfn;
		},

		sortCaseInsensitive : function(a, b) {
			var that = TableSorting.that;

			var aa = that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase();
			var bb = that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase();
			if (aa==bb) {
				return 0;
			} else if (aa<bb) {
				return -1;
			} else {
				return 1;
			}
		},

		sortDate : function(a,b) {
			var that = TableSorting.that;

			// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
			var aa = that.getInnerText(a.cells[that.sortColumnIndex]);
			var bb = that.getInnerText(b.cells[that.sortColumnIndex]);

			var dt1, dt2, yr = -1;

			if (aa.length == 10) {
				dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
			} else {
				yr = aa.substr(6,2);
				if (parseInt(yr) < 50) {
					yr = '20'+yr;
				} else {
					yr = '19'+yr;
				}
				dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
			}

			if (bb.length == 10) {
				dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
			} else {
				yr = bb.substr(6,2);
				if (parseInt(yr) < 50) {
					yr = '20'+yr;
				} else {
					yr = '19'+yr;
				}
				dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
			}

			if (dt1==dt2) {
				return 0;
			} else if (dt1<dt2) {
				return -1;
			}
			return 1;
		},

		sortCurrency : function(a,b) {
			var that = TableSorting.that;

			var aa = that.getInnerText(a.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
			var bb = that.getInnerText(b.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
			return parseFloat(aa) - parseFloat(bb);
		},

		sortNumeric : function(a,b) {
			var that = TableSorting.that;

			var aa = parseFloat(that.getInnerText(a.cells[that.sortColumnIndex]));
			if (isNaN(aa)) {
				aa = 0;
			}
			var bb = parseFloat(that.getInnerText(b.cells[that.sortColumnIndex]));
			if (isNaN(bb)) {
				bb = 0;
			}
			return aa-bb;
		},

		makeStandardIPAddress : function(val) {
			var vals = val.split('.');

			for (x in vals) {
				val = vals[x];

				while (3 > val.length) {
					val = '0'+val;
				}
				vals[x] = val;
			}

			val = vals.join('.');

			return val;
		},

		sortIP : function(a,b) {
			var that = TableSorting.that;

			var aa = that.makeStandardIPAddress(that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase());
			var bb = that.makeStandardIPAddress(that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase());
			if (aa==bb) {
				return 0;
			} else if (aa<bb) {
				return -1;
			} else {
				return 1;
			}
		},

		moveRows : function(table, newRows) {
			this.isOdd = false;

			// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
			for (var i=0;i<newRows.length;i++) {
				var rowItem = newRows[i];

				this.doStripe(rowItem);

				table.tBodies[0].appendChild(rowItem);
			}
		},

		doStripe : function(rowItem) {
			if (this.isOdd) {
				addClass(rowItem, "odd");
			} else {
				delClass(rowItem, "odd");
			}

			this.isOdd = !this.isOdd;
		}

	};

/**
 * Make unobtrusive nice titles for elements with attribute "title".
 *
 * @param  posXadd add value to X position
 * @param  posYadd add value to Y position
 * @param  showAfterTime show title after n time
 * @param  hideAfterTime hide title after n time
 * @return remove attribute title from all elements and replace them with "tip" attribute and add class "Tooltip" for each "tip"
 */
var uTitle = {
	posX :0,
	posY : 0,
	posXadd : 20,
	posYadd : 20,
	showAfterTime : 750,		// After this time (miliseconds) show tooltip.
	hideAfterTime : 60000,		// After this time (miliseconds) hide tooltip.
	speedFadeIn : 0.05,			// Speed of fade in
	speedFadeOut : 0.01,		// Speed of fade out
	tipElement : Object,		// Reference to "toolTip" element
	refObj : Object,			// Reference to object from event
	pageSize : getPageSize(),	// Get actual page and window size
	startShowAfter : '',
	fadingStartShow : '',
	startHideAfter : '',
	fadingStartHide : '',

	init : function() {
		// Init, check DOM
		if (!document.getElementById || !document.createElement || !document.getElementsByTagName) {
			return false;
		}

		// Create div element with id "toolTip"
		this.tipElement = document.createElement('div');
		this.tipElement.setAttribute("id", "toolTip");
		document.getElementsByTagName('body')[0].appendChild(this.tipElement);

		var elems = getElementsByAttribute(document.body, "*", "title");// get elements with title attribute; return an array of elements
		var i = elems.length, attrtip; // i=amout of titles
		if (i < 1) {
			return false; // there is no elements with "title" attribute
		}

		while(i--){
			// Create a new attribute "tip" node, append it to an element node, move
			// nodeValue from title to tip and remove attribute "title"
			attrtip = document.createAttribute("tip");
			attrtip.value = elems[i].title;
			elems[i].setAttributeNode(attrtip);
			elems[i].removeAttribute("title"); // remove attribute title
			// Create events for mouse
			//elems[i].onmouseover = uTitle.uTitleOver;
			elems[i].onmouseover = uTitle.uTitleOver;
			elems[i].onmouseout = uTitle.uTitleOut;
			elems[i].onmousemove = uTitle.uTitlePosition;
		}
	},

	uTitleShow : function() {
		var d = document.getElementById("toolTip");
		if(!d){ return false; }

		d.oOpacity += uTitle.speedFadeIn; // Speed fade in

		if (d.oOpacity < 0.99) {
			setOpacity(d);
		} else {
			d.oOpacity = 0.99;
			setOpacity(d);
			if (window.fadingStartShow) {
				window.clearInterval(fadingStartShow);
			}
			if (window.startShowAfter) {
				window.clearTimeout(startShowAfter);
			}
		}
		// Calculate tooltip width
		if(d.offsetLeft+d.clientWidth > uTitle.pageSize[2]){
			d.style.width = (uTitle.pageSize[2]-d.offsetLeft)+"px";
		}
		if(d.clientWidth > 300){
			d.style.width = 30 + "em";
		}
	},

	uTitleHide : function(opac) {
		d = document.getElementById("toolTip");
		if(!d){ return false; }

		d.oOpacity -= uTitle.speedFadeOut; // Speed fade out
		if (d.oOpacity > 0) {
			setOpacity(d);
		} else {
			d.oOpacity = 0;
			setOpacity(d);
			if (window.fadingStartHide){
				window.clearInterval(fadingStartHide);
			}
			// Hide tip
			d.style.display = "none";
			d.style.width = ""; // reset width
		}
	},

	uTitleOver: function(e) {
		var d = document.getElementById("toolTip");
		if(!d){ return false; }

		// Set coordinates
		uTitle.uTitlePosition(e);

		// Set xOpacity param
		d.oOpacity = 0;
		setOpacity(d);

		// Set content tip
		//var tiptext = htmlspecialchars(this.getAttribute("tip"));
		//DOMinnerHTML(d, tiptext); // get content from "tip" attribute

		var tiptext = this.getAttribute("tip");
		//tiptext = tiptext.replace(/<[^>]+>/g, ""); // remove all html tags
		tiptext = tiptext.replace(/<\/?[^>]+>/gi, ""); // remove all html tags
		d.appendChild(document.createTextNode(tiptext));

		// Show ToolTip after n miliseconds
		startShowAfter = setTimeout( function() {
			fadingStartShow = window.setInterval("uTitle.uTitleShow()", 5);
		}, uTitle.showAfterTime); // After this time hide tooltip. Example: 500 is 0.5 seconds

		startHideAfter = setTimeout( function() {
			fadingStartHide = window.setInterval("uTitle.uTitleHide()", 5);
		}, uTitle.hideAfterTime); // After this time hide tooltip. Example: 5000 is 5 seconds

		// Display tip
		d.style.display = "block";
	},

	uTitleOut : function() {
		var d = document.getElementById("toolTip");
		if(!d){ return false; }

		// Clearing intervals
		if (window.fadingStartShow || window.startShowAfter) {
			if (window.fadingStartShow) {
				window.clearInterval(fadingStartShow);
			}
			if (window.startShowAfter) {
				window.clearTimeout(startShowAfter);
			}
			d.oOpacity = 0;
			setOpacity(d);
		}
		if (window.startHideAfter) {
			window.clearTimeout(startHideAfter);
		}

		// Hide tip
		d.style.display = "none";
		d.style.width = ""; // reset width

		// Remove all previous content from <div id="toolTip">, before add new content
		removeElementNodes(d);
	},

	uTitlePosition : function(e){
		var d = document.getElementById("toolTip");
		if(!d){ return false; }

		if ( document.captureEvents ) {
			uTitle.posX = e.pageX;
			uTitle.posY = e.pageY;
		} else if ( window.event.clientX ) {
			uTitle.posX = window.event.clientX+document.documentElement.scrollLeft;
			uTitle.posY = window.event.clientY+document.documentElement.scrollTop;
		}

		d.style.top = (uTitle.posY + uTitle.posXadd) + "px";
		d.style.left = (uTitle.posX + uTitle.posYadd) + "px";
	}
};

// * * * * * * * * * * * * * * * * * * * * *
// Alert message box
// errorMesssage - display message
// elementFocus - set focus to element after hide alert (optional)
// labelText - a text from <label>

function AlertBox() {
	var elementFocus = null;
	var buttons = [];
	var returnVal = null;
	var sizes = getPageSize();

	// create background layer
	var alertBg = document.createElement("div");
	alertBg.id = "dialog_alert"; // ID of bg layer
	document.getElementsByTagName("body")[0].appendChild(alertBg);

	// create alert layer
	var dialog = document.createElement("div");
	dialog.id = "dialogbox";
	addClass(dialog, "dialog");
	dialog.onclick = function(e) {
		e = e || event;
		e.cancelBubble = true;
		return false;
	};
	alertBg.appendChild(dialog);

	// remember element to set focus when close alert
	this.addPostElement = function(elem) {
		elementFocus = elem;
	};

	// create message box
	this.addMessage = function(errorMessage, elementFocus) {

		// If elementFocus exits, then find <label> and get label text
		// [labelText.firstChild.nodeValue] - a text from <label></label>
		// Replace "Pole" with "Pole [text from label]"
		var elementFromLabel = findLabel(elementFocus);
		if (elementFromLabel !== false) {
			var getLabelText = (elementFromLabel.firstChild.nodeType === 3) ? elementFromLabel.firstChild.nodeValue : '';
			errorMessage = str_replace(errorMessage, "Pole", "Pole <strong>" + getLabelText + "</strong> ");
			if(hasClass(elementFromLabel, "required")){
				errorMessage = errorMessage + " jest wymagane.";
			}
		}
		errorMessage = "<p>" + errorMessage + "</p>";
		DOMinnerHTML(dialog, errorMessage);
	};

	// create button for close alert
	this.addButton = function(text, title, className, ret, elementFocus) {
		var button = document.createElement("a");
		button.setAttribute("href", "#");
		button.appendChild(document.createTextNode(text));
		addClass(button, className);
		button.setAttribute("title", title);
		button.ret = ret;
		button.elfocus = elementFocus;
		button.onfocus = function() {
			addClass(this, "focus");
		};
		button.onblur = function() {
			delClass(this, "focus");
		};
		// add button to alert layer
		dialog.appendChild(button);
		// add close alert function for mouse
		button.onclick = function() {
			// remove alert layer & layer childs
			removeElement(alertBg);

			// Set focus for the input element, which concerns the message
			var tofocus = _getElementById(this.elfocus);
			if (tofocus){
				setTimeout(function(){ focusOn(tofocus); }, 10);
			}
			return this.ret;
		};
		// add close alert function for ESC key
		button.onkeypress = function(e) {
			var event = (!e) ? window.event : e; // Find event
			if (GetKeyCode(event) !== 27) {
				return false;
			}// if not ESC key, then return

			// remove alert layer & layer childs
			removeElement(alertBg);

			// Set focus for the input element, which concerns the message
			var tofocus2 = _getElementById(this.elfocus);
			if (tofocus2){
				setTimeout(function(){ focusOn(tofocus2); }, 10);
			}
			return this.ret;
		};

		buttons[buttons.length] = button;
		return false;
	};

	this.show = function() {

		// hide selects (IE6 bug)
		if (Browser.getIEVersion() == 6) {
			var selects = document.getElementsByTagName("select");
			for ( var i = 0; i < selects.length; i++) {
				selects[i].style.visibility = 'hidden';
			}
		}

		// block with transparent PNG
		// alertBg.style.width = sizes[0]+"px";
		alertBg.style.height = sizes[1] + "px";

		dialog.style.position = "absolute";
		/*dialog.style.top = Math.ceil(((sizes[3] / 2)) - (dialog.offsetHeight / 2)) + "px";
		dialog.style.left = Math.ceil(parseInt((alertBg.offsetWidth / 2), 10) - (dialog.offsetWidth / 2)) + "px";
		*/

		var centerCoords = findCenterPosition("dialogbox");
		dialog.style.top = centerCoords[0]+"px";
		dialog.style.left = centerCoords[1]+"px";

		alertBg.onclick = function() {
			addClass(dialog, "alert");
			setTimeout( function() {
				delClass(dialog, "alert");
				if (buttons.length == 1) {
					buttons[0].focus();
				}
			}, 1000);
		};

		// Firefox seems to take a little time to set focus back to the page
		// after the alert and needs a split second to do so.
		// Opera 9.5 has broken (and probably insecure) leak of events on
		// focus()
		setTimeout( function() {
			focusOn(buttons[buttons.length - 1]);
		}, 10);
	};
}

function myAlert(errorMessage, elementFocus) {
	var box = new AlertBox();
	box.addMessage(errorMessage, elementFocus);
	box.addPostElement(elementFocus);
	box.addButton("OK", "Zamknij", "button-close-dialog-alert", false, elementFocus);
	box.show();
	return false;
}

function newAlertBox(message) {
	var box = new AlertBox();
	box.addMessage(message);
	// box.addPostElement(elementFocus);
	box.addButton("OK", "Zamknij", "button-close-dialog-alert", false);
	box.show();
	return false;
}

function myConfirm(question) {
	var box = new AlertBox();
	getform = this;
	box.addMessage(question);
	box.addButton("OK", "Potwierdż czynność", "button-ok-dialog-alert", true);
	box.addButton("Anuluj", "Anuluj czynność", "button-cancel-dialog-alert", false);
	box.show();
	return false;
}

// window.confirm = myConfirm; // replace standard confirm dialog Box

// * * * * * * * * * * * * * * * * * * * * *
// Default validation forms functions

function getFormElementValue(inputId) {
	var input = document.getElementById(inputId);
	if (!input) {
		alert("Input " + inputId + " not found!");
		return null;
	}

	return input.value;
}

function focusFailedInput(inputId, errorMessage) {
	var labels = document.getElementsByTagName("label");

	var tmplabel;
	var i = labels.length;
	// set error class to correct label and remove error class from others
	while (i--) {
		var label = labels[i];
		delClass(label, "error");
		// if anything will be wrong, remove break statement
		// KCI -> KCI i think it is wrong 'couse it coulnd not loop to the end
		if ((label.getAttribute('for') || label.getAttribute('htmlFor')) == inputId) {
			addClass(label, "error");
			break;
		}
	}

	if (errorMessage) {
		myAlert(errorMessage, inputId);
	}
	return false;
}

function checkInput(inputId, errorMessage) {
	var inputel;
	if(typeof inputId === "string"){ inputel = document.getElementById(inputId); }
	else if(typeof inputId === "object" && inputId !== null){ inputel = inputId; }
	else { return false; }

	return (inputel.value === "") ? focusFailedInput(inputId, errorMessage) : true;
}

function compareFields(fieldId1, fieldId2, errorMessage) {
	var field1 = document.getElementById(fieldId1);
	if (!field1) {
		alert("Element " + fieldId1 + " nie znaleziono!");
		return false;
	}

	var field2 = document.getElementById(fieldId2);
	if (!field2) {
		alert("Element " + fieldId2 + " not found!");
		return false;
	}

	if (field1.value != field2.value) {
		return focusFailedInput(fieldId2, errorMessage);
	}
	return true;
}

function checkTextarea(inputId, errorMessage) {
	var input = document.getElementById(inputId);
	if (!input) {
		alert("Textarea " + inputId + " not found!");
		return false;
	}

	if (input.value.length <= 3) {
		return focusFailedInput(inputId, errorMessage);
	}
	return true;
}

function isValidEmail(email) {
	var template = /^\w+([\.\-]?\w+)*@\w+([\.\-]?\w+)*(\.\w{2,6})+$/;
	if (template.test(email) === false) {
		return false;
	}
	return true;
}

function checkEmail(inputId, errorMessage) {
	var input = document.getElementById(inputId);
	if (!input) {
		alert("Input " + inputId + " not found!");
		return false;
	}

	if (!isValidEmail(input.value)) {
		focusFailedInput(inputId, errorMessage);
		return false;
	}
	return true;
}

function clearError() {
	var labels = document.getElementsByTagName("label");

	for ( var i = 0; i < labels.length; i++) {
		var label = labels[i];
		delClass(label, "error");
	}
	return true;
}

function checkRadio(form, inputs, errorMessage, inputId) {
	var tmpForm = document.getElementById(form);
	if (tmpForm) {
		form = tmpForm;
	}

	if (!form[inputs]) {
		alert("Element " + inputs + " not found!");
		return false;
	}

	if (!form[inputs].length) { // 1 input
		if (form[inputs].checked) {
			return true;
		}
		return focusFailedInput(inputId, errorMessage);
	}

	for ( var i = 0; i < form[inputs].length; i++) {
		if (form[inputs][i].checked === true) {
			break;
		}
	}

	if (i == form[inputs].length) {
		return focusFailedInput(inputId, errorMessage);
	}
	return true;
}

function groupFields(name, id, cnt, message) {
	var count = parseInt(cnt, 10);
	for ( var i = 1; i <= count; i++) {
		if (document.getElementById(id + "_" + i, message).value === "") {
			return true;
		}
	}
	return focusFailedInput(id + "_1", message);
}

function groupEmails(name, id, cnt, message) {
	var template = /^[0-9a-z]+[0-9a-z._\-]*\@[0-9a-z]+[0-9a-z._\-]*\.[0-9a-z]{2,}$/i;
	var count = parseInt(cnt, 10);
	for ( var i = 1; i <= count; i++) {
		if (template.test(document.getElementById(id + "_" + i, message).value) === true) {
			return true;
		}
	}
	return focusFailedInput(id + "_1", message);
}

function validatePESEL(pesel) {
	// basic check
	if (pesel.length !== 11) {
		return false;
	}

	// check date
	var month = parseInt(pesel.slice(2, 4), 10);
	if (month === 0 || month > 12) {
		return false;
	}
	var day = parseInt(pesel.slice(4, 6), 10);
	if (day === 0 || day > 31) {
		return false;
	}
	var year = parseInt(pesel.slice(0, 2), 10) + 1900;

	if (month > 20 && month < 40) {
		year += 100;
	} else if (month > 80) {
		year -= 100;
	} else if (month > 60) {
		year += 300;
	} else if (month > 40) {
		year += 200;
	}

	var bornString = ((month < 10 ? "0" : "") + month) + "/" + ((day < 10 ? "0" : "") + day) + "/" + ("" + year);
	// nice regexp ;)
	var RegExPattern = /^(?=\d)(?:(?:(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})|(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))|(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2}))($|\ (?=\d)))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$/;
	if (!bornString.match(RegExPattern)) {
		return false;
	}

	// calculate crc
	var steps = [ 1, 3, 7, 9 ];
	var crc = 0;
	for ( var i = 0; i < 10; i++) {
		crc += steps[i % 4] * parseInt(pesel[i], 10);
	}
	crc = 10 - (crc % 10);
	if (crc == 10) {
		crc = 0;
	}
	return crc == parseInt(pesel[10], 10);
}

function checkPESEL(inputId, errorMessage) {
	var input = document.getElementById(inputId);
	if (!input) {
		alert("Input " + inputId + " not found!");
		return false;
	}

	if (!validatePESEL(input.value)) {
		return focusFailedInput(inputId, errorMessage);
	}
	return true;
}

function checkPostCode(inputId, errorMessage) {
	if (!checkInput(inputId, errorMessage)) {
		return false;
	}

	var value = document.getElementById(inputId).value;
	return (!value.match(/^\d{2}-\d{3}$/)) ? focusFailedInput(inputId,
			errorMessage) : true;
}

// ************************
// Add confirm alert to buttons with class "button-delete", links "buttonlink-delete" and images "img-delete"
// ************************

function addConfirmDelete() {
	var elemsInput = getElementsByClassName("button-delete","input");
	var elemsLink = getElementsByClassName("buttonlink-delete","a");
	var elemsImg = getElementsByClassName("img-delete","img");
	var elemsInputImg = getElementsByClassName("buttonimg-delete","input");

	var i;

	// Add event for inputs
	i = elemsInput.length;
	if (i >= 1){
		while (i--)
		{
			addEvent(elemsInput[i], 'click', (function(e)
			{
				var evt = e || window.event;
				var result = confirm("Czy na pewno chcesz usunąć?");
				if(evt.preventDefault && !result){
					evt.preventDefault();
				}
				return result;
			}));
		}
	}

	// Add event for links
	i = elemsLink.length;
	if (i >= 1){
		while (i--)
		{
			addEvent(elemsLink[i], 'click', (function(e)
			{
				var evt = e || window.event;
				var result = confirm("Czy na pewno chcesz usunąć?");
				if(evt.preventDefault && !result){
					evt.preventDefault();
				}
				return result;
			}));
		}
	}
	
	// Add event for links
	i = elemsImg.length;
	if (i >= 1){
		while (i--)
		{
			addEvent(elemsImg[i], 'click', (function(e)
			{
				var evt = e || window.event;
				var result = confirm("Czy na pewno chcesz usunąć?");
				if(evt.preventDefault && !result){
					evt.preventDefault();
				}
				return result;
			}));
		}
	}
	
	// Add event for input type image
	i = elemsInputImg.length;
	if (i >= 1){
		while (i--)
		{
			addEvent(elemsInputImg[i], 'click', (function(e)
			{
				var evt = e || window.event;
				var result = confirm("Czy na pewno chcesz usunąć?");
				if(evt.preventDefault && !result){
					evt.preventDefault();
				}
				return result;
			}));
		}
	}
}

// ************************
// Handling errors and highlighting messages
// ************************
function handling_errors() {
	var errorid = document.getElementById("errors");
	if (!errorid) {
		return false;
	}

	var anchs = errorid.getElementsByTagName("a");
	for ( var i = 0; i < anchs.length; i++) {
		var ids = anchs[i].hash.replace('#', '');
		addClass(document.getElementById(ids), "input-error-field");
		addClass(document.getElementById(ids).parentNode, "input-error-field-parent");
	}
}

// ************************
// Set logout prompt
// ************************
function setLogoutPrompt() {
	var logoutid = document.getElementById("logout");
	if (!logoutid) {
		return false;
	}

	logoutid.onclick = function() {
		return confirm("Czy na pewno chcesz się wylogować?");
	};
}

//************************
// Set focus on input login
//************************
var inputLoginFocus = {
	focuselms : '',

	init : function() {
		focuselms = getElementsByClassName("focus_on");
		if (focuselms.length < 1) { return false; }
		setTimeout( function() {
			focusOn(focuselms[0]);
		}, 10);
	}
};

// ************************
// load all event in onload
// ************************

// These functions may be called repeatedly, for example, when Ajaks reload the
// page.
function runFunctions() {
	toggleElement.init(); // toggle class on elements
	initOverLabels(); // Insert a text from the field <label> to <input>.
	externalLinks.init("class", "external"); // If the link includes parameter rel = "external" to open the content in a new window.
	zebraTables(); // Find <table> with class="zebra" and make zebra on every <tr>
	zebraLists(); // Find <ol>,<ul> with class="zebra" and make zebra on every <li>
	TableSorting.init(); // Make sort tables every table with class "sortable"
	pullquote.init(); // initialise pullquote
	uTitle.init(); // Unobtrusive, light titles
	labelfocus(); // Create the same class for the label, which has inputs elements
	addConfirmDelete(); // Add a confirmation message removal
	handling_errors(); // Handling errors and highlighting messages
	setLogoutPrompt();
}

addEvent(window, 'load', function() {
	textareaResizer.init(); // Add automatically resizer to textarea
	setInitTextSize();
	textplus();
	textminus();
	goToTopOfPage.init(); // set scroll to top
	inputLoginFocus.init(); // set focus on login input

	// submitform_once_init(); // prevent double click form
	runFunctions(); // Run all other functions
});

addEvent(window, 'scroll', function() {
	goToTopOfPage.showHideBackToTop();
});
