/* 
 * jsForms JavaScriptUtils module
 * 
 * Extends abilities of standard (X)HTML forms.
 * 
 */
 
 
 		
		/*
		 * popupCalendar
		 * 
		 * Associates a popup calendar with a input field.
		 *
		 */
		//var calvalarr;
		var ccm = now.getMonth();
		var ccy = now.getFullYear();
		var popupCalendarElem; // Handle to an jQuery element which represents popup calendar window
		var popupCalendarTarget; // Handle to an jQuery element which currently invokes popupcalendar
		var popupCalendarSelYearElem;
		var popupCalendarSelMonthElem;
		var bDisableEarlierDates;
		var bDisableWeekends;
		var popupCalendarselDaysElems = new Array(42);
		var popupCalendarSelected;
		
		
		
		
 
 		
		/* 
		 * popupTime
		 * 
		 * Associates a popup timepicker with a input field.
		 * 
		 */
		var popupTimePicker;
		var popupTimePickerTarget;
		var bSelectedHour;
		var bSelectedMinutes;
		var curTime;
		var newTime = new Array(3);
		
		
		
 
 
 
// Create days grid for renderCalendar()
function prepareDaysGrid(elem, daysElem) {
	for(kk=1; kk<=6; kk++) {
		newTr = $(document.createElement('tr')).appendTo(elem);
		for(var tt=1; tt<=7; tt++) {
			var newTd = $(document.createElement('td')).appendTo(newTr);
			daysElem[7 * (kk-1) + tt] = $(document.createElement('a')).appendTo(newTd);
			if ((tt == 7) || ((tt == 1) && (!bStartMonday)) || ((tt == 6) && (bStartMonday))) { // Weekend
				newTd.addClass('wk');
			}
		}
	}	
}


// Universal function for rendering calendars
// day, month, year, elements, choose event
function renderCalendar(hd, cm, cy, daysElem, chooseEvent, disableEarlierDates, disableWeekends, weekMode) {			
	function weekOver () { 
		$(this).parents('tr').addClass('hoverWeek');
	}
	
	function weekOut () { $(this).parents('tr').removeClass('hoverWeek'); }
	
	var sd = now.getDate();
	
	td = new Date(cy, cm, 1);
	
	cd = td.getDay();
	if (bStartMonday) {
		if (cd == 0) cd = 7;
		cd--;
	}
	cd++;
	
	// Week selecting erase
	daysElem[1].parents('tbody').find('tr').removeClass('cChCurr');

	var cmtt = date.set(cy, cm, 1).getDaysInMonth() - cd + 1;
	

	for (var d = 1; d < cd; d++) { // Dny pred	
		cmtt++;
		daysElem[d].removeClass('cChCurr').removeClass('cChToday').removeClass('cChNot').removeClass('hoverable').text('' + cmtt).unbind().click( function () { return false; } );
	}
	// pocet mesicu tohoto tydne!
	for (d = cd; d < (date.set(cy, cm, 1).getDaysInMonth() - -cd); d++) {
		var curElem = daysElem[d];
		curElem.text(d - cd - (-1));
		curElem.removeClass('cChCurr').removeClass('cChToday').removeClass('cChNot').removeClass('hoverable');
		// Disable some dates
		if (
				(disableEarlierDates &&
					(
						(cy < now.getFullYear()) ||
						(
							(cy == now.getFullYear()) && (cm < now.getMonth())
						) ||
						(
							(cy == now.getFullYear()) && (cm == now.getMonth()) && ((d - cd - (-1)) < sd)
						)
					)
				)
			 || 
				(disableWeekends && curElem.parent('td').hasClass('wk'))
			) {
			curElem.addClass('cChNot').unbind().click( function () { return false; } );
			if (((d - cd - (-1)) == sd)  && (cm == now.getMonth()) && (cy == now.getFullYear())) {
				curElem.addClass('cChToday');
			}
		} else {
			if (((d - cd - (-1)) == sd)  && (cm == now.getMonth()) && (cy == now.getFullYear())) {
				curElem.addClass('cChToday');
			}
			if (weekMode && (new Date(cy, cm, (d - cd - -1)).getISOWeek() == hd)) { // Select week
				curElem.parents('tr').addClass('cChCurr');
			} else if (!weekMode && ((d - cd - -1) == hd)) { // Select day
				curElem.addClass('cChCurr');		
			}
			curElem.addClass('hoverable').click(chooseEvent);
		}
		curElem.mouseover(weekOver).mouseout(weekOut);
	}
	for (var x = d; x <= 42; x++) {
		daysElem[x].removeClass('cChCurr').removeClass('cChToday').removeClass('cChNot').removeClass('hoverable')
			.text(''+x-d +1).unbind().click( function () { return false; } );
	}
}


 
 
 function renderPopupCalendar() {
			popupCalendarSelYearElem.val(ccy);
			popupCalendarSelMonthElem.val(ccm);
			if (popupCalendarSelected && (popupCalendarSelected.getMonth() == ccm) && (popupCalendarSelected.getFullYear() == ccy)) {
				var selDay = popupCalendarSelected.getDate();
			} else {
				var selDay = null;		
			}	
			renderCalendar(selDay, ccm, ccy, popupCalendarselDaysElems, cs_click, bDisableEarlierDates, bDisableWeekends);
		}

		// Showing-of-calendar handling function
		var initCalendar = function () {
				
			popupCalendarTarget = $(this);
			//popupCalendarTarget.css('background', 'red');
			
			bDisableEarlierDates = popupCalendarTarget.hasClass('future');
			bDisableFutureDates = popupCalendarTarget.hasClass('past');
			bDisableWeekends = popupCalendarTarget.hasClass('noWeekends');
			
			popupCalendarSelected = parseFieldDate(popupCalendarTarget.val()); // Retrieve current value
			if (popupCalendarSelected) {
				ccm = popupCalendarSelected.getMonth();
				ccy = popupCalendarSelected.getFullYear();
				renderPopupCalendar();
			} else {
				if (popupCalendarTarget.hasClass('forceLastDate')) {
					ccm = now.getMonth();
					ccy = now.getFullYear();
				}
			 	renderPopupCalendar(); // Render default calendar
			}
		
			// Fill calendar's year and month selectors with data
			popupCalendarSelYearElem.get(0).options.length = 0;
			if (bDisableEarlierDates || bDisableFutureDates) { // Render only future years
				if (bDisableEarlierDates) {
					var lg = ccy - now.getFullYear() + 14;
					if (lg < 10) lg = 10;
					if (lg > 50) {
						var startingYear = ccy - 49;
						lg = 50
					} else {
						var startingYear = now.getFullYear();	
					}
				} else {
					// 2008 - 1910
					var lg = now.getFullYear() - ccy;
					if (lg < 100) lg = 100;
					if (lg > 100) {
						var startingYear = ccy;
						lg = 100
					} else {
						var startingYear = now.getFullYear() - lg + 1;	
					}
				}
				var m = 0;
				if (ccy < startingYear) {
					popupCalendarSelYearElem.get(0).options[0] = new Option(ccy, ccy);
					m = 1;
				}
				for (var i = startingYear; i < (startingYear + lg); i++) {
					popupCalendarSelYearElem.get(0).options[i - startingYear + m] = new Option(i, i);
				}				
			} else {
				// Normal calendar year select range
				if ((now.getFullYear() - ccy) > 0) {
					var ymax = (now.getFullYear() - ccy);
					if (ymax > 200) ymax = 200;
				} else {
					var ymax = 0;
				}
				
				for (var i = 0; i < 125 + ymax; i++) {
					popupCalendarSelYearElem.get(0).options[i] = new Option(ccy - -i -100, ccy - -i -100);
				}
			}
			popupCalendarSelYearElem.val(ccy);

			popupCalendarElem.makeForm(popupCalendarTarget);
			
		}
		
 		// Function handling day-pick event
		var cs_click = function () {
			popupCalendarTarget.val(formatFieldDate($(this).text(), ccm - -1, ccy));
			closeLastFormLayerElement();
			return false;
		}
		
 
 
 
 	function closePopupTimePicker () {
			if ((newTime[1] != undefined) && (newTime[0] != undefined)) popupTimePickerTarget.val(formatFieldTime(newTime[0], newTime[1]));
			if (bSelectedHour && bSelectedMinutes) closeLastFormLayerElement();
		}
		
		var selHour = function () { // Select color
			popupTimePicker.find('.hours').find('.sel').removeClass('sel');
			$(this).addClass('sel');
			bSelectedHour = true;
			newTime[0] = $(this).html();
			closePopupTimePicker();
		}
		
		var selMinutes = function () { // Select color
			popupTimePicker.find('.minutes').find('.sel').removeClass('sel');
			$(this).addClass('sel');
			if (curTime) bSelectedHour = true;
			bSelectedMinutes = true;
			newTime[1] = $(this).html();
			closePopupTimePicker();		
		}

		var initTimePicker = function () {
			
			function timeZeroFill(str) {
				str += ''; 
				if (str.length == 1) str = '0' + str;
				return str;
			}
			
			popupTimePickerTarget = $(this);
			
			curTime = parseFieldTime(popupTimePickerTarget.val()); // Retrieve current value
			if (curTime) newTime = curTime;
			
			bSelectedHour = false;
			bSelectedMinutes = false;
			
			var innerValues = '';			
			var selectedHour = null;
			
			// Hours selector
			if ((popupTimePickerDefaultHourTo - popupTimePickerDefaultHourFrom + 1) > 12) innerValues += '<div class="hours scrollable">'; 
			else innerValues += '<div class="hours">'; 
			for (var i = popupTimePickerDefaultHourFrom; i <= popupTimePickerDefaultHourTo; i++) {
				if (curTime && (curTime[0] == i)) {
					selectedHour = i; 
					innerValues += '<div class="item sel hour-'+i+'">' + i + '</div>';
				} else innerValues += '<div class="item hour-'+i+'">' + i + '</div>';
			}
			innerValues += '</div>';

			// Minutes selector
			innerValues += '<div class="minutes">';
			for (var i = 0; i < 12; i++) {
				if (curTime && (curTime[1] == (i * 5))) innerValues += '<div class="item sel">' + timeZeroFill(i * 5) + '</div>';
				else innerValues += '<div class="item">' + timeZeroFill(i * 5) + '</div>';
			}
			innerValues += '</div>';
			
			popupTimePicker.html('<div class="inner">' + innerValues + '</div><!--[if lte IE 6.5]><iframe></iframe><![endif]-->');
			
			popupTimePicker.find('.item').addHoverAbility();
			popupTimePicker.find('.hours').find('div').click( selHour );
			popupTimePicker.find('.minutes').find('div').click( selMinutes );
			
			popupTimePicker.makeForm(popupTimePickerTarget);		

			if (selectedHour == null) {
				popupTimePicker.find('.hours').scrollTo(popupTimePicker.find('.hours .hour-' + 6), 200);	
			} else if (selectedHour > 6) popupTimePicker.find('.hours').scrollTo(popupTimePicker.find('.hours .hour-' + (selectedHour - 6)), 200);
		}
		
		
 
 
var initForms = function(){


		
		
		// Renders calendar's HTML
		var outstr = "";
		outstr = outstr + ('<table cellspacing="0"><thead>');
		outstr = outstr + ('<tr>');
		outstr = outstr + ('<th align="center" colspan="7"><select id="popupcalendar-selmonth" name="popupcalendar-selmonth">');	
		for (var i = 0; i < 12; i++) {
			outstr = outstr + '<option value="'+i+'" >'+date.nameOfMonths[i]+'</option>';
		}
		outstr = outstr + ('</select><select id="popupcalendar-selyear" name="popupcalendar-selyear">');
		outstr = outstr + ('</select></th>');
		outstr = outstr + ('</tr>');
		outstr = outstr + ('<tr class="bottom">');
		for(var kk=1; kk<=7; kk++) {
			outstr = outstr + ('<th>' + date.nameOfDaysShort[kk % 7] +'</th>');
		}			
		outstr = outstr + ('</tr>');
		outstr = outstr + ('</thead><tbody class="calendarChooser">');
		outstr = outstr + ('</tbody></table><!--[if lte IE 6.5]><iframe></iframe><![endif]-->');
		
		popupCalendarElem = $(document.createElement('div'));
		popupCalendarElem.attr('id', 'popcalendar').addClass('select-free').html(outstr).css({
			position: 'absolute', 
			zIndex: 6100
		}).appendTo($('body')).hide();

		prepareDaysGrid(popupCalendarElem.find(".calendarChooser"), popupCalendarselDaysElems);
		
		// Cache calendar elements
		popupCalendarSelYearElem = $('#popupcalendar-selyear');
		popupCalendarSelMonthElem = $('#popupcalendar-selmonth');
	
		// Attach events to month and year selectors
		popupCalendarSelYearElem.change( function () {
			ccy = $(this).val();
			renderPopupCalendar();
		});
		popupCalendarSelMonthElem.change( function () {
			ccm = $(this).val();
			renderPopupCalendar();
		});

		
 
 


	
		
		// Insert timePicker into DOM
		var outstr = "";
		var oDiv = $(document.createElement('div'));
		oDiv.attr('id', 'poptime');
		oDiv.addClass('select-free');
		oDiv.hide();
		oDiv.html(outstr);
		$('body').append(oDiv);
		oDiv.hide();
		popupTimePicker = $(oDiv);
 
 
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
jQuery.fn.registerForms = function() {

	var jsFormsElements = this;
	
		
	if (jsFormsElements.length) {

	

	
	
	
	
		/* Make items alive */
		
		jsFormsElements.find('.JSBlocked').show();




	
	
	
	


		/* 
		 * modOnCheck, hideOnCheck
		 * 
		 * Hides/shows, enables/disables elements according to a 'checked' attribute of the associated checkbox field
		 * 
		 */
		jsFormsElements.find(':checkbox.modOnCheck').each(function () {
			function hideShowOnCheck(elem) {
				elem = $(elem);
				elemForm = elem.parents('form').eq(0);
				if (elem.attr('checked')) {
					elemForm.find(".showOnCheck-" + elem.attr('name')).show();
					elemForm.find(".hideOnCheck-" + elem.attr('name')).hide();
					elemForm.find(".disableOnCheck-" + elem.attr('name')).attr("disabled", true);
					elemForm.find(".enableOnCheck-" + elem.attr('name')).removeAttr("disabled");
				} else {
					elemForm.find(".showOnCheck-" + elem.attr('name')).hide();
					elemForm.find(".hideOnCheck-" + elem.attr('name')).show();
					elemForm.find(".disableOnCheck-" + elem.attr('name')).removeAttr("disabled");
					elemForm.find(".enableOnCheck-" + elem.attr('name')).attr("disabled", true);			 
				}
			}
			var eventItemName = $(this).attr('name');
			$(this).click(function () { hideShowOnCheck(this); });
			hideShowOnCheck(this);
		});
	

		/* 
		 * chckTgl
		 * 
		 * Toggle 'checked' attribute of associated checkboxes.
		 * 
		 */
		var chckTglTargetsCache = new Array;
		var chckTglCache = new Array;
		jsFormsElements.find(':checkbox.chckTgl').each(function () {
			elem = $(this);
			elemName = elem.attr('name');
			elemForm = elem.parents('form').eq(0);

			chckTglTargetsCache[elemName] = elemForm.find('.chckTgl-' + elemName);
			chckTglCache[elemName] = elem;
						
			function updateChckTgl() {
				elem = $(this);
				elemClassName = elem.attr('class') + " ";
				if (elem.attr('checked')) { // Checked
					// Too complex, do nothing yet 
				} else { // Unchecked
					// Retrieve associated checkboxes and uncheck them
					var fPos = -1;
					var associatedCheckboxes = new Array;
					while (true) {
						fPos = elemClassName.indexOf('chckTgl-', ++fPos);
						if (fPos != -1) {
							chckTglCache[elemClassName.substring(fPos + 8, elemClassName.indexOf(' ', fPos))].attr('checked', '');
						} else {
							break;
						}
					}
				}
			}
			chckTglTargetsCache[elemName].unbind('change'); // Prevents from attaching procChckTgl more times
			chckTglTargetsCache[elemName].change(updateChckTgl);
			function procChckTgl() {
				elem = $(this);
				chckTglTargetsCache[elem.attr('name')].attr('checked', elem.attr('checked') ? 'checked' : '');
			}
			var eventItemName = $(this).attr('name');
			elem.click(procChckTgl);
			/* Go through all associated checkboxes */
			var allChecked = true;
			for (var i = 0; i < chckTglTargetsCache[elemName].length; i++) {
				if (!chckTglTargetsCache[elemName].get(i).checked) {
					allChecked = false;
					break;
				}
			}
			/* If all checked, check controller too */
			if (allChecked) {
				elem.attr('checked', true);	
			}
		});
	
		
		/* 
		 * modOnSelect
		 * 
		 * Hides/shows, enables/disables elements according to currently selected item's value of the associated checkbox field
		 * 
		 */
		// Hidden select for cached options removed from DOM
		var modOnSelectSelectsCache = new Object;
		var oSelect = $(document.createElement('select'));
		oSelect.attr('id', 'modOnSelectSelectsCache');
		oSelect.hide();
		$('body').append(oSelect);
		oSelect.hide();
		
		jsFormsElements.find('select.modOnSelect').each(function () {
			
			// Initialize cache for OPTION elements from SELECTs
			modOnSelectSelectsCache[$(this).attr('name')] = new Array;
						
			var hideShowOnSelect = function() {

				function hideOption(elemOption, modOnSelectName) {
					// If not in cache, add to cache and sign parent element
					var cacheIndex = jQuery.inArray(elemOption.get(0), modOnSelectSelectsCache[modOnSelectName]);
					// Pozdeji vylepsit - pridavani atributu ktery neni v souladu s DTD
					if (cacheIndex == -1) {
						elemOption.attr('parentSelect', elemOption.parent('select').attr('name'));
						modOnSelectSelectsCache[modOnSelectName][modOnSelectSelectsCache[elem.attr('name')].length] = elemOption.get(0);	
					} else {
						$(modOnSelectSelectsCache[modOnSelectName][cacheIndex]).attr('parentSelect', elemOption.parent('select').attr('name'));
					}
					// Remove from DOM temporarily
					if (elemOption.siblings().size() == 0) elemOption.parent().attr('disabled', 'true'); // Disable select when no more options left
					elemOption.appendTo('#modOnSelectSelectsCache');
					elemOption.removeAttr('selected');
				}

				var elem = $(this);
				var elemForm = elem.parents('form').eq(0);
				var paramMark = 'on-' + elem.attr('value');
				
				var associatedElements = elemForm.find(".hideOnSelect-" + elem.attr('name'));	
				for (var i = 0; i < associatedElements.length; i++) {
					var affectedElem = $(associatedElements[i]);
					if (affectedElem.hasClass(paramMark)) {
						// Special behaviour if an option is affected.
						// - IE does not hide options in select after .hide()
						if (affectedElem.attr('tagName') == 'OPTION') {

							hideOption(affectedElem, elem.attr('name'));
							
						} else {
							affectedElem.hide();
						}
					} else {
						affectedElem.show();						
					}
				}
				
				var associatedElements = elemForm.find(".showOnSelect-" + elem.attr('name'));
				for (var i = 0; i < associatedElements.length; i++) {
					var affectedElem = $(associatedElements[i]);
					if (affectedElem.hasClass(paramMark)) {
						affectedElem.show();		
					} else {
						// Special behaviour if an option is affected.
						// - IE does not hide options in select after .hide()
						if (affectedElem.attr('tagName') == 'OPTION') {
							//alert(affectedElem.attr('tagName'));
							hideOption(affectedElem, elem.attr('name'));
						} else {
							affectedElem.hide();
						}
					}		
				}
				
				var associatedElements = elemForm.find(".enableOnSelect-" + elem.attr('name'));
				for (var i = 0; i < associatedElements.length; i++) {
					var affectedElem = $(associatedElements[i]);
					if (affectedElem.hasClass(paramMark)) {
						affectedElem.removeAttr("disabled");
					} else {
						affectedElem.attr('disabled', 'disabled');
						if (affectedElem.attr('tagName') == 'OPTION') {
							affectedElem.removeAttr('selected'); // Disabled OPTION cannot be selected
						}					
					}				
				}
				
				var associatedElements = elemForm.find(".disableOnSelect-" + elem.attr('name'));
				for (var i = 0; i < associatedElements.length; i++) {
					var affectedElem = $(associatedElements[i]);
					if (affectedElem.hasClass(paramMark)) {
						affectedElem.attr('disabled', 'disabled');
						if (affectedElem.attr('tagName') == 'OPTION') {
							affectedElem.removeAttr('selected'); // Disabled OPTION cannot be selected
						}
					} else {
						affectedElem.removeAttr("disabled");
					}
				}
								
				// Process OPTIONs - return back to DOM if needed	
				for (var i = 0; i < modOnSelectSelectsCache[elem.attr('name')].length; i++) {
					var cachedOption = $(modOnSelectSelectsCache[elem.attr('name')][i]);			
					if (
						(cachedOption.is('.showOnSelect-' + elem.attr('name')) && cachedOption.is('.on-' + elem.attr('value')))
						||
						(cachedOption.is('.hideOnSelect-' + elem.attr('name')) && !cachedOption.is('.on-' + elem.attr('value')))
					 	) {
							var parentSelect = $("select[name='" + cachedOption.attr('parentSelect') + "']");
							cachedOption.removeAttr('parentSelect'); // Remove DTD incomaptible attribute
							// Insert back to DOM
							cachedOption.appendTo(parentSelect);
							parentSelect.removeAttr('disabled'); // Enabled select when there is more than 1 option
							
					}
				}
		
				return true;
			}
			$(this).change(hideShowOnSelect);
			$(this).change(); // Invoke on start
		});	
	
	
	
	
	
	



		/* 
		 * calendarSelector
		 * 
		 * After an invoker element, creates and static calendar with month-selecting ability
		 * 
		 */
		var calendarSelInvoker = $('#dateSelector');
		if (calendarSelInvoker) {
			var calendarSelDaysElems = new Array(42);
			var calendarSelElem = $(document.createElement('table')).attr('cellspacing', '0').addClass('dateSelector').insertAfter(calendarSelInvoker).html(			
					"<thead><tr><th><a id='prevMonth' href=''><</a></th><th id='monthCaption' colspan='5'></th><th><a id='nextMonth' href=''>></a></th></tr>");
			var weekstr = calendarSelElem.html() + ('<tr class="bottom">');
			for(var kk=1; kk<=7; kk++) {
				weekstr = weekstr + ('<th>' + date.nameOfDaysShort[kk % 7] + '</th>');
			}
			weekstr = weekstr + ('</tr>');
			calendarSelElem.html(weekstr + "</thead><tbody class='calendarChooser'></tbody>");
			prepareDaysGrid(calendarSelElem.find(".calendarChooser"), calendarSelDaysElems);
			var calendarSelCaption = calendarSelElem.find('#monthCaption');	
			
			// initialize values for default view	
			var calendarSelAttachURL = (calendarSelInvoker.getClassParam("url"))
			if (calendarSelAttachURL == null) calendarSelAttachURL = '';
			var bcalendarSelWeekMode = (calendarSelInvoker.getClassParam("week") != null);
			var calendarSelSelYear = calendarSelInvoker.getClassParam("year");
			var calendarSelSelMonth = calendarSelInvoker.getClassParam("month") - 1;
			if (bcalendarSelWeekMode) {
				calendarSelElem.addClass('weekMode');
				var calendarSelStartWeek = calendarSelInvoker.getClassParam("week");
			} else {
				var calendarSelStartDay = calendarSelInvoker.getClassParam("day");	
			}
			var calendarSelStartYear = calendarSelSelYear;
			var calendarSelStartMonth = calendarSelSelMonth;
	
			// Event after clicking the calendar
			function calendarSelSelDay () {
				self.location = calendarSelAttachURL +
					"&month=" + (calendarSelSelMonth - -1) +
					"&year=" + calendarSelSelYear +
					"&day=" + ($(this).text()) +
					"&week=" + date.set(calendarSelSelYear, calendarSelSelMonth, $(this).text()).getISOWeek();
				return false;
			}
			function rendercalendarSel () {
				calendarSelCaption.html(date.nameOfMonths[calendarSelSelMonth] + '&nbsp;' + calendarSelSelYear);
				if (bcalendarSelWeekMode) renderCalendar((calendarSelSelYear == calendarSelStartYear) ? calendarSelStartWeek : null, calendarSelSelMonth, calendarSelSelYear, calendarSelDaysElems, calendarSelSelDay, false, false, true);
				else renderCalendar(((calendarSelSelYear == calendarSelStartYear) && (calendarSelSelMonth == calendarSelStartMonth)) ? calendarSelStartDay : null, calendarSelSelMonth, calendarSelSelYear, calendarSelDaysElems, calendarSelSelDay, false, false);
			}
			// Month switchers
			calendarSelElem.find('#prevMonth').click( function () {
				if (calendarSelSelMonth == 0) {
					calendarSelSelYear--;
					calendarSelSelMonth = 11;
				} else calendarSelSelMonth--;
				rendercalendarSel();
				return false;		
			});
			calendarSelElem.find('#nextMonth').click( function () {
				if (calendarSelSelMonth == 11) {
					calendarSelSelYear++;
					calendarSelSelMonth = 0;
				} else calendarSelSelMonth++;
				rendercalendarSel();
				return false;
			});
			rendercalendarSel();
		}
		
		
		
	
		
	
	

			// Associate popup calendar with marked input fields
			jsFormsElements.find(':text.popupCalendar').each(function () {		
			
				$(this).focus(initCalendar).keyup(function() {	
					if ($(this).val().length === 0) {	
						initCalendar();
					} else {
						closeLastFormLayerElement();
					}
				});
			});
		
		




		/*
		// TODO
		if (!seleniumSafeMode) {
			// Associate popup timepicker with marked input fields
			jsFormsElements.find(':text.popupTime').each(function () {
				$(this).focus(initTimePicker);
				$(this).keyup(initTimePicker);
				$(this).keydown(initTimePicker);
			});
		}
		*/




		// $Id: farbtastic.js,v 1.2 2007/01/08 22:53:01 unconed Exp $
		// Farbtastic 1.2
		
		jQuery.fn.farbtastic = function (callback) {
		  $.farbtastic(this, callback);
		  return this;
		};
		
		jQuery.farbtastic = function (container, callback) {
		  var container = $(container).get(0);
		  return container.farbtastic || (container.farbtastic = new jQuery._farbtastic(container, callback));
		}
		
		jQuery._farbtastic = function (container, callback) {
		  // Store farbtastic object
		  var fb = this;
		
		  // Insert markup
		  $(container).html('<div class="farbtastic"><div class="color"></div><div class="wheel"></div><div class="overlay"></div><div class="h-marker marker"></div><div class="sl-marker marker"></div></div>');
		  var e = $('.farbtastic', container);
		  fb.wheel = $('.wheel', container).get(0);
		  // Dimensions
		  fb.radius = 84;
		  fb.square = 100;
		  fb.width = 194;
		
		  // Fix background PNGs in IE6
		  if (navigator.appVersion.match(/MSIE [0-6]\./)) {
		    $('*', e).each(function () {
		      if (this.currentStyle.backgroundImage != 'none') {
		        var image = this.currentStyle.backgroundImage;
		        image = this.currentStyle.backgroundImage.substring(5, image.length - 2);
		        $(this).css({
		          'backgroundImage': 'none',
		          'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"
		        });
		      }
		    });
		  }
		
		  /**
		   * Link to the given element(s) or callback.
		   */
		  fb.linkTo = function (callback) {
		    // Unbind previous nodes
		    if (typeof fb.callback == 'object') {
		      $(fb.callback).unbind('keyup', fb.updateValue);
		    }
		
		    // Reset color
		    fb.color = null;
		
		    // Bind callback or elements
		    if (typeof callback == 'function') {
		      fb.callback = callback;
		    }
		    else if (typeof callback == 'object' || typeof callback == 'string') {
		      fb.callback = $(callback);
		      fb.callback.bind('keyup', fb.updateValue);
		      if (fb.callback.get(0).value) {
		        fb.setColor(fb.callback.get(0).value);
		      }
		    }
		    return this;
		  }
		  fb.updateValue = function (event) {
		    if (this.value && this.value != fb.color) {
		      fb.setColor(this.value);
		    }
		  }
		
		  /**
		   * Change color with HTML syntax #123456
		   */
		  fb.setColor = function (color) {
		    var unpack = fb.unpack(color);
		    if (fb.color != color && unpack) {
		      fb.color = color;
		      fb.rgb = unpack;
		      fb.hsl = fb.RGBToHSL(fb.rgb);
		      fb.updateDisplay();
		    }
		    return this;
		  }
		
		  /**
		   * Change color with HSL triplet [0..1, 0..1, 0..1]
		   */
		  fb.setHSL = function (hsl) {
		    fb.hsl = hsl;
		    fb.rgb = fb.HSLToRGB(hsl);
		    fb.color = fb.pack(fb.rgb);
		    fb.updateDisplay();
		    return this;
		  }
		
		  /////////////////////////////////////////////////////
		
		  /**
		   * Retrieve the coordinates of the given event relative to the center
		   * of the widget.
		   */
		  fb.widgetCoords = function (event) {
		    var x, y;
		    var el = event.target || event.srcElement;
		    var reference = fb.wheel;
		
		    if (typeof event.offsetX != 'undefined') {
		      // Use offset coordinates and find common offsetParent
		      var pos = { x: event.offsetX, y: event.offsetY };
		
		      // Send the coordinates upwards through the offsetParent chain.
		      var e = el;
		      while (e) {
		        e.mouseX = pos.x;
		        e.mouseY = pos.y;
		        pos.x += e.offsetLeft;
		        pos.y += e.offsetTop;
		        e = e.offsetParent;
		      }
		
		      // Look for the coordinates starting from the wheel widget.
		      var e = reference;
		      var offset = { x: 0, y: 0 }
		      while (e) {
		        if (typeof e.mouseX != 'undefined') {
		          x = e.mouseX - offset.x;
		          y = e.mouseY - offset.y;
		          break;
		        }
		        offset.x += e.offsetLeft;
		        offset.y += e.offsetTop;
		        e = e.offsetParent;
		      }
		
		      // Reset stored coordinates
		      e = el;
		      while (e) {
		        e.mouseX = undefined;
		        e.mouseY = undefined;
		        e = e.offsetParent;
		      }
		    }
		    else {
		      // Use absolute coordinates
		      var pos = fb.absolutePosition(reference);
		      x = (event.pageX || 0*(event.clientX + $('html').get(0).scrollLeft)) - pos.x;
		      y = (event.pageY || 0*(event.clientY + $('html').get(0).scrollTop)) - pos.y;
		    }
		    // Subtract distance to middle
		    return { x: x - fb.width / 2, y: y - fb.width / 2 };
		  }
		
		  /**
		   * Mousedown handler
		   */
		  fb.mousedown = function (event) {
		    // Capture mouse
		    if (!document.dragging) {
		      $(document).bind('mousemove', fb.mousemove).bind('mouseup', fb.mouseup);
		      document.dragging = true;
		    }
		
		    // Check which area is being dragged
		    var pos = fb.widgetCoords(event);
		    fb.circleDrag = Math.max(Math.abs(pos.x), Math.abs(pos.y)) * 2 > fb.square;
		
		    // Process
		    fb.mousemove(event);
		    return false;
		  }
		
		  /**
		   * Mousemove handler
		   */
		  fb.mousemove = function (event) {
		    // Get coordinates relative to color picker center
		    var pos = fb.widgetCoords(event);
		
		    // Set new HSL parameters
		    if (fb.circleDrag) {
		      var hue = Math.atan2(pos.x, -pos.y) / 6.28;
		      if (hue < 0) hue += 1;
		      fb.setHSL([hue, fb.hsl[1], fb.hsl[2]]);
		    }
		    else {
		      var sat = Math.max(0, Math.min(1, -(pos.x / fb.square) + .5));
		      var lum = Math.max(0, Math.min(1, -(pos.y / fb.square) + .5));
		      fb.setHSL([fb.hsl[0], sat, lum]);
		    }
		    return false;
		  }
		
		  /**
		   * Mouseup handler
		   */
		  fb.mouseup = function () {
		    // Uncapture mouse
		    $(document).unbind('mousemove', fb.mousemove);
		    $(document).unbind('mouseup', fb.mouseup);
		    document.dragging = false;
		  }
		
		  /**
		   * Update the markers and styles
		   */
		  fb.updateDisplay = function () {
		    // Markers
		    var angle = fb.hsl[0] * 6.28;
		    $('.h-marker', e).css({
		      left: Math.round(Math.sin(angle) * fb.radius + fb.width / 2) + 'px',
		      top: Math.round(-Math.cos(angle) * fb.radius + fb.width / 2) + 'px'
		    });
		
		    $('.sl-marker', e).css({
		      left: Math.round(fb.square * (.5 - fb.hsl[1]) + fb.width / 2) + 'px',
		      top: Math.round(fb.square * (.5 - fb.hsl[2]) + fb.width / 2) + 'px'
		    });
		
		    // Saturation/Luminance gradient
		    $('.color', e).css('backgroundColor', fb.pack(fb.HSLToRGB([fb.hsl[0], 1, 0.5])));
		
		    // Linked elements or callback
		    if (typeof fb.callback == 'object') {
		      // Set background/foreground color
		      $(fb.callback).css({
		        backgroundColor: fb.color,
		        color: fb.hsl[2] > 0.5 ? '#000' : '#fff'
		      });
		
		      // Change linked value
		      $(fb.callback).each(function() {
		        if (this.value && this.value != fb.color) {
		          this.value = fb.color;
		        }
		      });
		    }
		    else if (typeof fb.callback == 'function') {
		      fb.callback.call(fb, fb.color);
		    }
		  }
		
		  /**
		   * Get absolute position of element
		   */
		  fb.absolutePosition = function (el) {
		    var r = { x: el.offsetLeft, y: el.offsetTop };
		    // Resolve relative to offsetParent
		    if (el.offsetParent) {
		      var tmp = fb.absolutePosition(el.offsetParent);
		      r.x += tmp.x;
		      r.y += tmp.y;
		    }
		    return r;
		  };
		
		  /* Various color utility functions */
		  fb.pack = function (rgb) {
		    var r = Math.round(rgb[0] * 255);
		    var g = Math.round(rgb[1] * 255);
		    var b = Math.round(rgb[2] * 255);
		    return '#' + (r < 16 ? '0' : '') + r.toString(16) +
		           (g < 16 ? '0' : '') + g.toString(16) +
		           (b < 16 ? '0' : '') + b.toString(16);
		  }
		
		  fb.unpack = function (color) {
		    if (color.length == 7) {
		      return [parseInt('0x' + color.substring(1, 3)) / 255,
		        parseInt('0x' + color.substring(3, 5)) / 255,
		        parseInt('0x' + color.substring(5, 7)) / 255];
		    }
		    else if (color.length == 4) {
		      return [parseInt('0x' + color.substring(1, 2)) / 15,
		        parseInt('0x' + color.substring(2, 3)) / 15,
		        parseInt('0x' + color.substring(3, 4)) / 15];
		    }
		  }
		
		  fb.HSLToRGB = function (hsl) {
		    var m1, m2, r, g, b;
		    var h = hsl[0], s = hsl[1], l = hsl[2];
		    m2 = (l <= 0.5) ? l * (s + 1) : l + s - l*s;
		    m1 = l * 2 - m2;
		    return [this.hueToRGB(m1, m2, h+0.33333),
		        this.hueToRGB(m1, m2, h),
		        this.hueToRGB(m1, m2, h-0.33333)];
		  }
		
		  fb.hueToRGB = function (m1, m2, h) {
		    h = (h < 0) ? h + 1 : ((h > 1) ? h - 1 : h);
		    if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
		    if (h * 2 < 1) return m2;
		    if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
		    return m1;
		  }
		
		  fb.RGBToHSL = function (rgb) {
		    var min, max, delta, h, s, l;
		    var r = rgb[0], g = rgb[1], b = rgb[2];
		    min = Math.min(r, Math.min(g, b));
		    max = Math.max(r, Math.max(g, b));
		    delta = max - min;
		    l = (min + max) / 2;
		    s = 0;
		    if (l > 0 && l < 1) {
		      s = delta / (l < 0.5 ? (2 * l) : (2 - 2 * l));
		    }
		    h = 0;
		    if (delta > 0) {
		      if (max == r && max != g) h += (g - b) / delta;
		      if (max == g && max != b) h += (2 + (b - r) / delta);
		      if (max == b && max != r) h += (4 + (r - g) / delta);
		      h /= 6;
		    }
		    return [h, s, l];
		  }
		
		  // Install mousedown handler (the others are set on the document on-demand)
		  $('*', e).mousedown(fb.mousedown);
		
		    // Init color
		  fb.setColor('#000000');
		
		  // Set linked elements/callback
		  if (callback) {
		    fb.linkTo(callback);
		  }
		}





	
		/* 
		 * colorPicker
		 * 
		 * Associates a popup timepicker with a input field.
		 * 
		 */
		var popupColorPicker;
		var popupColorPickerTarget;
		var popupColorPickerTargetInput;
		
		var bDisableNone;
		var bDisableWheel;
		var bUsePallete;
		
		var selectColor = function () { // Select color
			if (!$(this).hasClass('none')) {
				var selColor = $(this).attr('id').substr(6);
				popupColorPickerTarget.find('span').removeClass('none');
				popupColorPickerTarget.find('span').css('background-color', selColor);
				popupColorPickerTargetInput.val(selColor);
				colorPickerWheel.setColor(selColor);
			} else {
				popupColorPickerTarget.find('span').css('background-color', '');
				$(popupColorPickerTarget.find('span').get(0)).addClass('none');
				popupColorPickerTargetInput.val('');
				colorPickerWheel.setColor('');
			}
			closeLastFormLayerElement();
		}
		
		var overColor = function () { $(this).addClass('hover'); }
		
		var outColor = function () { $(this).removeClass('hover'); }
		
		var initColorPicker = function () {		
			popupColorPickerTarget = $(this);

			popupColorPickerTargetInput = $(popupColorPickerTarget.find('input').get(0));
			var curColor = popupColorPickerTargetInput.val(); // Retrieve current value
			colorPickerWheel.setColor(curColor);

			bDisableNone = popupColorPickerTargetInput.hasClass('disableNone'); // Retrieve current value
			bDisableWheel =  popupColorPickerTargetInput.hasClass('disableWheel'); // Retrieve current value
			bUsePallete = popupColorPickerTargetInput.attr('class').indexOf('pallete-') > -1;	

			if (bUsePallete) {
				popupColorPicker.find('#colorPickerPallete').show();	
				popupColorPicker.find('#colorPickerWheelFrame').hide();
				popupColorPicker.find('#colorPickerWheelFrame a').show();
				
				var innerValues = '';
	
				if (!bDisableNone) {
					innerValues += '<div id="color-none" class="colorCell none '+ (curColor == '' ? ' sel' : '') + '"><span></span></div>';
					popupColorPicker.find('#colorPickerWheelFrame .none').show();	
				} else {
					popupColorPicker.find('#colorPickerWheelFrame .none').hide();
				}

				var addClass = '';
				for (var i = 0; i < DefinedPalletes.length; i++) {
					if (popupColorPickerTargetInput.hasClass('pallete-' + DefinedPalletes[i][0])) {
						for (var c = 0; c < DefinedPalletes[i][1].length; c++) {					
							if (curColor == DefinedPalletes[i][1][c]) addClass = 'sel';
							else addClass = '';
							innerValues += '<div id="color-' + DefinedPalletes[i][1][c] + '" class="colorCell ' + addClass + '"><span style="background-color:'+ DefinedPalletes[i][1][c] + '"></span></div>';
							if (((c + 1 + (bDisableNone ? 0 : 1)) % DefinedPalletes[i][2] == 0)) {
								innerValues += '<br />';
							}
						}
					}
				}
				if (!bDisableWheel) innerValues += '<div class="panel"><a href=""> </a></div>';			
				popupColorPicker.find('#colorPickerPallete').html(innerValues);
				popupColorPicker.find('div.colorCell').click( selectColor ).mouseover( overColor ).mouseout( outColor );
				popupColorPicker.find('#colorPickerPallete a').click( function () {
					popupColorPicker.find('#colorPickerPallete').hide();
					popupColorPicker.find('#colorPickerWheelFrame').show();	
					return false;
				} );
			} else {
				popupColorPicker.find('#colorPickerWheelFrame').show();
				popupColorPicker.find('#colorPickerPallete').hide();	
				popupColorPicker.find('#colorPickerWheelFrame a').hide();
			}			
			popupColorPicker.makeForm(popupColorPickerTarget);		
		}
		
		// Insert timePicker into DOM
		var popupColorPicker = $(document.createElement('div'));
		popupColorPicker.attr('id', 'colorPicker');
		popupColorPicker.addClass('select-free');
		popupColorPicker.hide();
		popupColorPicker.html('<div class="inner"><div id="colorPickerWheelFrame"><div id="colorPickerWheel"></div><div id="colorPickerCloser">&times;</div><div class="panel">' +
			'<a href=""> </a><div class="colorCell none"><span></span></div>' +
			'</div></div>  <div id="colorPickerPallete"></div>   </div><!--[if lte IE 6.5]><iframe></iframe><![endif]-->');
		$('body').append(popupColorPicker);
		popupColorPicker.hide();
	
		popupColorPicker.find('#colorPickerCloser').click( closeLastFormLayerElement );
		popupColorPicker.find('#colorPickerWheelFrame .none').click( selectColor ).mouseover( overColor ).mouseout( outColor );

		popupColorPicker.find('#colorPickerWheelFrame a').click( function () {
			popupColorPicker.find('#colorPickerWheelFrame').hide();	
			popupColorPicker.find('#colorPickerPallete').show();
			return false;
		} );
		
		// Initialize wheel
		var colorPickerWheel = $.farbtastic(popupColorPicker.find('#colorPickerWheel'), function () {
			popupColorPickerTarget.find('span').removeClass('none');
			popupColorPickerTarget.find('span').css('background-color', this.color);
			popupColorPickerTargetInput.val(this.color);
			colorPickerWheel.setColor(this.color);
		});
		
		// Associate colorPicker with marked input fields
		jsFormsElements.find(':text.colorPicker').each(function () {
			var oDiv = $(document.createElement('span'));
			oDiv.addClass('colorPickerInput')
				.html('<span></span>')
				.insertBefore($(this))
				.append($(this));
			// Inherit value to new field
			var curColor= $(this).val(); // Retrieve current value
			if (curColor != '') oDiv.find('span').css('background-color', curColor);
			else oDiv.find('span').addClass('none');
			oDiv.click(initColorPicker);
		});






	}
}





/* Dynamic forms */
$(function(){

	// When field contains an error note, add class to parent tr
	$("form table.layouter td .error").parents("tr").addClass("error");

	function getDynamicFormpattern(elem) {
		var handle = elem.attr("id");
		
	
		var patternField = $(".patternField.for-"+handle);
		if (patternField.length == 0) {	// Create pattern line if not available
			var existingLine = $(".fieldLine.for-"+handle).eq(0);
			patternField = existingLine.clone(true);
			patternField.find("input").val(''); // Clear input boxes
			patternField.find("input, select, textarea, button").each(function(){
				// Delete number form field
				var fieldName = $(this).attr("name");
				fieldName = fieldName.substring(0, $(this).attr("name").lastIndexOf('_'));
				$(this).attr("name", fieldName).attr("id", fieldName);
			});
			patternField.find("label").each(function(){
				// Delete number form field
				var fieldName = $(this).attr("for");
				fieldName = fieldName.substring(0, $(this).attr("for").lastIndexOf('_'));
				$(this).attr("for", fieldName);
			});
			patternField.addClass('patternField for-'+handle).hide().insertBefore(existingLine);
			
			// remove patternField when submitting form
			elem.parents("form").submit(function(){
				$(this).find(".patternField").remove();
			});
		}
		
		return patternField;
	}
	
	$(".dynamicFormDelete").attachSafeClick( function () {
		// Check that pattern exists	
		var fieldLine = $(this).parents('.fieldLine').eq(0);
		getDynamicFormpattern($("#"+fieldLine.getClassParam('for')));
		fieldLine.remove();
	}).addHoverAbility();

	$(".dynamicFormAdd").attachSafeClick( function () {
		
		// Look fot pattern
		var patternField = getDynamicFormpattern($(this));
				
		var newField = patternField.clone(true).addClass("fieldLine");	
		newField.removeClass('patternField'); // Is not pattern any more
		
		// Adding indexes to fields
			// Find free index
			var fieldName = patternField.find("input, select, textarea, button").eq(0);
			fieldName = fieldName.attr("name");
			var newIndex = 0;
			while (patternField.siblings('.fieldLine').find("[name='"+fieldName+"_"+newIndex+"']").length > 0) newIndex++;

			// Rename fields in new line
			newField.find("input, select, textarea, button").each(function(){
				var fieldName = $(this).attr("name");
				$(this).attr("name", fieldName+"_"+newIndex).attr("id", fieldName+"_"+newIndex);
			});
			newField.find("label").each(function(){
				var fieldName = $(this).attr("for");
				$(this).attr("for", fieldName+"_"+newIndex);
			});
			
		newField.appendTo(patternField.parent()).show();

		return false;
	}).addHoverAbility();

});


