/**
 * Fix for IE, allowing to search for elements within array
 * @param	{Any}		obj		any data to search within array values
 * 
 * @return	{Integet}			index of found value or -1 if nothing matched
 */
if(!Array.indexOf){
	Array.prototype.indexOf = function(obj){
		for(var i=0; i<this.length; i++){
			if(this[i] == obj){
				return i;
			}
		}
		return -1;
	}
}
/**
 * Base utils holder object
 */
var wcmsUtils = new function(){
	var _self = this; //instanse of self to get access to internal method when any method is called from different scope
	/**
	 * Searches recursivelly all child elements for node
	 * @param	{DOM object}	container	parent element
	 * @param	{DOM object}	node		element to search under the parent
	 * 
	 * @return	{Boolean}					true if found, false if not
	 */
	this.contains = function(container, node) {
		var found = false;
		if (null != node){
			if (node == container)
				found = true;
			else
				found = this.contains(container, node.parentNode);
		}
		return found;
	};
	/**
	 * Creates element using DOM compliant methods
	 * @param	{Object}		elementData		Element data object with properties, tagName, id, className, name, textNode, attributes
	 * 											attributes containes atrributes object {attr1: value1, attr2: value2, ...}
	 * @param	{DOM Object}	parentElement	If provided newly created element will be appended to this element
	 */
	this.createElement = function(elementData, parentElement){
		var element = null;
		if (null != elementData && elementData.tagName){
			element = document.createElement(elementData.tagName);
			if (element){
				if (elementData.id){
					element.id = elementData.id;
				}
				if (elementData.name){
					element.name = elementData.name;
				}
				if (elementData.className){
					element.className = elementData.className;
				}
				if (elementData.attributes){
					for(var x in elementData.attributes){
						if (null != elementData.attributes[x]){
							element.setAttribute(x, elementData.attributes[x]);
						}
					}
				}
				if (elementData.textNode){
					element.appendChild(document.createTextNode(elementData.textNode));
				}
			}
			if (parentElement){
				parentElement.appendChild(element);
			}
		}
		return element;
	};
	/**
	 * Method for removing all childnodes from element
	 */
	this.removeAllChildNodes = function(target){
		if (target && "string" == typeof(target)){
			target = document.getElementById(target);
		}
		if (target){
			while (target.hasChildNodes()) {
				target.removeChild(target.firstChild);
			}
		}
	};
	/**
	 * Checks if browser is Internet Explorer and returns its version
	 */
	this.checkIE = function(){
		var isIE = false;
		var ua = navigator.userAgent.toLowerCase();
		var re = new RegExp("msie ([0-9]{1,}[\.0-9]{0,})");
		if (re.exec(ua) != null) {
			isIE = parseFloat(RegExp.$1);
		}
		return isIE;
	};
	/**
	 * Retrieve elements by their class name
	 * @param	{String}		className	Class name that will be searched
	 * @param	{String}		tagName		Tag name of elements to search, if not provided, will search in all tags
	 * @param	{DOM Object}	elmObj		DOM element in witch we need to find elements, if not provided, will search in whole document
	 */
	this.elmentsByClass = function (className, tagName, elmObj){
		var retArr = [];
		if (!tagName){
			tagName = '*';
		}
		if (!elmObj){
			elmObj = document;
		}
		var searchRegExp = new RegExp('\\b' + className + '\\b');
		var searchElements = elmObj.getElementsByTagName(tagName);
		
		for (var i = 0 ; i < searchElements.length ; i++)
		{
			var className = searchElements[i].className;
			
			if (searchRegExp.test(className))
				retArr.push(searchElements[i]);
		}
		return retArr;
	};
	/**
	 * Check if string is notset, empty or contains only space characters 
	 */
	this.isEmpty = function(text){
		var empty = true;
		var regExp = /\S/;
		if (text && regExp.test(text)){
			empty = false;
		}
		return empty;
	};
	/**
	 * Joins pseoudo array elements in to array and returns it
	 */
	this.joinHtmlCollections = function(){
		var retArr = [];
		for (var i = 0; i < arguments.length; i++){
			if (arguments[i].length){
				for (var k = 0; k < arguments[i].length; k++){
					retArr.push(arguments[i][k]);
				}
			}
		}
		return retArr;
	};
	/**
	 * Retrieves all form elements(inputs, selects, textareas)
	 * @param	{DOM Object}	holder	holder of form element
	 * @return	{Array}					array of founded form elements
	 */
	this.getAllFormElements = function(holder){
		var arrElements = [];
		if (holder){
			var selects = holder.getElementsByTagName('select');
			var inputs = holder.getElementsByTagName('input');
			var textareas = holder.getElementsByTagName('textarea');
			arrElements = wcmsUtils.joinHtmlCollections(selects, inputs, textareas);
		}
		return arrElements;
	};
	/**
	 * Checks if there any radiobutton checked in the group
	 */
	this.isRadioButtonChecked = function(holder, groupName){
		var inputs = holder.getElementsByTagName('input');
		var selected = false;
		for (var i = 0; i < inputs.length; i++){
			if (groupName == inputs[i].name && inputs[i].checked){
				selected = true;
				break;
			}
		}
		return selected;
	}
	/**
	 * Makes form fields validation
	 * @param	{DOM Object/String}		holder	form fields container DOM Object or id of it
	 * 
	 * @return	{Object}						validation object with main property success, and additional properties 
	 * 											for each validation type, that holds arrays of failed fields and one array 
	 * 											of fields passed validation
	 */
	this.validateFormFields = function(holder){
		var validation = {
			success: false,
			mandatory: [],
			maxlength: [],
			identical: [],
			regExp: [],
			customFn: [],
			validationPassed: []
		};
		if (holder && "string" == typeof(holder)){
			holder = document.getElementById(holder);
		}
		if (holder){
			formFields = this.getAllFormElements(holder);
			for (var i = 0; i < formFields.length; i++){
				var mandatory = formFields[i].getAttribute("__mandatory");
				var maxlength = formFields[i].getAttribute("maxlength");
				var identical = formFields[i].getAttribute("__identical");
				var regExp = formFields[i].getAttribute("__regExp");
				var customFn = formFields[i].getAttribute("__customFn");
				var type = formFields[i].getAttribute("type");
				var valid = true;
				
				if (mandatory && type == "radio" && !wcmsUtils.isRadioButtonChecked(holder, formFields[i].name)){
					validation.mandatory.push(formFields[i]);
					valid = false;
				}
				else if (mandatory && type == "checkbox" && !formFields[i].checked){
					validation.mandatory.push(formFields[i]);
					valid = false;
				}
				else if (mandatory && wcmsUtils.isEmpty(formFields[i].value)){
					validation.mandatory.push(formFields[i]);
					valid = false;
				}
				
				if (maxlength){
					var strLength = formFields[i].value.toString().length;
					if (strLength > maxlength){
						validation.maxlength.push(formFields[i]);
						valid = false;
					}
				}
				
				if (identical){
					var checkField = document.getElementById(identical);
					if (!checkField || checkField && checkField.value != formFields[i].value){
						validation.identical.push(formFields[i]);
						valid = false;
					}
				}
				
				if (regExp){
					var regTest = new RegExp(regExp, 'i');
					if (!regTest.test(formFields[i].value)){
						validation.regExp.push(formFields[i]);
						valid = false;
					}
				}
				
				if (customFn && window[customFn]){
					if (!window[customFn](formFields[i], holder)){
						validation.customFn.push(formFields[i]);
						valid = false;
					}
				}
				
				if (valid){
					validation.validationPassed.push(formFields[i]);
				}
			}
		}
		if (!validation.mandatory.length && !validation.maxlength.length && !validation.identical.length && !validation.regExp.length && !validation.customFn.length){
			validation.success = true;
		}
		return validation;
	};
	/**
	 * Checks element for class presence and add provided class name if not found
	 */
	this.addClass = function(element, className){
		if ("string" == typeof(element)){
			element = document.getElementById(element);
		}
		if (element){
			var elementClassName = element.className + "";
			if (-1 == elementClassName.indexOf(className)){
				element.className += " " + className;
			}
		}
	};
	/**
	 * Checks element for class presence and removes provided class name if found
	 */
	this.removeClass = function(element, className){
		if ("string" == typeof(element)){
			element = document.getElementById(element);
		}
		if (element){
			var elementClassName = element.className + "";
			if (-1 != elementClassName.indexOf(className)){
				if (-1 != elementClassName.indexOf(className + " ")){
					className += " ";
				}
				else if(-1 != elementClassName.indexOf(" " + className)){
					className = " " + className;
				}
				elementClassName = elementClassName.replace(className, "");
				element.className = elementClassName;
			}
		}
	};
	/**
	 * Checks for default value of the element, and sets it if there no value provided from user om blur, or removes it if user focus on field
	 * @param	{DOM Object}	element		form element with default value
	 * @param	{Boolean}		isBlur		true if we have blur event
	 */
	this.handleDefaultValue = function(element, isBlur){
		if (element){
			if (isBlur && wcmsUtils.isEmpty(element.value) && element.defaultValue){
				element.value = element.defaultValue;
			}
			else if (!isBlur && element.value == element.defaultValue){
				element.value = "";
			}
		}
	};
	/**
	 * Finds absolute position of the element according to the most top layout element in the DOM(html)
	 * @param	{DOM Object}	elmObj		DOM element wich coordinates we need to find
	 */
	this.findPosition = function (elmObj){
		var curLeft = curTop = 0;
		if (elmObj.offsetParent){
			do{
				curLeft += elmObj.offsetLeft;
				curTop 	+= elmObj.offsetTop;
			}
			while (elmObj = elmObj.offsetParent);
			
			return {'x' : curLeft, 'y' : curTop};
		}
	};
};

/**
 * Validates form and submits it if everything is filled right
 * @param	{DOM Object/String}		form	DOM object of form element or id of its element
 */
var validateAndSubmitForm = function(form, notificationContainerId){
	if (form && "string" == typeof(form)){
		form = document.getElementById(form);
	}
	if (form){
		var validation = wcmsUtils.validateFormFields(form);
		var notificationContainer = document.getElementById(notificationContainerId);
		if (validation.success){
			if (notificationContainer){
				wcmsUtils.removeAllChildNodes(notificationContainer);
				notificationContainer.style.display = "none";
			}
			form.submit();
		}
		else {
			if (validation.mandatory.length){
				for (var i = 0; i < validation.mandatory.length; i++){
					wcmsUtils.addClass(validation.mandatory[i], "formFieldError");
					wcmsUtils.addClass("label_" + validation.mandatory[i].id, "formLabelError");
				}
			}
			if (validation.maxlength.length){
				for (var i = 0; i < validation.maxlength.length; i++){
					wcmsUtils.addClass(validation.maxlength[i], "formFieldError");
					wcmsUtils.addClass("label_" + validation.maxlength[i].id, "formLabelError");
				}
			}
			if (validation.identical.length){
				for (var i = 0; i < validation.identical.length; i++){
					wcmsUtils.addClass(validation.identical[i], "formFieldError");
					wcmsUtils.addClass("label_" + validation.identical[i].id, "formLabelError");
				}
			}
			if (validation.regExp.length){
				for (var i = 0; i < validation.regExp.length; i++){
					wcmsUtils.addClass(validation.regExp[i], "formFieldError");
					wcmsUtils.addClass("label_" + validation.regExp[i].id, "formLabelError");
				}
			}
			if (validation.customFn.length){
				for (var i = 0; i < validation.customFn.length; i++){
					wcmsUtils.addClass(validation.customFn[i], "formFieldError");
					wcmsUtils.addClass("label_" + validation.customFn[i].id, "formLabelError");
				}
			}
			if (validation.validationPassed.length){
				for (var i = 0; i < validation.validationPassed.length; i++){
					wcmsUtils.removeClass(validation.validationPassed[i], "formFieldError");
					wcmsUtils.removeClass("label_" + validation.validationPassed[i].id, "formLabelError");
				}
			}
			if (notificationContainer){
				wcmsUtils.removeAllChildNodes(notificationContainer);
				notificationContainer.appendChild(document.createTextNode("Fehler! Bitte ueberpruefen Sie die rot markierten Felder!"));
				notificationContainer.style.display = "block";
			}
		}
	}
};
/**
 * Used to switch tabs in tabcontent component(part of page content component)
 */
var tabswitch = function(id, phid, tabcount){
	var contentHolder = document.getElementById("tabcontent_" + phid + "_body");
	var contentSource = document.getElementById("tabcontent_" + phid + "_" + id);
	if (contentHolder){
		for(var i = 0; i <= tabcount; i++){
			document.getElementById("tabelement_" + phid + "_" + i).className = "tabpassive";
		}
		if (contentSource){
			contentHolder.innerHTML = contentSource.innerHTML;
		}
		else {
			contentHolder.innerHTML = "";
		}
		document.getElementById("tabelement_" + phid + "_" + id).className = "tabactive";
	}
	return false;
};
/**
 * Used to navigate back if we have ability to navigate back using history
 */
var goBack = function(){
	if (window.history.length){
		window.history.back();
	}
};
/**
 * Switches blocks selected by jquery selector.
 * @param 	{String}	selector
 * @return 	{Boolean}	returns false to use in a elements for supressing href clicking
 */
var changeBanners = function(selector){
	if (!selector){
		selector = 'div.bannerBlock';
	}
	var bannerBlocks = $(selector);
	for (var i = 0; i < bannerBlocks.length; i++){
		if (bannerBlocks[i].style.display != "none"){
			bannerBlocks[i].style.display = "none";
			var index = 0;
			if (i < bannerBlocks.length - 1){
				index = i + 1;
			}
			bannerBlocks[index].style.display = "";
			break;
		}
	}
	return false;
};
/**
 * Changes display on data base on selelcted radio button
 * @param	{Object}	elm		radio button html object
 * @param	{String}	baseId	base part of id.
 */
var changeDataSource = function (elm, baseId){
	var oldSource = window.selectedDataSource && window.selectedDataSource[baseId]? window.selectedDataSource[baseId] : document.getElementById(baseId + "_0_data");
	var dataSource = document.getElementById(elm.id + '_data');
	if (oldSource){
		wcmsUtils.addClass(oldSource, "nondisplayedElement");
	}
	if (dataSource){
		wcmsUtils.removeClass(dataSource, "nondisplayedElement");
		window.selectedDataSource[baseId] = dataSource;
	}
};
