/**
 *
 * Date picker
 * Author: Stefan Petre www.eyecon.ro
 * 
 * Dual licensed under the MIT and GPL licenses
 * 
 */
(function ($) {
	var DatePicker = function () {
		var	ids = {},
			views = {
				years: 'datepickerViewYears',
				moths: 'datepickerViewMonths',
				days: 'datepickerViewDays'
			},
			tpl = {
				wrapper: '<div class="datepicker"><div class="datepickerBorderT" /><div class="datepickerBorderB" /><div class="datepickerBorderL" /><div class="datepickerBorderR" /><div class="datepickerBorderTL" /><div class="datepickerBorderTR" /><div class="datepickerBorderBL" /><div class="datepickerBorderBR" /><div class="datepickerContainer"><table cellspacing="0" cellpadding="0"><tbody><tr></tr></tbody></table></div></div>',
				head: [
					'<td>',
					'<table cellspacing="0" cellpadding="0">',
						'<thead>',
							'<tr>',
								'<th class="datepickerGoPrev"><a href="#"><span><%=prev%></span></a></th>',
								'<th colspan="6" class="datepickerMonth"><a href="#"><span></span></a></th>',
								'<th class="datepickerGoNext"><a href="#"><span><%=next%></span></a></th>',
							'</tr>',
							'<tr class="datepickerDoW">',
								'<th><span><%=week%></span></th>',
								'<th><span><%=day1%></span></th>',
								'<th><span><%=day2%></span></th>',
								'<th><span><%=day3%></span></th>',
								'<th><span><%=day4%></span></th>',
								'<th><span><%=day5%></span></th>',
								'<th><span><%=day6%></span></th>',
								'<th><span><%=day7%></span></th>',
							'</tr>',
						'</thead>',
					'</table></td>'
				],
				space : '<td class="datepickerSpace"><div></div></td>',
				days: [
					'<tbody class="datepickerDays">',
						'<tr>',
							'<th class="datepickerWeek"><a href="#"><span><%=weeks[0].week%></span></a></th>',
							'<td class="<%=weeks[0].days[0].classname%>"><a href="#"><span><%=weeks[0].days[0].text%></span></a></td>',
							'<td class="<%=weeks[0].days[1].classname%>"><a href="#"><span><%=weeks[0].days[1].text%></span></a></td>',
							'<td class="<%=weeks[0].days[2].classname%>"><a href="#"><span><%=weeks[0].days[2].text%></span></a></td>',
							'<td class="<%=weeks[0].days[3].classname%>"><a href="#"><span><%=weeks[0].days[3].text%></span></a></td>',
							'<td class="<%=weeks[0].days[4].classname%>"><a href="#"><span><%=weeks[0].days[4].text%></span></a></td>',
							'<td class="<%=weeks[0].days[5].classname%>"><a href="#"><span><%=weeks[0].days[5].text%></span></a></td>',
							'<td class="<%=weeks[0].days[6].classname%>"><a href="#"><span><%=weeks[0].days[6].text%></span></a></td>',
						'</tr>',
						'<tr>',
							'<th class="datepickerWeek"><a href="#"><span><%=weeks[1].week%></span></a></th>',
							'<td class="<%=weeks[1].days[0].classname%>"><a href="#"><span><%=weeks[1].days[0].text%></span></a></td>',
							'<td class="<%=weeks[1].days[1].classname%>"><a href="#"><span><%=weeks[1].days[1].text%></span></a></td>',
							'<td class="<%=weeks[1].days[2].classname%>"><a href="#"><span><%=weeks[1].days[2].text%></span></a></td>',
							'<td class="<%=weeks[1].days[3].classname%>"><a href="#"><span><%=weeks[1].days[3].text%></span></a></td>',
							'<td class="<%=weeks[1].days[4].classname%>"><a href="#"><span><%=weeks[1].days[4].text%></span></a></td>',
							'<td class="<%=weeks[1].days[5].classname%>"><a href="#"><span><%=weeks[1].days[5].text%></span></a></td>',
							'<td class="<%=weeks[1].days[6].classname%>"><a href="#"><span><%=weeks[1].days[6].text%></span></a></td>',
						'</tr>',
						'<tr>',
							'<th class="datepickerWeek"><a href="#"><span><%=weeks[2].week%></span></a></th>',
							'<td class="<%=weeks[2].days[0].classname%>"><a href="#"><span><%=weeks[2].days[0].text%></span></a></td>',
							'<td class="<%=weeks[2].days[1].classname%>"><a href="#"><span><%=weeks[2].days[1].text%></span></a></td>',
							'<td class="<%=weeks[2].days[2].classname%>"><a href="#"><span><%=weeks[2].days[2].text%></span></a></td>',
							'<td class="<%=weeks[2].days[3].classname%>"><a href="#"><span><%=weeks[2].days[3].text%></span></a></td>',
							'<td class="<%=weeks[2].days[4].classname%>"><a href="#"><span><%=weeks[2].days[4].text%></span></a></td>',
							'<td class="<%=weeks[2].days[5].classname%>"><a href="#"><span><%=weeks[2].days[5].text%></span></a></td>',
							'<td class="<%=weeks[2].days[6].classname%>"><a href="#"><span><%=weeks[2].days[6].text%></span></a></td>',
						'</tr>',
						'<tr>',
							'<th class="datepickerWeek"><a href="#"><span><%=weeks[3].week%></span></a></th>',
							'<td class="<%=weeks[3].days[0].classname%>"><a href="#"><span><%=weeks[3].days[0].text%></span></a></td>',
							'<td class="<%=weeks[3].days[1].classname%>"><a href="#"><span><%=weeks[3].days[1].text%></span></a></td>',
							'<td class="<%=weeks[3].days[2].classname%>"><a href="#"><span><%=weeks[3].days[2].text%></span></a></td>',
							'<td class="<%=weeks[3].days[3].classname%>"><a href="#"><span><%=weeks[3].days[3].text%></span></a></td>',
							'<td class="<%=weeks[3].days[4].classname%>"><a href="#"><span><%=weeks[3].days[4].text%></span></a></td>',
							'<td class="<%=weeks[3].days[5].classname%>"><a href="#"><span><%=weeks[3].days[5].text%></span></a></td>',
							'<td class="<%=weeks[3].days[6].classname%>"><a href="#"><span><%=weeks[3].days[6].text%></span></a></td>',
						'</tr>',
						'<tr>',
							'<th class="datepickerWeek"><a href="#"><span><%=weeks[4].week%></span></a></th>',
							'<td class="<%=weeks[4].days[0].classname%>"><a href="#"><span><%=weeks[4].days[0].text%></span></a></td>',
							'<td class="<%=weeks[4].days[1].classname%>"><a href="#"><span><%=weeks[4].days[1].text%></span></a></td>',
							'<td class="<%=weeks[4].days[2].classname%>"><a href="#"><span><%=weeks[4].days[2].text%></span></a></td>',
							'<td class="<%=weeks[4].days[3].classname%>"><a href="#"><span><%=weeks[4].days[3].text%></span></a></td>',
							'<td class="<%=weeks[4].days[4].classname%>"><a href="#"><span><%=weeks[4].days[4].text%></span></a></td>',
							'<td class="<%=weeks[4].days[5].classname%>"><a href="#"><span><%=weeks[4].days[5].text%></span></a></td>',
							'<td class="<%=weeks[4].days[6].classname%>"><a href="#"><span><%=weeks[4].days[6].text%></span></a></td>',
						'</tr>',
						'<tr>',
							'<th class="datepickerWeek"><a href="#"><span><%=weeks[5].week%></span></a></th>',
							'<td class="<%=weeks[5].days[0].classname%>"><a href="#"><span><%=weeks[5].days[0].text%></span></a></td>',
							'<td class="<%=weeks[5].days[1].classname%>"><a href="#"><span><%=weeks[5].days[1].text%></span></a></td>',
							'<td class="<%=weeks[5].days[2].classname%>"><a href="#"><span><%=weeks[5].days[2].text%></span></a></td>',
							'<td class="<%=weeks[5].days[3].classname%>"><a href="#"><span><%=weeks[5].days[3].text%></span></a></td>',
							'<td class="<%=weeks[5].days[4].classname%>"><a href="#"><span><%=weeks[5].days[4].text%></span></a></td>',
							'<td class="<%=weeks[5].days[5].classname%>"><a href="#"><span><%=weeks[5].days[5].text%></span></a></td>',
							'<td class="<%=weeks[5].days[6].classname%>"><a href="#"><span><%=weeks[5].days[6].text%></span></a></td>',
						'</tr>',
					'</tbody>'
				],
				months: [
					'<tbody class="<%=className%>">',
						'<tr>',
							'<td colspan="2"><a href="#"><span><%=data[0]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[1]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[2]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[3]%></span></a></td>',
						'</tr>',
						'<tr>',
							'<td colspan="2"><a href="#"><span><%=data[4]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[5]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[6]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[7]%></span></a></td>',
						'</tr>',
						'<tr>',
							'<td colspan="2"><a href="#"><span><%=data[8]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[9]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[10]%></span></a></td>',
							'<td colspan="2"><a href="#"><span><%=data[11]%></span></a></td>',
						'</tr>',
					'</tbody>'
				]
			},
			defaults = {
				flat: false,
				starts: 1,
				prev: '&#9664;',
				next: '&#9654;',
				lastSel: false,
				mode: 'single',
				view: 'days',
				calendars: 1,
				format: 'Y-m-d',
				position: 'bottom',
				eventName: 'click',
				onRender: function(){return {};},
				onChange: function(){return true;},
				onShow: function(){return true;},
				onBeforeShow: function(){return true;},
				onHide: function(){return true;},
				locale: {
					days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],
					daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
					daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"],
					months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
					monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
					weekMin: 't'
				}
			},
			fill = function(el) {
				var options = $(el).data('datepicker');
				var cal = $(el);
				var currentCal = Math.floor(options.calendars/2), date, data, dow, month, cnt = 0, week, days, indic, indic2, html, tblCal;
				cal.find('td>table tbody').remove();
				for (var i = 0; i < options.calendars; i++) {
					date = new Date(options.current);
					date.addMonths(-currentCal + i);
					tblCal = cal.find('table').eq(i+1);
					switch (tblCal[0].className) {
						case 'datepickerViewDays':
							dow = formatDate(date, 'B, Y');
							break;
						case 'datepickerViewMonths':
							dow = date.getFullYear();
							break;
						case 'datepickerViewYears':
							dow = (date.getFullYear()-6) + ' - ' + (date.getFullYear()+5);
							break;
					} 
					tblCal.find('thead tr:first th:eq(1) span').text(dow);
					dow = date.getFullYear()-6;
					data = {
						data: [],
						className: 'datepickerYears'
					}
					for ( var j = 0; j < 12; j++) {
						data.data.push(dow + j);
					}
					html = tmpl(tpl.months.join(''), data);
					date.setDate(1);
					data = {weeks:[], test: 10};
					month = date.getMonth();
					var dow = (date.getDay() - options.starts) % 7;
					date.addDays(-(dow + (dow < 0 ? 7 : 0)));
					week = -1;
					cnt = 0;
					while (cnt < 42) {
						indic = parseInt(cnt/7,10);
						indic2 = cnt%7;
						if (!data.weeks[indic]) {
							week = date.getWeekNumber();
							data.weeks[indic] = {
								week: week,
								days: []
							};
						}
						data.weeks[indic].days[indic2] = {
							text: date.getDate(),
							classname: []
						};
						if (month != date.getMonth()) {
							data.weeks[indic].days[indic2].classname.push('datepickerNotInMonth');
						}
						if (date.getDay() == 0) {
							data.weeks[indic].days[indic2].classname.push('datepickerSunday');
						}
						if (date.getDay() == 6) {
							data.weeks[indic].days[indic2].classname.push('datepickerSaturday');
						}
						var fromUser = options.onRender(date);
						var val = date.valueOf();
						if (fromUser.selected || options.date == val || $.inArray(val, options.date) > -1 || (options.mode == 'range' && val >= options.date[0] && val <= options.date[1])) {
							data.weeks[indic].days[indic2].classname.push('datepickerSelected');
						}
						if (fromUser.disabled) {
							data.weeks[indic].days[indic2].classname.push('datepickerDisabled');
						}
						if (fromUser.className) {
							data.weeks[indic].days[indic2].classname.push(fromUser.className);
						}
						data.weeks[indic].days[indic2].classname = data.weeks[indic].days[indic2].classname.join(' ');
						cnt++;
						date.addDays(1);
					}
					html = tmpl(tpl.days.join(''), data) + html;
					data = {
						data: options.locale.monthsShort,
						className: 'datepickerMonths'
					};
					html = tmpl(tpl.months.join(''), data) + html;
					tblCal.append(html);
				}
			},
			parseDate = function (date, format) {
				if (date.constructor == Date) {
					return new Date(date);
				}
				var parts = date.split(/\W+/);
				var against = format.split(/\W+/), d, m, y, h, min, now = new Date();
				for (var i = 0; i < parts.length; i++) {
					switch (against[i]) {
						case 'd':
						case 'e':
							d = parseInt(parts[i],10);
							break;
						case 'm':
							m = parseInt(parts[i], 10)-1;
							break;
						case 'Y':
						case 'y':
							y = parseInt(parts[i], 10);
							y += y > 100 ? 0 : (y < 29 ? 2000 : 1900);
							break;
						case 'H':
						case 'I':
						case 'k':
						case 'l':
							h = parseInt(parts[i], 10);
							break;
						case 'P':
						case 'p':
							if (/pm/i.test(parts[i]) && h < 12) {
								h += 12;
							} else if (/am/i.test(parts[i]) && h >= 12) {
								h -= 12;
							}
							break;
						case 'M':
							min = parseInt(parts[i], 10);
							break;
					}
				}
				return new Date(
					y === undefined ? now.getFullYear() : y,
					m === undefined ? now.getMonth() : m,
					d === undefined ? now.getDate() : d,
					h === undefined ? now.getHours() : h,
					min === undefined ? now.getMinutes() : min,
					0
				);
			},
			formatDate = function(date, format) {
				var m = date.getMonth();
				var d = date.getDate();
				var y = date.getFullYear();
				var wn = date.getWeekNumber();
				var w = date.getDay();
				var s = {};
				var hr = date.getHours();
				var pm = (hr >= 12);
				var ir = (pm) ? (hr - 12) : hr;
				var dy = date.getDayOfYear();
				if (ir == 0) {
					ir = 12;
				}
				var min = date.getMinutes();
				var sec = date.getSeconds();
				var parts = format.split(''), part;
				for ( var i = 0; i < parts.length; i++ ) {
					part = parts[i];
					switch (parts[i]) {
						case 'a':
							part = date.getDayName();
							break;
						case 'A':
							part = date.getDayName(true);
							break;
						case 'b':
							part = date.getMonthName();
							break;
						case 'B':
							part = date.getMonthName(true);
							break;
						case 'C':
							part = 1 + Math.floor(y / 100);
							break;
						case 'd':
							part = (d < 10) ? ("0" + d) : d;
							break;
						case 'e':
							part = d;
							break;
						case 'H':
							part = (hr < 10) ? ("0" + hr) : hr;
							break;
						case 'I':
							part = (ir < 10) ? ("0" + ir) : ir;
							break;
						case 'j':
							part = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy;
							break;
						case 'k':
							part = hr;
							break;
						case 'l':
							part = ir;
							break;
						case 'm':
							part = (m < 9) ? ("0" + (1+m)) : (1+m);
							break;
						case 'M':
							part = (min < 10) ? ("0" + min) : min;
							break;
						case 'p':
						case 'P':
							part = pm ? "PM" : "AM";
							break;
						case 's':
							part = Math.floor(date.getTime() / 1000);
							break;
						case 'S':
							part = (sec < 10) ? ("0" + sec) : sec;
							break;
						case 'u':
							part = w + 1;
							break;
						case 'w':
							part = w;
							break;
						case 'y':
							part = ('' + y).substr(2, 2);
							break;
						case 'Y':
							part = y;
							break;
					}
					parts[i] = part;
				}
				return parts.join('');
			},
			extendDate = function(options) {
				if (Date.prototype.tempDate) {
					return;
				}
				Date.prototype.tempDate = null;
				Date.prototype.months = options.months;
				Date.prototype.monthsShort = options.monthsShort;
				Date.prototype.days = options.days;
				Date.prototype.daysShort = options.daysShort;
				Date.prototype.getMonthName = function(fullName) {
					return this[fullName ? 'months' : 'monthsShort'][this.getMonth()];
				};
				Date.prototype.getDayName = function(fullName) {
					return this[fullName ? 'days' : 'daysShort'][this.getDay()];
				};
				Date.prototype.addDays = function (n) {
					this.setDate(this.getDate() + n);
					this.tempDate = this.getDate();
				};
				Date.prototype.addMonths = function (n) {
					if (this.tempDate == null) {
						this.tempDate = this.getDate();
					}
					this.setDate(1);
					this.setMonth(this.getMonth() + n);
					this.setDate(Math.min(this.tempDate, this.getMaxDays()));
				};
				Date.prototype.addYears = function (n) {
					if (this.tempDate == null) {
						this.tempDate = this.getDate();
					}
					this.setDate(1);
					this.setFullYear(this.getFullYear() + n);
					this.setDate(Math.min(this.tempDate, this.getMaxDays()));
				};
				Date.prototype.getMaxDays = function() {
					var tmpDate = new Date(Date.parse(this)),
						d = 28, m;
					m = tmpDate.getMonth();
					d = 28;
					while (tmpDate.getMonth() == m) {
						d ++;
						tmpDate.setDate(d);
					}
					return d - 1;
				};
				Date.prototype.getFirstDay = function() {
					var tmpDate = new Date(Date.parse(this));
					tmpDate.setDate(1);
					return tmpDate.getDay();
				};
				Date.prototype.getWeekNumber = function() {
					var tempDate = new Date(this);
					tempDate.setDate(tempDate.getDate() - (tempDate.getDay() + 6) % 7 + 3);
					var dms = tempDate.valueOf();
					tempDate.setMonth(0);
					tempDate.setDate(4);
					return Math.round((dms - tempDate.valueOf()) / (604800000)) + 1;
				};
				Date.prototype.getDayOfYear = function() {
					var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
					var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
					var time = now - then;
					return Math.floor(time / 24*60*60*1000);
				};
			},
			layout = function (el) {
				var options = $(el).data('datepicker');
				var cal = $('#' + options.id);
				if (!options.extraHeight) {
					var divs = $(el).find('div');
					options.extraHeight = divs.get(0).offsetHeight + divs.get(1).offsetHeight;
					options.extraWidth = divs.get(2).offsetWidth + divs.get(3).offsetWidth;
				}
				var tbl = cal.find('table:first').get(0);
				var width = tbl.offsetWidth;
				var height = tbl.offsetHeight;
				cal.css({
					width: width + options.extraWidth + 'px',
					height: height + options.extraHeight + 'px'
				}).find('div.datepickerContainer').css({
					width: width + 'px',
					height: height + 'px'
				});
			},
			click = function(ev) {
				if ($(ev.target).is('span')) {
					ev.target = ev.target.parentNode;
				}
				var el = $(ev.target);
				if (el.is('a')) {
					ev.target.blur();
					if (el.hasClass('datepickerDisabled')) {
						return false;
					}
					var options = $(this).data('datepicker');
					var parentEl = el.parent();
					var tblEl = parentEl.parent().parent().parent();
					var tblIndex = $('table', this).index(tblEl.get(0)) - 1;
					var tmp = new Date(options.current);
					var changed = false;
					var fillIt = false;
					if (parentEl.is('th')) {
						if (parentEl.hasClass('datepickerWeek') && options.mode == 'range' && !parentEl.next().hasClass('datepickerDisabled')) {
							var val = parseInt(parentEl.next().text(), 10);
							tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
							if (parentEl.next().hasClass('datepickerNotInMonth')) {
								tmp.addMonths(val > 15 ? -1 : 1);
							}
							tmp.setDate(val);
							options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();
							tmp.setHours(23,59,59,0);
							tmp.addDays(6);
							options.date[1] = tmp.valueOf();
							fillIt = true;
							changed = true;
							options.lastSel = false;
						} else if (parentEl.hasClass('datepickerMonth')) {
							tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
							switch (tblEl.get(0).className) {
								case 'datepickerViewDays':
									tblEl.get(0).className = 'datepickerViewMonths';
									el.find('span').text(tmp.getFullYear());
									break;
								case 'datepickerViewMonths':
									tblEl.get(0).className = 'datepickerViewYears';
									el.find('span').text((tmp.getFullYear()-6) + ' - ' + (tmp.getFullYear()+5));
									break;
								case 'datepickerViewYears':
									tblEl.get(0).className = 'datepickerViewDays';
									el.find('span').text(formatDate(tmp, 'B, Y'));
									break;
							}
						} else if (parentEl.parent().parent().is('thead')) {
							switch (tblEl.get(0).className) {
								case 'datepickerViewDays':
									options.current.addMonths(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);
									break;
								case 'datepickerViewMonths':
									options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -1 : 1);
									break;
								case 'datepickerViewYears':
									options.current.addYears(parentEl.hasClass('datepickerGoPrev') ? -12 : 12);
									break;
							}
							fillIt = true;
						}
					} else if (parentEl.is('td') && !parentEl.hasClass('datepickerDisabled')) {
						switch (tblEl.get(0).className) {
							case 'datepickerViewMonths':
								options.current.setMonth(tblEl.find('tbody.datepickerMonths td').index(parentEl));
								options.current.setFullYear(parseInt(tblEl.find('thead th.datepickerMonth span').text(), 10));
								options.current.addMonths(Math.floor(options.calendars/2) - tblIndex);
								tblEl.get(0).className = 'datepickerViewDays';
								break;
							case 'datepickerViewYears':
								options.current.setFullYear(parseInt(el.text(), 10));
								tblEl.get(0).className = 'datepickerViewMonths';
								break;
							default:
								var val = parseInt(el.text(), 10);
								tmp.addMonths(tblIndex - Math.floor(options.calendars/2));
								if (parentEl.hasClass('datepickerNotInMonth')) {
									tmp.addMonths(val > 15 ? -1 : 1);
								}
								tmp.setDate(val);
								switch (options.mode) {
									case 'multiple':
										val = (tmp.setHours(0,0,0,0)).valueOf();
										if ($.inArray(val, options.date) > -1) {
											$.each(options.date, function(nr, dat){
												if (dat == val) {
													options.date.splice(nr,1);
													return false;
												}
											});
										} else {
											options.date.push(val);
										}
										break;
									case 'range':
										if (!options.lastSel) {
											options.date[0] = (tmp.setHours(0,0,0,0)).valueOf();
										}
										val = (tmp.setHours(23,59,59,0)).valueOf();
										if (val < options.date[0]) {
											options.date[1] = options.date[0] + 86399000;
											options.date[0] = val - 86399000;
										} else {
											options.date[1] = val;
										}
										options.lastSel = !options.lastSel;
										break;
									default:
										options.date = tmp.valueOf();
										break;
								}
								break;
						}
						fillIt = true;
						changed = true;
					}
					if (fillIt) {
						fill(this);
					}
					if (changed) {
						options.onChange.apply(this, prepareDate(options));
					}
				}
				return false;
			},
			prepareDate = function (options) {
				var tmp;
				if (options.mode == 'single') {
					tmp = new Date(options.date);
					return [formatDate(tmp, options.format), tmp, options.el];
				} else {
					tmp = [[],[], options.el];
					$.each(options.date, function(nr, val){
						var date = new Date(val);
						tmp[0].push(formatDate(date, options.format));
						tmp[1].push(date);
					});
					return tmp;
				}
			},
			getViewport = function () {
				var m = document.compatMode == 'CSS1Compat';
				return {
					l : window.pageXOffset || (m ? document.documentElement.scrollLeft : document.body.scrollLeft),
					t : window.pageYOffset || (m ? document.documentElement.scrollTop : document.body.scrollTop),
					w : window.innerWidth || (m ? document.documentElement.clientWidth : document.body.clientWidth),
					h : window.innerHeight || (m ? document.documentElement.clientHeight : document.body.clientHeight)
				};
			},
			isChildOf = function(parentEl, el, container) {
				if (parentEl == el) {
					return true;
				}
				if (parentEl.contains) {
					return parentEl.contains(el);
				}
				if ( parentEl.compareDocumentPosition ) {
					return !!(parentEl.compareDocumentPosition(el) & 16);
				}
				var prEl = el.parentNode;
				while(prEl && prEl != container) {
					if (prEl == parentEl)
						return true;
					prEl = prEl.parentNode;
				}
				return false;
			},
			show = function (ev) {
				var cal = $('#' + $(this).data('datepickerId'));
				if (!cal.is(':visible')) {
					var calEl = cal.get(0);
					fill(calEl);
					var options = cal.data('datepicker');
					options.onBeforeShow.apply(this, [cal.get(0)]);
					var pos = $(this).offset();
					var viewPort = getViewport();
					var top = pos.top;
					var left = pos.left;
					var oldDisplay = $.curCSS(calEl, 'display');
					cal.css({
						visibility: 'hidden',
						display: 'block'
					});
					layout(calEl);
					switch (options.position){
						case 'top':
							top -= calEl.offsetHeight;
							break;
						case 'left':
							left -= calEl.offsetWidth;
							break;
						case 'right':
							left += this.offsetWidth;
							break;
						case 'bottom':
							top += this.offsetHeight;
							break;
					}
					if (top + calEl.offsetHeight > viewPort.t + viewPort.h) {
						top = pos.top  - calEl.offsetHeight;
					}
					if (top < viewPort.t) {
						top = pos.top + this.offsetHeight + calEl.offsetHeight;
					}
					if (left + calEl.offsetWidth > viewPort.l + viewPort.w) {
						left = pos.left - calEl.offsetWidth;
					}
					if (left < viewPort.l) {
						left = pos.left + this.offsetWidth
					}
					cal.css({
						visibility: 'visible',
						display: 'block',
						top: top + 'px',
						left: left + 'px'
					});
					if (options.onShow.apply(this, [cal.get(0)]) != false) {
						cal.show();
					}
					$(document).bind('mousedown', {cal: cal, trigger: this}, hide);
				}
				return false;
			},
			hide = function (ev) {
				if (ev.target != ev.data.trigger && !isChildOf(ev.data.cal.get(0), ev.target, ev.data.cal.get(0))) {
					if (ev.data.cal.data('datepicker').onHide.apply(this, [ev.data.cal.get(0)]) != false) {
						ev.data.cal.hide();
					}
					$(document).unbind('mousedown', hide);
				}
			};
		return {
			init: function(options){
				options = $.extend({}, defaults, options||{});
				extendDate(options.locale);
				options.calendars = Math.max(1, parseInt(options.calendars,10)||1);
				options.mode = /single|multiple|range/.test(options.mode) ? options.mode : 'single';
				return this.each(function(){
					if (!$(this).data('datepicker')) {
						options.el = this;
						if (options.date.constructor == String) {
							options.date = parseDate(options.date, options.format);
							options.date.setHours(0,0,0,0);
						}
						if (options.mode != 'single') {
							if (options.date.constructor != Array) {
								options.date = [options.date.valueOf()];
								if (options.mode == 'range') {
									options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());
								}
							} else {
								for (var i = 0; i < options.date.length; i++) {
									options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();
								}
								if (options.mode == 'range') {
									options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();
								}
							}
						} else {
							options.date = options.date.valueOf();
						}
						if (!options.current) {
							options.current = new Date();
						} else {
							options.current = parseDate(options.current, options.format);
						} 
						options.current.setDate(1);
						options.current.setHours(0,0,0,0);
						var id = 'datepicker_' + parseInt(Math.random() * 1000), cnt;
						options.id = id;
						$(this).data('datepickerId', options.id);
						var cal = $(tpl.wrapper).attr('id', id).bind('click', click).data('datepicker', options);
						if (options.className) {
							cal.addClass(options.className);
						}
						var html = '';
						for (var i = 0; i < options.calendars; i++) {
							cnt = options.starts;
							if (i > 0) {
								html += tpl.space;
							}
							html += tmpl(tpl.head.join(''), {
									week: options.locale.weekMin,
									prev: options.prev,
									next: options.next,
									day1: options.locale.daysMin[(cnt++)%7],
									day2: options.locale.daysMin[(cnt++)%7],
									day3: options.locale.daysMin[(cnt++)%7],
									day4: options.locale.daysMin[(cnt++)%7],
									day5: options.locale.daysMin[(cnt++)%7],
									day6: options.locale.daysMin[(cnt++)%7],
									day7: options.locale.daysMin[(cnt++)%7]
								});
						}
						cal
							.find('tr:first').append(html)
								.find('table').addClass(views[options.view]);
						fill(cal.get(0));
						if (options.flat) {
							cal.appendTo(this).show().css('position', 'relative');
							layout(cal.get(0));
						} else {
							cal.appendTo(document.body);
							$(this).bind(options.eventName, show);
						}
					}
				});
			},
			showPicker: function() {
				return this.each( function () {
					if ($(this).data('datepickerId')) {
						show.apply(this);
					}
				});
			},
			hidePicker: function() {
				return this.each( function () {
					if ($(this).data('datepickerId')) {
						$('#' + $(this).data('datepickerId')).hide();
					}
				});
			},
			setDate: function(date, shiftTo){
				return this.each(function(){
					if ($(this).data('datepickerId')) {
						var cal = $('#' + $(this).data('datepickerId'));
						var options = cal.data('datepicker');
						options.date = date;
						if (options.date.constructor == String) {
							options.date = parseDate(options.date, options.format);
							options.date.setHours(0,0,0,0);
						}
						if (options.mode != 'single') {
							if (options.date.constructor != Array) {
								options.date = [options.date.valueOf()];
								if (options.mode == 'range') {
									options.date.push(((new Date(options.date[0])).setHours(23,59,59,0)).valueOf());
								}
							} else {
								for (var i = 0; i < options.date.length; i++) {
									options.date[i] = (parseDate(options.date[i], options.format).setHours(0,0,0,0)).valueOf();
								}
								if (options.mode == 'range') {
									options.date[1] = ((new Date(options.date[1])).setHours(23,59,59,0)).valueOf();
								}
							}
						} else {
							options.date = options.date.valueOf();
						}
						if (shiftTo) {
							options.current = new Date (options.mode != 'single' ? options.date[0] : options.date);
						}
						fill(cal.get(0));
					}
				});
			},
			getDate: function(formated) {
				if (this.size() > 0) {
					return prepareDate($('#' + $(this).data('datepickerId')).data('datepicker'))[formated ? 0 : 1];
				}
			},
			clear: function(){
				return this.each(function(){
					if ($(this).data('datepickerId')) {
						var cal = $('#' + $(this).data('datepickerId'));
						var options = cal.data('datepicker');
						if (options.mode != 'single') {
							options.date = [];
							fill(cal.get(0));
						}
					}
				});
			},
			fixLayout: function(){
				return this.each(function(){
					if ($(this).data('datepickerId')) {
						var cal = $('#' + $(this).data('datepickerId'));
						var options = cal.data('datepicker');
						if (options.flat) {
							layout(cal.get(0));
						}
					}
				});
			}
		};
	}();
	$.fn.extend({
		DatePicker: DatePicker.init,
		DatePickerHide: DatePicker.hidePicker,
		DatePickerShow: DatePicker.showPicker,
		DatePickerSetDate: DatePicker.setDate,
		DatePickerGetDate: DatePicker.getDate,
		DatePickerClear: DatePicker.clear,
		DatePickerLayout: DatePicker.fixLayout
	});
})(jQuery);

(function(){
  var cache = {};
 
  this.tmpl = function tmpl(str, data){
    // Figure out if we're getting a template, or if we need to
    // load the template - and be sure to cache the result.
    var fn = !/\W/.test(str) ?
      cache[str] = cache[str] ||
        tmpl(document.getElementById(str).innerHTML) :
     
      // Generate a reusable function that will serve as a template
      // generator (and which will be cached).
      new Function("obj",
        "var p=[],print=function(){p.push.apply(p,arguments);};" +
       
        // Introduce the data as local variables using with(){}
        "with(obj){p.push('" +
       
        // Convert the template into pure JavaScript
        str
          .replace(/[\r\t\n]/g, " ")
          .split("<%").join("\t")
          .replace(/((^|%>)[^\t]*)'/g, "$1\r")
          .replace(/\t=(.*?)%>/g, "',$1,'")
          .split("\t").join("');")
          .split("%>").join("p.push('")
          .split("\r").join("\\'")
      + "');}return p.join('');");
   
    // Provide some basic currying to the user
    return data ? fn( data ) : fn;
  };
})();;
/**
 * jQuery Validation Plugin 1.8.0
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
 * http://docs.jquery.com/Plugins/Validation
 *
 * Copyright (c) 2006 - 2011 Jörn Zaefferer
 *
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

(function($) {

$.extend($.fn, {
	// http://docs.jquery.com/Plugins/Validation/validate
	validate: function( options ) {

		// if nothing is selected, return nothing; can't chain anyway
		if (!this.length) {
			options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" );
			return;
		}

		// check if a validator for this form was already created
		var validator = $.data(this[0], 'validator');
		if ( validator ) {
			return validator;
		}

		validator = new $.validator( options, this[0] );
		$.data(this[0], 'validator', validator);

		if ( validator.settings.onsubmit ) {

			// allow suppresing validation by adding a cancel class to the submit button
			this.find("input, button").filter(".cancel").click(function() {
				validator.cancelSubmit = true;
			});

			// when a submitHandler is used, capture the submitting button
			if (validator.settings.submitHandler) {
				this.find("input, button").filter(":submit").click(function() {
					validator.submitButton = this;
				});
			}

			// validate the form on submit
			this.submit( function( event ) {
				if ( validator.settings.debug )
					// prevent form submit to be able to see console output
					event.preventDefault();

				function handle() {
					if ( validator.settings.submitHandler ) {
						if (validator.submitButton) {
							// insert a hidden input as a replacement for the missing submit button
							var hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);
						}
						validator.settings.submitHandler.call( validator, validator.currentForm );
						if (validator.submitButton) {
							// and clean up afterwards; thanks to no-block-scope, hidden can be referenced
							hidden.remove();
						}
						return false;
					}
					return true;
				}

				// prevent submit for invalid forms or custom submit handlers
				if ( validator.cancelSubmit ) {
					validator.cancelSubmit = false;
					return handle();
				}
				if ( validator.form() ) {
					if ( validator.pendingRequest ) {
						validator.formSubmitted = true;
						return false;
					}
					return handle();
				} else {
					validator.focusInvalid();
					return false;
				}
			});
		}

		return validator;
	},
	// http://docs.jquery.com/Plugins/Validation/valid
	valid: function() {
        if ( $(this[0]).is('form')) {
            return this.validate().form();
        } else {
            var valid = true;
            var validator = $(this[0].form).validate();
            this.each(function() {
				valid &= validator.element(this);
            });
            return valid;
        }
    },
	// attributes: space seperated list of attributes to retrieve and remove
	removeAttrs: function(attributes) {
		var result = {},
			$element = this;
		$.each(attributes.split(/\s/), function(index, value) {
			result[value] = $element.attr(value);
			$element.removeAttr(value);
		});
		return result;
	},
	// http://docs.jquery.com/Plugins/Validation/rules
	rules: function(command, argument) {
		var element = this[0];

		if (command) {
			var settings = $.data(element.form, 'validator').settings;
			var staticRules = settings.rules;
			var existingRules = $.validator.staticRules(element);
			switch(command) {
			case "add":
				$.extend(existingRules, $.validator.normalizeRule(argument));
				staticRules[element.name] = existingRules;
				if (argument.messages)
					settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
				break;
			case "remove":
				if (!argument) {
					delete staticRules[element.name];
					return existingRules;
				}
				var filtered = {};
				$.each(argument.split(/\s/), function(index, method) {
					filtered[method] = existingRules[method];
					delete existingRules[method];
				});
				return filtered;
			}
		}

		var data = $.validator.normalizeRules(
		$.extend(
			{},
			$.validator.metadataRules(element),
			$.validator.classRules(element),
			$.validator.attributeRules(element),
			$.validator.staticRules(element)
		), element);

		// make sure required is at front
		if (data.required) {
			var param = data.required;
			delete data.required;
			data = $.extend({required: param}, data);
		}

		return data;
	}
});

// Custom selectors
$.extend($.expr[":"], {
	// http://docs.jquery.com/Plugins/Validation/blank
	blank: function(a) {return !$.trim("" + a.value);},
	// http://docs.jquery.com/Plugins/Validation/filled
	filled: function(a) {return !!$.trim("" + a.value);},
	// http://docs.jquery.com/Plugins/Validation/unchecked
	unchecked: function(a) {return !a.checked;}
});

// constructor for validator
$.validator = function( options, form ) {
	this.settings = $.extend( true, {}, $.validator.defaults, options );
	this.currentForm = form;
	this.init();
};

$.validator.format = function(source, params) {
	if ( arguments.length == 1 )
		return function() {
			var args = $.makeArray(arguments);
			args.unshift(source);
			return $.validator.format.apply( this, args );
		};
	if ( arguments.length > 2 && params.constructor != Array  ) {
		params = $.makeArray(arguments).slice(1);
	}
	if ( params.constructor != Array ) {
		params = [ params ];
	}
	$.each(params, function(i, n) {
		source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
	});
	return source;
};

$.extend($.validator, {

	defaults: {
		messages: {},
		groups: {},
		rules: {},
		errorClass: "error",
		validClass: "valid",
		errorElement: "label",
		focusInvalid: true,
		errorContainer: $( [] ),
		errorLabelContainer: $( [] ),
		onsubmit: true,
		ignore: [],
		ignoreTitle: false,
		onfocusin: function(element) {
			this.lastActive = element;

			// hide error label and remove error class on focus if enabled
			if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
				this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
				this.addWrapper(this.errorsFor(element)).hide();
			}
		},
		onfocusout: function(element) {
			if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
				this.element(element);
			}
		},
		onkeyup: function(element) {
			if ( element.name in this.submitted || element == this.lastElement ) {
				this.element(element);
			}
		},
		onclick: function(element) {
			// click on selects, radiobuttons and checkboxes
			if ( element.name in this.submitted )
				this.element(element);
			// or option elements, check parent select in that case
			else if (element.parentNode.name in this.submitted)
				this.element(element.parentNode);
		},
		highlight: function( element, errorClass, validClass ) {
			$(element).addClass(errorClass).removeClass(validClass);
		},
		unhighlight: function( element, errorClass, validClass ) {
			$(element).removeClass(errorClass).addClass(validClass);
		}
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
	setDefaults: function(settings) {
		$.extend( $.validator.defaults, settings );
	},

	messages: {
		required: "This field is required.",
		remote: "Please fix this field.",
		email: "Please enter a valid email address.",
		url: "Please enter a valid URL.",
		date: "Please enter a valid date.",
		dateISO: "Please enter a valid date (ISO).",
		number: "Please enter a valid number.",
		digits: "Please enter only digits.",
		creditcard: "Please enter a valid credit card number.",
		equalTo: "Please enter the same value again.",
		accept: "Please enter a value with a valid extension.",
		maxlength: $.validator.format("Please enter no more than {0} characters."),
		minlength: $.validator.format("Please enter at least {0} characters."),
		rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
		range: $.validator.format("Please enter a value between {0} and {1}."),
		max: $.validator.format("Please enter a value less than or equal to {0}."),
		min: $.validator.format("Please enter a value greater than or equal to {0}.")
	},

	autoCreateRanges: false,

	prototype: {

		init: function() {
			this.labelContainer = $(this.settings.errorLabelContainer);
			this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
			this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
			this.submitted = {};
			this.valueCache = {};
			this.pendingRequest = 0;
			this.pending = {};
			this.invalid = {};
			this.reset();

			var groups = (this.groups = {});
			$.each(this.settings.groups, function(key, value) {
				$.each(value.split(/\s/), function(index, name) {
					groups[name] = key;
				});
			});
			var rules = this.settings.rules;
			$.each(rules, function(key, value) {
				rules[key] = $.validator.normalizeRule(value);
			});

			function delegate(event) {
				var validator = $.data(this[0].form, "validator"),
					eventType = "on" + event.type.replace(/^validate/, "");
				validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] );
			}
			$(this.currentForm)
				.validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate)
				.validateDelegate(":radio, :checkbox, select, option", "click", delegate);

			if (this.settings.invalidHandler)
				$(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/form
		form: function() {
			this.checkForm();
			$.extend(this.submitted, this.errorMap);
			this.invalid = $.extend({}, this.errorMap);
			if (!this.valid())
				$(this.currentForm).triggerHandler("invalid-form", [this]);
			this.showErrors();
			return this.valid();
		},

		checkForm: function() {
			this.prepareForm();
			for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
				this.check( elements[i] );
			}
			return this.valid();
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/element
		element: function( element ) {
			element = this.clean( element );
			this.lastElement = element;
			this.prepareElement( element );
			this.currentElements = $(element);
			var result = this.check( element );
			if ( result ) {
				delete this.invalid[element.name];
			} else {
				this.invalid[element.name] = true;
			}
			if ( !this.numberOfInvalids() ) {
				// Hide error containers on last error
				this.toHide = this.toHide.add( this.containers );
			}
			this.showErrors();
			return result;
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/showErrors
		showErrors: function(errors) {
			if(errors) {
				// add items to error list and map
				$.extend( this.errorMap, errors );
				this.errorList = [];
				for ( var name in errors ) {
					this.errorList.push({
						message: errors[name],
						element: this.findByName(name)[0]
					});
				}
				// remove items from success list
				this.successList = $.grep( this.successList, function(element) {
					return !(element.name in errors);
				});
			}
			this.settings.showErrors
				? this.settings.showErrors.call( this, this.errorMap, this.errorList )
				: this.defaultShowErrors();
		},

		// http://docs.jquery.com/Plugins/Validation/Validator/resetForm
		resetForm: function() {
			if ( $.fn.resetForm )
				$( this.currentForm ).resetForm();
			this.submitted = {};
			this.prepareForm();
			this.hideErrors();
			this.elements().removeClass( this.settings.errorClass );
		},

		numberOfInvalids: function() {
			return this.objectLength(this.invalid);
		},

		objectLength: function( obj ) {
			var count = 0;
			for ( var i in obj )
				count++;
			return count;
		},

		hideErrors: function() {
			this.addWrapper( this.toHide ).hide();
		},

		valid: function() {
			return this.size() == 0;
		},

		size: function() {
			return this.errorList.length;
		},

		focusInvalid: function() {
			if( this.settings.focusInvalid ) {
				try {
					$(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
					.filter(":visible")
					.focus()
					// manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
					.trigger("focusin");
				} catch(e) {
					// ignore IE throwing errors when focusing hidden elements
				}
			}
		},

		findLastActive: function() {
			var lastActive = this.lastActive;
			return lastActive && $.grep(this.errorList, function(n) {
				return n.element.name == lastActive.name;
			}).length == 1 && lastActive;
		},

		elements: function() {
			var validator = this,
				rulesCache = {};

			// select all valid inputs inside the form (no submit or reset buttons)
			// workaround $Query([]).add until http://dev.jquery.com/ticket/2114 is solved
			return $([]).add(this.currentForm.elements)
			.filter(":input")
			.not(":submit, :reset, :image, [disabled]")
			.not( this.settings.ignore )
			.filter(function() {
				!this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this);

				// select only the first element for each name, and only those with rules specified
				if ( this.name in rulesCache || !validator.objectLength($(this).rules()) )
					return false;

				rulesCache[this.name] = true;
				return true;
			});
		},

		clean: function( selector ) {
			return $( selector )[0];
		},

		errors: function() {
			return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext );
		},

		reset: function() {
			this.successList = [];
			this.errorList = [];
			this.errorMap = {};
			this.toShow = $([]);
			this.toHide = $([]);
			this.currentElements = $([]);
		},

		prepareForm: function() {
			this.reset();
			this.toHide = this.errors().add( this.containers );
		},

		prepareElement: function( element ) {
			this.reset();
			this.toHide = this.errorsFor(element);
		},

		check: function( element ) {
			element = this.clean( element );

			// if radio/checkbox, validate first element in group instead
			if (this.checkable(element)) {
				element = this.findByName( element.name ).not(this.settings.ignore)[0];
			}

			var rules = $(element).rules();
			var dependencyMismatch = false;
			for (var method in rules ) {
				var rule = { method: method, parameters: rules[method] };
				try {
					var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters );

					// if a method indicates that the field is optional and therefore valid,
					// don't mark it as valid when there are no other rules
					if ( result == "dependency-mismatch" ) {
						dependencyMismatch = true;
						continue;
					}
					dependencyMismatch = false;

					if ( result == "pending" ) {
						this.toHide = this.toHide.not( this.errorsFor(element) );
						return;
					}

					if( !result ) {
						this.formatAndAdd( element, rule );
						return false;
					}
				} catch(e) {
					this.settings.debug && window.console && console.log("exception occured when checking element " + element.id
						 + ", check the '" + rule.method + "' method", e);
					throw e;
				}
			}
			if (dependencyMismatch)
				return;
			if ( this.objectLength(rules) )
				this.successList.push(element);
			return true;
		},

		// return the custom message for the given element and validation method
		// specified in the element's "messages" metadata
		customMetaMessage: function(element, method) {
			if (!$.metadata)
				return;

			var meta = this.settings.meta
				? $(element).metadata()[this.settings.meta]
				: $(element).metadata();

			return meta && meta.messages && meta.messages[method];
		},

		// return the custom message for the given element name and validation method
		customMessage: function( name, method ) {
			var m = this.settings.messages[name];
			return m && (m.constructor == String
				? m
				: m[method]);
		},

		// return the first defined argument, allowing empty strings
		findDefined: function() {
			for(var i = 0; i < arguments.length; i++) {
				if (arguments[i] !== undefined)
					return arguments[i];
			}
			return undefined;
		},

		defaultMessage: function( element, method) {
			return this.findDefined(
				this.customMessage( element.name, method ),
				this.customMetaMessage( element, method ),
				// title is never undefined, so handle empty string as undefined
				!this.settings.ignoreTitle && element.title || undefined,
				$.validator.messages[method],
				"<strong>Warning: No message defined for " + element.name + "</strong>"
			);
		},

		formatAndAdd: function( element, rule ) {
			var message = this.defaultMessage( element, rule.method ),
				theregex = /\$?\{(\d+)\}/g;
			if ( typeof message == "function" ) {
				message = message.call(this, rule.parameters, element);
			} else if (theregex.test(message)) {
				message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters);
			}
			this.errorList.push({
				message: message,
				element: element
			});

			this.errorMap[element.name] = message;
			this.submitted[element.name] = message;
		},

		addWrapper: function(toToggle) {
			if ( this.settings.wrapper )
				toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
			return toToggle;
		},

		defaultShowErrors: function() {
			for ( var i = 0; this.errorList[i]; i++ ) {
				var error = this.errorList[i];
				this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
				this.showLabel( error.element, error.message );
			}
			if( this.errorList.length ) {
				this.toShow = this.toShow.add( this.containers );
			}
			if (this.settings.success) {
				for ( var i = 0; this.successList[i]; i++ ) {
					this.showLabel( this.successList[i] );
				}
			}
			if (this.settings.unhighlight) {
				for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) {
					this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
				}
			}
			this.toHide = this.toHide.not( this.toShow );
			this.hideErrors();
			this.addWrapper( this.toShow ).show();
		},

		validElements: function() {
			return this.currentElements.not(this.invalidElements());
		},

		invalidElements: function() {
			return $(this.errorList).map(function() {
				return this.element;
			});
		},

		showLabel: function(element, message) {
			var label = this.errorsFor( element );
			if ( label.length ) {
				// refresh error/success class
				label.removeClass().addClass( this.settings.errorClass );

				// check if we have a generated label, replace the message then
				label.attr("generated") && label.html(message);
			} else {
				// create label
				label = $("<" + this.settings.errorElement + "/>")
					.attr({"for":  this.idOrName(element), generated: true})
					.addClass(this.settings.errorClass)
					.html(message || "");
				if ( this.settings.wrapper ) {
					// make sure the element is visible, even in IE
					// actually showing the wrapped element is handled elsewhere
					label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
				}
				if ( !this.labelContainer.append(label).length )
					this.settings.errorPlacement
						? this.settings.errorPlacement(label, $(element) )
						: label.insertAfter(element);
			}
			if ( !message && this.settings.success ) {
				label.text("");
				typeof this.settings.success == "string"
					? label.addClass( this.settings.success )
					: this.settings.success( label );
			}
			this.toShow = this.toShow.add(label);
		},

		errorsFor: function(element) {
			var name = this.idOrName(element);
    		return this.errors().filter(function() {
				return $(this).attr('for') == name;
			});
		},

		idOrName: function(element) {
			return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
		},

		checkable: function( element ) {
			return /radio|checkbox/i.test(element.type);
		},

		findByName: function( name ) {
			// select by name and filter by form for performance over form.find("[name=...]")
			var form = this.currentForm;
			return $(document.getElementsByName(name)).map(function(index, element) {
				return element.form == form && element.name == name && element  || null;
			});
		},

		getLength: function(value, element) {
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				return $("option:selected", element).length;
			case 'input':
				if( this.checkable( element) )
					return this.findByName(element.name).filter(':checked').length;
			}
			return value.length;
		},

		depend: function(param, element) {
			return this.dependTypes[typeof param]
				? this.dependTypes[typeof param](param, element)
				: true;
		},

		dependTypes: {
			"boolean": function(param, element) {
				return param;
			},
			"string": function(param, element) {
				return !!$(param, element.form).length;
			},
			"function": function(param, element) {
				return param(element);
			}
		},

		optional: function(element) {
			return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch";
		},

		startRequest: function(element) {
			if (!this.pending[element.name]) {
				this.pendingRequest++;
				this.pending[element.name] = true;
			}
		},

		stopRequest: function(element, valid) {
			this.pendingRequest--;
			// sometimes synchronization fails, make sure pendingRequest is never < 0
			if (this.pendingRequest < 0)
				this.pendingRequest = 0;
			delete this.pending[element.name];
			if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) {
				$(this.currentForm).submit();
				this.formSubmitted = false;
			} else if (!valid && this.pendingRequest == 0 && this.formSubmitted) {
				$(this.currentForm).triggerHandler("invalid-form", [this]);
				this.formSubmitted = false;
			}
		},

		previousValue: function(element) {
			return $.data(element, "previousValue") || $.data(element, "previousValue", {
				old: null,
				valid: true,
				message: this.defaultMessage( element, "remote" )
			});
		}

	},

	classRuleSettings: {
		required: {required: true},
		email: {email: true},
		url: {url: true},
		date: {date: true},
		dateISO: {dateISO: true},
		dateDE: {dateDE: true},
		number: {number: true},
		numberDE: {numberDE: true},
		digits: {digits: true},
		creditcard: {creditcard: true}
	},

	addClassRules: function(className, rules) {
		className.constructor == String ?
			this.classRuleSettings[className] = rules :
			$.extend(this.classRuleSettings, className);
	},

	classRules: function(element) {
		var rules = {};
		var classes = $(element).attr('class');
		classes && $.each(classes.split(' '), function() {
			if (this in $.validator.classRuleSettings) {
				$.extend(rules, $.validator.classRuleSettings[this]);
			}
		});
		return rules;
	},

	attributeRules: function(element) {
		var rules = {};
		var $element = $(element);

		for (var method in $.validator.methods) {
			var value = $element.attr(method);
			if (value) {
				rules[method] = value;
			}
		}

		// maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
		if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) {
			delete rules.maxlength;
		}

		return rules;
	},

	metadataRules: function(element) {
		if (!$.metadata) return {};

		var meta = $.data(element.form, 'validator').settings.meta;
		return meta ?
			$(element).metadata()[meta] :
			$(element).metadata();
	},

	staticRules: function(element) {
		var rules = {};
		var validator = $.data(element.form, 'validator');
		if (validator.settings.rules) {
			rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
		}
		return rules;
	},

	normalizeRules: function(rules, element) {
		// handle dependency check
		$.each(rules, function(prop, val) {
			// ignore rule when param is explicitly false, eg. required:false
			if (val === false) {
				delete rules[prop];
				return;
			}
			if (val.param || val.depends) {
				var keepRule = true;
				switch (typeof val.depends) {
					case "string":
						keepRule = !!$(val.depends, element.form).length;
						break;
					case "function":
						keepRule = val.depends.call(element, element);
						break;
				}
				if (keepRule) {
					rules[prop] = val.param !== undefined ? val.param : true;
				} else {
					delete rules[prop];
				}
			}
		});

		// evaluate parameters
		$.each(rules, function(rule, parameter) {
			rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
		});

		// clean number parameters
		$.each(['minlength', 'maxlength', 'min', 'max'], function() {
			if (rules[this]) {
				rules[this] = Number(rules[this]);
			}
		});
		$.each(['rangelength', 'range'], function() {
			if (rules[this]) {
				rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
			}
		});

		if ($.validator.autoCreateRanges) {
			// auto-create ranges
			if (rules.min && rules.max) {
				rules.range = [rules.min, rules.max];
				delete rules.min;
				delete rules.max;
			}
			if (rules.minlength && rules.maxlength) {
				rules.rangelength = [rules.minlength, rules.maxlength];
				delete rules.minlength;
				delete rules.maxlength;
			}
		}

		// To support custom messages in metadata ignore rule methods titled "messages"
		if (rules.messages) {
			delete rules.messages;
		}

		return rules;
	},

	// Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
	normalizeRule: function(data) {
		if( typeof data == "string" ) {
			var transformed = {};
			$.each(data.split(/\s/), function() {
				transformed[this] = true;
			});
			data = transformed;
		}
		return data;
	},

	// http://docs.jquery.com/Plugins/Validation/Validator/addMethod
	addMethod: function(name, method, message) {
		$.validator.methods[name] = method;
		$.validator.messages[name] = message != undefined ? message : $.validator.messages[name];
		if (method.length < 3) {
			$.validator.addClassRules(name, $.validator.normalizeRule(name));
		}
	},

	methods: {

		// http://docs.jquery.com/Plugins/Validation/Methods/required
		required: function(value, element, param) {
			// check if dependency is met
			if ( !this.depend(param, element) )
				return "dependency-mismatch";
			switch( element.nodeName.toLowerCase() ) {
			case 'select':
				// could be an array for select-multiple or a string, both are fine this way
				var val = $(element).val();
				return val && val.length > 0;
			case 'input':
				if ( this.checkable(element) )
					return this.getLength(value, element) > 0;
			default:
				return $.trim(value).length > 0;
			}
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/remote
		remote: function(value, element, param) {
			if ( this.optional(element) )
				return "dependency-mismatch";

			var previous = this.previousValue(element);
			if (!this.settings.messages[element.name] )
				this.settings.messages[element.name] = {};
			previous.originalMessage = this.settings.messages[element.name].remote;
			this.settings.messages[element.name].remote = previous.message;

			param = typeof param == "string" && {url:param} || param;

			if ( this.pending[element.name] ) {
				return "pending";
			}
			if ( previous.old === value ) {
				return previous.valid;
			}

			previous.old = value;
			var validator = this;
			this.startRequest(element);
			var data = {};
			data[element.name] = value;
			$.ajax($.extend(true, {
				url: param,
				mode: "abort",
				port: "validate" + element.name,
				dataType: "json",
				data: data,
				success: function(response) {
					validator.settings.messages[element.name].remote = previous.originalMessage;
					var valid = response === true;
					if ( valid ) {
						var submitted = validator.formSubmitted;
						validator.prepareElement(element);
						validator.formSubmitted = submitted;
						validator.successList.push(element);
						validator.showErrors();
					} else {
						var errors = {};
						var message = response || validator.defaultMessage( element, "remote" );
						errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
						validator.showErrors(errors);
					}
					previous.valid = valid;
					validator.stopRequest(element, valid);
				}
			}, param));
			return "pending";
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/minlength
		minlength: function(value, element, param) {
			return this.optional(element) || this.getLength($.trim(value), element) >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/maxlength
		maxlength: function(value, element, param) {
			return this.optional(element) || this.getLength($.trim(value), element) <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/rangelength
		rangelength: function(value, element, param) {
			var length = this.getLength($.trim(value), element);
			return this.optional(element) || ( length >= param[0] && length <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/min
		min: function( value, element, param ) {
			return this.optional(element) || value >= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/max
		max: function( value, element, param ) {
			return this.optional(element) || value <= param;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/range
		range: function( value, element, param ) {
			return this.optional(element) || ( value >= param[0] && value <= param[1] );
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/email
		email: function(value, element) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
			return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/url
		url: function(value, element) {
			// contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
			return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/date
		date: function(value, element) {
			return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/dateISO
		dateISO: function(value, element) {
			return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/number
		number: function(value, element) {
			return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/digits
		digits: function(value, element) {
			return this.optional(element) || /^\d+$/.test(value);
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/creditcard
		// based on http://en.wikipedia.org/wiki/Luhn
		creditcard: function(value, element) {
			if ( this.optional(element) )
				return "dependency-mismatch";
			// accept only digits and dashes
			if (/[^0-9-]+/.test(value))
				return false;
			var nCheck = 0,
				nDigit = 0,
				bEven = false;

			value = value.replace(/\D/g, "");

			for (var n = value.length - 1; n >= 0; n--) {
				var cDigit = value.charAt(n);
				var nDigit = parseInt(cDigit, 10);
				if (bEven) {
					if ((nDigit *= 2) > 9)
						nDigit -= 9;
				}
				nCheck += nDigit;
				bEven = !bEven;
			}

			return (nCheck % 10) == 0;
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/accept
		accept: function(value, element, param) {
			param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif";
			return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i"));
		},

		// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
		equalTo: function(value, element, param) {
			// bind to the blur event of the target in order to revalidate whenever the target field is updated
			// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
			var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
				$(element).valid();
			});
			return value == target.val();
		}

	}

});

// deprecated, use $.validator.format instead
$.format = $.validator.format;

})(jQuery);

// ajax mode: abort
// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
;(function($) {
	var pendingRequests = {};
	// Use a prefilter if available (1.5+)
	if ( $.ajaxPrefilter ) {
		$.ajaxPrefilter(function(settings, _, xhr) {
			var port = settings.port;
			if (settings.mode == "abort") {
				if ( pendingRequests[port] ) {
					pendingRequests[port].abort();
				}
				pendingRequests[port] = xhr;
			}
		});
	} else {
		// Proxy ajax
		var ajax = $.ajax;
		$.ajax = function(settings) {
			var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
				port = ( "port" in settings ? settings : $.ajaxSettings ).port;
			if (mode == "abort") {
				if ( pendingRequests[port] ) {
					pendingRequests[port].abort();
				}
				return (pendingRequests[port] = ajax.apply(this, arguments));
			}
			return ajax.apply(this, arguments);
		};
	}
})(jQuery);

// provides cross-browser focusin and focusout events
// IE has native support, in other browsers, use event caputuring (neither bubbles)

// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
;(function($) {
	// only implement if not provided by jQuery core (since 1.4)
	// TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs
	if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) {
		$.each({
			focus: 'focusin',
			blur: 'focusout'
		}, function( original, fix ){
			$.event.special[fix] = {
				setup:function() {
					this.addEventListener( original, handler, true );
				},
				teardown:function() {
					this.removeEventListener( original, handler, true );
				},
				handler: function(e) {
					arguments[0] = $.event.fix(e);
					arguments[0].type = fix;
					return $.event.handle.apply(this, arguments);
				}
			};
			function handler(e) {
				e = $.event.fix(e);
				e.type = fix;
				return $.event.handle.call(this, e);
			}
		});
	};
	$.extend($.fn, {
		validateDelegate: function(delegate, type, handler) {
			return this.bind(type, function(event) {
				var target = $(event.target);
				if (target.is(delegate)) {
					return handler.apply(target, arguments);
				}
			});
		}
	});
})(jQuery);
;
jQuery.noConflict();  
jQuery(document).ready(function() {

	var slider = jQuery('.view-display-id-entity_view_1 .views-row');
	var max_height = 0;
	
	jQuery('.view-display-id-entity_view_2 ul li.views-row-first a').addClass('active');
	jQuery('.view-display-id-entity_view_1 ul li.views-row-first').addClass('active');
	var tabs = jQuery('.view-display-id-entity_view_2 ul li a');
	tabs.each(function(el){
		tabs.eq(el).click(function(){
			jQuery('.view-display-id-entity_view_2 ul li a.active').removeClass('active');			
			tabs.eq(el).addClass('active');			
			jQuery('.view-display-id-entity_view_1 .active').hide().removeClass('active');
			jQuery('.swap-tab-'+tabs.eq(el).attr('rel')).show().addClass('active');
			return false;
		});		
	});


	var setonfirst = function() {
		var _first = true;		
		/* przygotowanie */
		jQuery('.front-slider-ul li').each(function(nr){
			if(_first) {
				jQuery('.front-slider-ul li').eq(nr).addClass('active');
			} else {
				
				jQuery('.front-slider-ul li').eq(nr).css({					
					"display": "none"
				});
			}
			_first = false;
		});
	}
	

	var images_number = jQuery('.front-slider-ul li').length;
	if (images_number > 0) {			
		setonfirst();
		var item_bar_width = jQuery('#slider_scroll').width()/images_number;
		jQuery('#slider_bar').animate({
						"width": item_bar_width
					},
					200);
		
		var ifmouseover = false;
		
		jQuery('.front-slider-ul').mouseover(function () {
			ifmouseover = true;
		});
		jQuery('.front-slider-ul').mouseout(function () {
			ifmouseover = false;
		});
		/* przerzucanie */
		var active_nr = 0; 
		var slide = function() {
			if(ifmouseover) return 0;
			active_nr++;
			if (active_nr < images_number) {
				jQuery('.front-slider-ul li').eq(active_nr).css({"display":"block"});//,"opacity":0}).animate({"opacity":1},4500);				
			} else {
				setonfirst();
				active_nr = 0; 
			}
			jQuery('#slider_bar').animate({
						"margin-left": active_nr*item_bar_width
					},
					200);
		}
		var interwal = setInterval(slide, 5000);
		
	}
	
	
	
	
	
	jQuery('#edit-field-termin-und-0-value').attr('AUTOCOMPLETE', 'OFF');
	
	var currentTime = new Date();
	var month=new Array(12);
	month[0]="01";
	month[1]="02";
	month[2]="03";
	month[3]="04";
	month[4]="05";
	month[5]="06";
	month[6]="07";
	month[7]="08";
	month[8]="09";
	month[9]="10";
	month[10]="11";
	month[11]="12";

	var months = currentTime.getMonth();
	var day = currentTime.getDate();
	var year = currentTime.getFullYear();
	
	var currentdate = day+"-"+month[months]+"-"+year;

	jQuery("#edit-field-termin-und-0-value").DatePicker({
		format:'d-m-Y',
		date: currentdate,
		current: currentdate,
		starts: 1,
		position: 'r',
		onBeforeShow: function(){
			jQuery('#edit-field-termin-und-0-value').DatePickerSetDate(currentdate, true);
		},
		onChange: function(formated, dates){
			jQuery('#edit-field-termin-und-0-value').val(formated);
			if (jQuery('#closeOnSelect input').attr('checked')) {
				jQuery('#edit-field-termin-und-0-value').DatePickerHide();
			}
		},
		locale: {
			days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota", "Niedziela"],
			daysShort: ["Nie", "Pon", "Wt", "Śr", "Czw", "Pt", "Sob", "Nie"],
			daysMin: ["Ni", "Po", "Wt", "Śr", "Cz", "Pt", "Sb", "Ni"],
			months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"],
			monthsShort: ["Sty", "Lut", "Mar", "Kwi", "Maj", "Czer", "Lip", "Sie", "Wrz", "Paź", "Lis", "Gru"], 
			weekMin: 'ty'
		}
	});
});

;
;
 /****************************************************************
  *                                                              *
  *  CurvyCorners                                                *
  *  ------------                                                *
  *                                                              *
  *  This script generates rounded corners for your boxes.       *
  *                                                              *
  *  Version 2.1                                             *
  *  Copyright (c) 2010 Cameron Cooke                            *
  *  Contributors: Tim Hutchison, CPK Smithies, Terry Riegel,    *
  *                SimĂł Albert.                                  *
  *                                                              *
  *  Website: http://www.curvycorners.net                        *
  *  SVN:     http://curvycorners.googlecode.com/                *
  *  Email:   cameron@curvycorners.net                           *
  *  Discuss: http://groups.google.com/group/curvycorners        *
  *                                                              *
  *  Please consult the SVN for a list of changes since the last *
  *  revision.                                                   *
  *                                                              *
  *  This library is free software; you can redistribute         *
  *  it and/or modify it under the terms of the GNU              *
  *  Lesser General Public License as published by the           *
  *  Free Software Foundation; either version 2.1 of the         *
  *  License, or (at your option) any later version.             *
  *                                                              *
  *  This library is distributed in the hope that it will        *
  *  be useful, but WITHOUT ANY WARRANTY; without even the       *
  *  implied warranty of MERCHANTABILITY or FITNESS FOR A        *
  *  PARTICULAR PURPOSE. See the GNU Lesser General Public       *
  *  License for more details.                                   *
  *                                                              *
  *  You should have received a copy of the GNU Lesser           *
  *  General Public License along with this library;             *
  *  Inc., 59 Temple Place, Suite 330, Boston,                   *
  *  MA 02111-1307 USA                                           *
  *                                                              *
  ****************************************************************/

/*
Version 2.x now autoMagically applies borders via CSS rules.

Opera and Chrome support rounded corners via

border-radius

Safari and Mozilla support rounded borders via

-webkit-border-radius, -moz-border-radius

We let these browsers render their borders natively.
Firefox for Windows renders non-antialiased
borders so they look a bit ugly. Google's Chrome will render its "ugly"
borders as well. So if we let FireFox, Safari, Opera and Chrome render
their borders natively, then we only have to support IE
for rounded borders. Fortunately IE reads CSS properties
that it doesn't understand (Opera, Firefox and Safari discard them);
so for IE we find and apply -moz-border-radius and friends.

So to make curvycorners work with any major browser simply add the
following CSS declarations and it should be good to go...

.round {
  border-radius: 3ex;
  -webkit-border-radius: 3ex;
  -moz-border-radius: 3ex;
}
*/

function browserdetect() {
  var agent = navigator.userAgent.toLowerCase();
  this.isIE = agent.indexOf("msie") > -1;
  if (this.isIE) {
    this.ieVer = /msie\s(\d\.\d)/.exec(agent)[1];
    this.quirksMode = !document.compatMode || document.compatMode.indexOf("BackCompat") > -1;
    this.get_style = function(obj, prop) {
      if (!(prop in obj.currentStyle)) return "";
      var matches = /^([\d.]+)(\w*)/.exec(obj.currentStyle[prop]);
      if (!matches) return obj.currentStyle[prop];
      if (matches[1] == 0) return '0';
      // now convert to pixels if necessary
      if (matches[2] && matches[2] !== 'px') {
        var style = obj.style.left;
        var rtStyle = obj.runtimeStyle.left;
        obj.runtimeStyle.left = obj.currentStyle.left;
        obj.style.left = matches[1] + matches[2];
        matches[0] = obj.style.pixelLeft;
        obj.style.left = style;
        obj.runtimeStyle.left = rtStyle;
      }
      return matches[0];
    };
    this.supportsCorners = false;
  }
  else {
    this.ieVer = this.quirksMode = 0;
    this.get_style = function(obj, prop) {
      prop = prop.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
      return document.defaultView.getComputedStyle(obj, '').getPropertyValue(prop);
    };
    this.isSafari  = agent.indexOf('safari') != -1;
    this.isWebKit  = agent.indexOf('webkit') != -1;
    this.isOp      = 'opera' in window;
    if (this.isOp)
      this.supportsCorners =  (this.isOp = window.opera.version()) >= 10.5;
    else {
      if (!this.isWebkit) { // firefox check
        if (!(this.isMoz = agent.indexOf('firefox') !== -1)) {
          for (var i = document.childNodes.length; --i >= 0; ) if ('style' in document.childNodes[i]) {
            this.isMoz = 'MozBorderRadius' in document.childNodes[i].style;
            break;
          }
        }
      }
      this.supportsCorners = this.isWebKit || this.isMoz;
    }
  }
}
var curvyBrowser = new browserdetect;

/* Force caching of bg images in IE6 */
if (curvyBrowser.isIE) {
  try {
    document.execCommand("BackgroundImageCache", false, true);
  }
  catch(e) {}
}

// object that parses border-radius properties for a box

function curvyCnrSpec(selText) {
  this.selectorText = selText;
  this.tlR = this.trR = this.blR = this.brR = 0;
  this.tlu = this.tru = this.blu = this.bru = "";
  this.antiAlias = true; // default true
}
curvyCnrSpec.prototype.setcorner = function(tb, lr, radius, unit) {
  if (!tb) { // no corner specified
    this.tlR = this.trR = this.blR = this.brR = parseInt(radius);
    this.tlu = this.tru = this.blu = this.bru = unit;
  }
  else { // corner specified
    var propname = tb.charAt(0) + lr.charAt(0);
    this[propname + 'R'] = parseInt(radius);
    this[propname + 'u'] = unit;
  }
};
/*
  get(propstring)
  where propstring is:
  - 'tR' or 'bR' : returns top or bottom radius.
  - 'tlR', 'trR', 'blR' or 'brR' : returns top/bottom left/right radius.
  - 'tlu', 'tru', 'blr' or 'bru' : returns t/b l/r unit (px, em...)
  - 'tRu' or 'bRu' : returns top/bottom radius+unit
  - 'tlRu', 'trRu', 'blRu', 'brRu' : returns t/b l/r radius+unit
*/
curvyCnrSpec.prototype.get = function(prop) {
  if (/^(t|b)(l|r)(R|u)$/.test(prop)) return this[prop];
  if (/^(t|b)(l|r)Ru$/.test(prop)) {
    var pname = prop.charAt(0) + prop.charAt(1);
    return this[pname + 'R'] + this[pname + 'u'];
  }
  if (/^(t|b)Ru?$/.test(prop)) {
    var tb = prop.charAt(0);
    tb += this[tb + 'lR'] > this[tb + 'rR'] ? 'l' : 'r';
    var retval = this[tb + 'R'];
    if (prop.length === 3 && prop.charAt(2) === 'u')
      retval += this[tb = 'u'];
    return retval;
  }
  throw new Error('Don\'t recognize property ' + prop);
};
curvyCnrSpec.prototype.radiusdiff = function(tb) {
  if (tb !== 't' && tb !== 'b') throw new Error("Param must be 't' or 'b'");
  return Math.abs(this[tb + 'lR'] - this[tb + 'rR']);
};
curvyCnrSpec.prototype.setfrom = function(obj) {
  this.tlu = this.tru = this.blu = this.bru = 'px'; // default to px
  if ('tl' in obj) this.tlR = obj.tl.radius;
  if ('tr' in obj) this.trR = obj.tr.radius;
  if ('bl' in obj) this.blR = obj.bl.radius;
  if ('br' in obj) this.brR = obj.br.radius;
  if ('antiAlias' in obj) this.antiAlias = obj.antiAlias;
};
curvyCnrSpec.prototype.cloneOn = function(box) { // not needed by IE
  var props = ['tl', 'tr', 'bl', 'br'];
  var converted = 0;
  var i, propu;

  for (i in props) if (!isNaN(i)) {
    propu = this[props[i] + 'u'];
    if (propu !== '' && propu !== 'px') {
      converted = new curvyCnrSpec;
      break;
    }
  }
  if (!converted)
    converted = this; // no need to clone
  else {
    var propi, propR, save = curvyBrowser.get_style(box, 'left');
    for (i in props) if (!isNaN(i)) {
      propi = props[i];
      propu = this[propi + 'u'];
      propR = this[propi + 'R'];
      if (propu !== 'px') {
        var save2 = box.style.left;
        box.style.left = propR + propu;
        propR = box.style.pixelLeft;
        box.style.left = save2;
      }
      converted[propi + 'R'] = propR;
      converted[propi + 'u'] = 'px';
    }
    box.style.left = save;
  }
  return converted;
};
curvyCnrSpec.prototype.radiusSum = function(tb) {
  if (tb !== 't' && tb !== 'b') throw new Error("Param must be 't' or 'b'");
  return this[tb + 'lR'] + this[tb + 'rR'];
};
curvyCnrSpec.prototype.radiusCount = function(tb) {
  var count = 0;
  if (this[tb + 'lR']) ++count;
  if (this[tb + 'rR']) ++count;
  return count;
};
curvyCnrSpec.prototype.cornerNames = function() {
  var ret = [];
  if (this.tlR) ret.push('tl');
  if (this.trR) ret.push('tr');
  if (this.blR) ret.push('bl');
  if (this.brR) ret.push('br');
  return ret;
};

/*
  Object that parses Opera CSS
*/
function operasheet(sheetnumber) {
  var txt = document.styleSheets.item(sheetnumber).ownerNode.text;
  txt = txt.replace(/\/\*(\n|\r|.)*?\*\//g, ''); // strip comments
  // this pattern extracts all border-radius-containing rulesets
  // matches will be:
  // [0] = the whole lot
  // [1] = the selector text
  // [2] = all the rule text between braces
  // [3] = top/bottom and left/right parts if present (only if webkit/CSS3)
  // [4] = top|bottom
  // [5] = left|right
  // .. but 3..5 are useless as they're only the first match.
  var pat = new RegExp("^\\s*([\\w.#][-\\w.#, ]+)[\\n\\s]*\\{([^}]+border-((top|bottom)-(left|right)-)?radius[^}]*)\\}", "mg");
  var matches;
  this.rules = [];
  while ((matches = pat.exec(txt)) !== null) {
    var pat2 = new RegExp("(..)border-((top|bottom)-(left|right)-)?radius:\\s*([\\d.]+)(in|em|px|ex|pt)", "g");
    var submatches, cornerspec = new curvyCnrSpec(matches[1]);
    while ((submatches = pat2.exec(matches[2])) !== null)
      if (submatches[1] !== "z-")
        cornerspec.setcorner(submatches[3], submatches[4], submatches[5], submatches[6]);
    this.rules.push(cornerspec);
  }
}
// static class function to determine if the sheet is worth parsing
operasheet.contains_border_radius = function(sheetnumber) {
  return /border-((top|bottom)-(left|right)-)?radius/.test(document.styleSheets.item(sheetnumber).ownerNode.text);
};

/*
Usage:

  curvyCorners(settingsObj, "selectorStr");
  curvyCorners(settingsObj, domObj1[, domObj2[, domObj3[, . . . [, domObjN]]]]);
  selectorStr::= "<complexSelector>[, <complexSelector>]..."
  complexSelector::= <selector>[ <selector]
  selector::= "[<elementname>].classname" | "#id"
*/

function curvyCorners() {
  var i, j, boxCol, settings, startIndex;
  // Check parameters
  if (typeof arguments[0] !== "object") throw curvyCorners.newError("First parameter of curvyCorners() must be an object.");
  if (arguments[0] instanceof curvyCnrSpec) {
    settings = arguments[0];
    if (!settings.selectorText && typeof arguments[1] === 'string')
      settings.selectorText = arguments[1];
  }
  else {
    if (typeof arguments[1] !== "object" && typeof arguments[1] !== "string") throw curvyCorners.newError("Second parameter of curvyCorners() must be an object or a class name.");
    j = arguments[1];
    if (typeof j !== 'string') j = '';
    if (j !== '' && j.charAt(0) !== '.' && 'autoPad' in arguments[0]) j = '.' + j; // for compatibility, prefix with dot
    settings = new curvyCnrSpec(j);
    settings.setfrom(arguments[0]);
  }

  // Get object(s)
  if (settings.selectorText) {
    startIndex = 0;
    var args = settings.selectorText.replace(/\s+$/,'').split(/,\s*/); // handle comma-separated selector list
    boxCol = new Array;

    for (i = 0; i < args.length; ++i) {
      if ((j = args[i].lastIndexOf('#')) !== -1)
        args[i] = args[i].substr(j); // ignore everything on LHS of ID
      boxCol = boxCol.concat(curvyCorners.getElementsBySelector(args[i].split(/\s+/)));
    }
  }
  else {
    startIndex = 1;
    boxCol = arguments;
  }

  // Loop through each object
  for (i = startIndex, j = boxCol.length; i < j; ++i) {
    var theBox = boxCol[i];
    var skipCorners = false;
    if (!theBox.className)
      theBox.className = 'curvyIgnore'; // don't do it twice
    else {
      skipCorners = theBox.className.indexOf('curvyIgnore') !== -1;
      if (!skipCorners) theBox.className += ' curvyIgnore'; // prevent repeats
    }
    if (!skipCorners) {
      if (theBox.className.indexOf('curvyRedraw') !== -1) {
        if (typeof curvyCorners.redrawList === 'undefined') curvyCorners.redrawList = new Array;
        curvyCorners.redrawList.push({
          node : theBox,
          spec : settings,
          copy : theBox.cloneNode(false)
        });
      }
      var obj = new curvyObject(settings, theBox);
      obj.applyCorners();
    }
  }
}
curvyCorners.prototype.applyCornersToAll = function () { // now redundant
  throw curvyCorners.newError('This function is now redundant. Just call curvyCorners(). See documentation.');
};

curvyCorners.redraw = function() {
  if (curvyBrowser.supportsCorners) return;
  if (!curvyCorners.redrawList) throw curvyCorners.newError('curvyCorners.redraw() has nothing to redraw.');
  var old_block_value = curvyCorners.block_redraw;
  curvyCorners.block_redraw = true;
  for (var i in curvyCorners.redrawList) {
    if (isNaN(i)) continue; // in case of added prototype methods
    var o = curvyCorners.redrawList[i];
    if (!o.node.clientWidth) continue; // don't resize hidden boxes
    var newchild = o.copy.cloneNode(false);
    for (var contents = o.node.firstChild; contents !== null; contents = contents.nextSibling)
      if (contents.className.indexOf('autoPadDiv') !== -1) break;
    if (!contents) {
      curvyCorners.alert('Couldn\'t find autoPad DIV');
      break;
    }
    o.node.parentNode.replaceChild(newchild, o.node);
    // remove script elements, if any
    var scripts = contents.getElementsByTagName('script');
    for (var j = scripts.length - 1; j >= 0; --j)
      scripts[j].parentNode.removeChild(scripts[j]);
    while (contents.firstChild) newchild.appendChild(contents.removeChild(contents.firstChild));
    o = new curvyObject(o.spec, o.node = newchild);
    o.applyCorners();
  }
  curvyCorners.block_redraw = old_block_value;
};
curvyCorners.adjust = function(obj, prop, newval) {
  if (!curvyBrowser.supportsCorners) {
    if (!curvyCorners.redrawList) throw curvyCorners.newError('curvyCorners.adjust() has nothing to adjust.');
    var i, j = curvyCorners.redrawList.length;
    for (i = 0; i < j; ++i) if (curvyCorners.redrawList[i].node === obj) break;
    if (i === j) throw curvyCorners.newError('Object not redrawable');
    obj = curvyCorners.redrawList[i].copy;
  }
  if (prop.indexOf('.') === -1)
    obj[prop] = newval;
  else eval('obj.' + prop + "='" + newval + "'");
};
curvyCorners.handleWinResize = function() {
  if (!curvyCorners.block_redraw) curvyCorners.redraw();
};
curvyCorners.setWinResize = function(onoff) {
  curvyCorners.block_redraw = !onoff;
};
curvyCorners.newError = function(errorMessage) {
  return new Error("curvyCorners Error:\n" + errorMessage);
};
curvyCorners.alert = function(errorMessage) {
  if (typeof curvyCornersVerbose === 'undefined' || curvyCornersVerbose) alert(errorMessage);
};

// curvyCorners object (can be called directly)

function curvyObject() {
  var boxDisp;
  this.box              = arguments[1];
  this.settings         = arguments[0];
  this.topContainer = this.bottomContainer = this.shell = boxDisp = null;
  var boxWidth = this.box.clientWidth; // browser-independent IE-emulation (NB includes padding)

  if (('canHaveChildren' in this.box && !this.box.canHaveChildren) || this.box.tagName === 'TABLE')
    throw new Error(this.errmsg("You cannot apply corners to " + this.box.tagName + " elements.", "Error"));
  if (!boxWidth && curvyBrowser.isIE) {
    this.box.style.zoom = 1; // can force IE to calculate width
    boxWidth = this.box.clientWidth;
  }

  // try to handle attempts to style inline elements

  if (!boxWidth && curvyBrowser.get_style(this.box, 'display') === 'inline') {
    this.box.style.display = 'inline-block';
    curvyCorners.alert(this.errmsg("Converting inline element to inline-block", "warning"));
    boxWidth = this.box.clientWidth;
  }

  // if still no clientWidth, maybe the box or a parent has 'display:none'.

  if (!boxWidth) {
    if (!this.box.parentNode) throw this.newError("box has no parent!"); // unlikely...
    for (boxDisp = this.box; ; boxDisp = boxDisp.parentNode) {
      if (!boxDisp || boxDisp.tagName === 'BODY') { // we've hit the buffers
        this.applyCorners = function() {}; // make the error benign
        curvyCorners.alert(this.errmsg("zero-width box with no accountable parent", "warning"));
        return;
      }
      if (curvyBrowser.get_style(boxDisp, 'display') === 'none') break;
    }
    // here, we've found the box whose display is set to 'none'.
    var boxDispSave = boxDisp.style.display;
    boxDisp.style.display = 'block'; // display in order to get browser to calculate clientWidth
    boxWidth = this.box.clientWidth;
  }

  // all attempts have failed

  if (!boxWidth) {
    curvyCorners.alert(this.errmsg("zero-width box, cannot display", "error"));
    this.applyCorners = function() {}; // make the error harmless
    return;
  }
  if (arguments[0] instanceof curvyCnrSpec)
    this.spec = arguments[0].cloneOn(this.box); // convert non-pixel units
  else {
    this.spec = new curvyCnrSpec('');
    this.spec.setfrom(this.settings); // no need for unit conversion, use settings param. directly
  }

  // Get box formatting details
  var borderWidth     = curvyBrowser.get_style(this.box, "borderTopWidth");
  var borderWidthB    = curvyBrowser.get_style(this.box, "borderBottomWidth");
  var borderWidthL    = curvyBrowser.get_style(this.box, "borderLeftWidth");
  var borderWidthR    = curvyBrowser.get_style(this.box, "borderRightWidth");
  var borderColour    = curvyBrowser.get_style(this.box, "borderTopColor");
  var borderColourB   = curvyBrowser.get_style(this.box, "borderBottomColor");
  var borderColourL   = curvyBrowser.get_style(this.box, "borderLeftColor");
  var borderColourR   = curvyBrowser.get_style(this.box, "borderRightColor");
  var borderStyle     = curvyBrowser.get_style(this.box, "borderTopStyle");
  var borderStyleB    = curvyBrowser.get_style(this.box, "borderBottomStyle");
  var borderStyleL    = curvyBrowser.get_style(this.box, "borderLeftStyle");
  var borderStyleR    = curvyBrowser.get_style(this.box, "borderRightStyle");

  var boxColour       = curvyBrowser.get_style(this.box, "backgroundColor");
  var backgroundImage = curvyBrowser.get_style(this.box, "backgroundImage");
  var backgroundRepeat= curvyBrowser.get_style(this.box, "backgroundRepeat");
  var backgroundPosX, backgroundPosY;
  if (this.box.currentStyle && this.box.currentStyle.backgroundPositionX) {
    backgroundPosX  = curvyBrowser.get_style(this.box, "backgroundPositionX");
    backgroundPosY  = curvyBrowser.get_style(this.box, "backgroundPositionY");
  }
  else {
    backgroundPosX = curvyBrowser.get_style(this.box, 'backgroundPosition');
    backgroundPosX = backgroundPosX.split(' ');
    backgroundPosY = backgroundPosX.length === 2 ? backgroundPosX[1] : 0;
    backgroundPosX = backgroundPosX[0];
  }
  var boxPosition     = curvyBrowser.get_style(this.box, "position");
  var topPadding      = curvyBrowser.get_style(this.box, "paddingTop");
  var bottomPadding   = curvyBrowser.get_style(this.box, "paddingBottom");
  var leftPadding     = curvyBrowser.get_style(this.box, "paddingLeft");
  var rightPadding    = curvyBrowser.get_style(this.box, "paddingRight");
  var filter = curvyBrowser.ieVer > 7 ? curvyBrowser.get_style(this.box, 'filter') : null; // IE8 bug fix

  var topMaxRadius    = this.spec.get('tR');
  var botMaxRadius    = this.spec.get('bR');
  var styleToNPx = function(val) {
    if (typeof val === 'number') return val;
    if (typeof val !== 'string') throw new Error('unexpected styleToNPx type ' + typeof val);
    var matches = /^[-\d.]([a-z]+)$/.exec(val);
    if (matches && matches[1] != 'px') throw new Error('Unexpected unit ' + matches[1]);
    if (isNaN(val = parseInt(val))) val = 0;
    return val;
  };
  var min0Px = function(val) {
    return val <= 0 ? "0" : val + "px";
  };

  // Set formatting properties
  try {
    this.borderWidth     = styleToNPx(borderWidth);
    this.borderWidthB    = styleToNPx(borderWidthB);
    this.borderWidthL    = styleToNPx(borderWidthL);
    this.borderWidthR    = styleToNPx(borderWidthR);
    this.boxColour       = curvyObject.format_colour(boxColour);
    this.topPadding      = styleToNPx(topPadding);
    this.bottomPadding   = styleToNPx(bottomPadding);
    this.leftPadding     = styleToNPx(leftPadding);
    this.rightPadding    = styleToNPx(rightPadding);
    this.boxWidth        = boxWidth;
    this.boxHeight       = this.box.clientHeight;
    this.borderColour    = curvyObject.format_colour(borderColour);
    this.borderColourB   = curvyObject.format_colour(borderColourB);
    this.borderColourL   = curvyObject.format_colour(borderColourL);
    this.borderColourR   = curvyObject.format_colour(borderColourR);
    this.borderString    = this.borderWidth + "px" + " " + borderStyle + " " + this.borderColour;
    this.borderStringB   = this.borderWidthB + "px" + " " + borderStyleB + " " + this.borderColourB;
    this.borderStringL   = this.borderWidthL + "px" + " " + borderStyleL + " " + this.borderColourL;
    this.borderStringR   = this.borderWidthR + "px" + " " + borderStyleR + " " + this.borderColourR;
    this.backgroundImage = ((backgroundImage != "none")? backgroundImage : "");
    this.backgroundRepeat= backgroundRepeat;
  }
  catch(e) {
    throw this.newError(e.message);
  }
  var clientHeight = this.boxHeight;
  var clientWidth = boxWidth; // save it as it gets trampled on later
  if (curvyBrowser.isOp) {
    var t;
    backgroundPosX = styleToNPx(backgroundPosX);
    backgroundPosY = styleToNPx(backgroundPosY);
    if (backgroundPosX) {
      t = clientWidth + this.borderWidthL + this.borderWidthR;
      if (backgroundPosX > t) backgroundPosX = t;
      backgroundPosX = (t / backgroundPosX * 100) + '%'; // convert to percentage
    }
    if (backgroundPosY) {
      t = clientHeight + this.borderWidth + this.borderWidthB;
      if (backgroundPosY > t) backgroundPosY = t;
      backgroundPosY = (t / backgroundPosY * 100) + '%'; // convert to percentage
    }
  }
  if (curvyBrowser.quirksMode) {
  }
  else {
    this.boxWidth -= this.leftPadding + this.rightPadding;
    this.boxHeight -= this.topPadding + this.bottomPadding;
  }

  // Create content container
  this.contentContainer = document.createElement("div");
  if (filter) this.contentContainer.style.filter = filter; // IE8 bug fix
  while (this.box.firstChild) this.contentContainer.appendChild(this.box.removeChild(this.box.firstChild));

  if (boxPosition != "absolute") this.box.style.position = "relative";
  this.box.style.padding = '0';
  this.box.style.border = this.box.style.backgroundImage = 'none';
  this.box.style.backgroundColor = 'transparent';

  this.box.style.width   = (clientWidth + this.borderWidthL + this.borderWidthR) + 'px';
  this.box.style.height  = (clientHeight + this.borderWidth + this.borderWidthB) + 'px';

  // Ok we add an inner div to actually put things into this will allow us to keep the height

  var newMainContainer = document.createElement("div");
  newMainContainer.style.position = "absolute";
  if (filter) newMainContainer.style.filter = filter; // IE8 bug fix
  if (curvyBrowser.quirksMode) {
    newMainContainer.style.width  = (clientWidth + this.borderWidthL + this.borderWidthR) + 'px';
  } else {
    newMainContainer.style.width  = clientWidth + 'px';
  }
  newMainContainer.style.height = min0Px(clientHeight + this.borderWidth + this.borderWidthB - topMaxRadius - botMaxRadius);
  newMainContainer.style.padding  = "0";
  newMainContainer.style.top    = topMaxRadius + "px";
  newMainContainer.style.left   = "0";
  if (this.borderWidthL)
    newMainContainer.style.borderLeft = this.borderStringL;
  if (this.borderWidth && !topMaxRadius)
    newMainContainer.style.borderTop = this.borderString;
  if (this.borderWidthR)
    newMainContainer.style.borderRight = this.borderStringR;
  if (this.borderWidthB && !botMaxRadius)
    newMainContainer.style.borderBottom = this.borderStringB;
  newMainContainer.style.backgroundColor    = boxColour;
  newMainContainer.style.backgroundImage    = this.backgroundImage;
  newMainContainer.style.backgroundRepeat   = this.backgroundRepeat;
  newMainContainer.style.direction = 'ltr';
  this.shell = this.box.appendChild(newMainContainer);

  boxWidth = curvyBrowser.get_style(this.shell, "width");
  if (boxWidth === "" || boxWidth === "auto" || boxWidth.indexOf("%") !== -1) throw this.newError('Shell width is ' + boxWidth);
  this.boxWidth = (boxWidth !== "" && boxWidth != "auto" && boxWidth.indexOf("%") == -1) ? parseInt(boxWidth) : this.shell.clientWidth;

  /*
    This method creates the corners and
    applies them to the div element.
  */
  this.applyCorners = function() {
    /*
      Set up background offsets. This may need to be delayed until
      the background image is loaded.
    */
    this.backgroundPosX = this.backgroundPosY = 0;
    if (this.backgroundObject) {
      var bgOffset = function(style, imglen, boxlen) {
        if (style === 0) return 0;
        if (style === 'right' || style === 'bottom') return boxlen - imglen;
        if (style === 'center') return (boxlen - imglen) / 2;
        if (style.indexOf('%') > 0) return (boxlen - imglen) * 100 / parseInt(style);
        return styleToNPx(style);
      };
      this.backgroundPosX  = bgOffset(backgroundPosX, this.backgroundObject.width, clientWidth);
      this.backgroundPosY  = bgOffset(backgroundPosY, this.backgroundObject.height, clientHeight);
    }
    else if (this.backgroundImage) {
      this.backgroundPosX = styleToNPx(backgroundPosX);
      this.backgroundPosY = styleToNPx(backgroundPosY);
    }
    /*
      Create top and bottom containers.
      These will be used as a parent for the corners and bars.
    */
    // Build top bar only if a top corner is to be drawn
    if (topMaxRadius) {
      newMainContainer = document.createElement("div");
      newMainContainer.style.width = this.boxWidth + "px";
      newMainContainer.style.fontSize = "1px";
      newMainContainer.style.overflow = "hidden";
      newMainContainer.style.position = "absolute";
      newMainContainer.style.paddingLeft  = this.borderWidth + "px";
      newMainContainer.style.paddingRight = this.borderWidth + "px";
      newMainContainer.style.height = topMaxRadius + "px";
      newMainContainer.style.top    = -topMaxRadius + "px";
      newMainContainer.style.left   = -this.borderWidthL + "px";
      this.topContainer = this.shell.appendChild(newMainContainer);
    }
    // Build bottom bar only if a bottom corner is to be drawn
    if (botMaxRadius) {
      newMainContainer = document.createElement("div");
      newMainContainer.style.width = this.boxWidth + "px";
      newMainContainer.style.fontSize = "1px";
      newMainContainer.style.overflow = "hidden";
      newMainContainer.style.position = "absolute";
      newMainContainer.style.paddingLeft  = this.borderWidthB + "px";
      newMainContainer.style.paddingRight = this.borderWidthB + "px";
      newMainContainer.style.height   =  botMaxRadius + "px";
      newMainContainer.style.bottom   = -botMaxRadius + "px";
      newMainContainer.style.left     = -this.borderWidthL + "px";
      this.bottomContainer = this.shell.appendChild(newMainContainer);
    }

    var corners = this.spec.cornerNames();  // array of available corners

    /*
    Loop for each corner
    */
    for (var i in corners) if (!isNaN(i)) {
      // Get current corner type from array
      var cc = corners[i];
      var specRadius = this.spec[cc + 'R'];
      // Has the user requested the currentCorner be round?
      // Code to apply correct color to top or bottom
      var bwidth, bcolor, borderRadius, borderWidthTB;
      if (cc == "tr" || cc == "tl") {
        bwidth = this.borderWidth;
        bcolor = this.borderColour;
        borderWidthTB = this.borderWidth;
      } else {
        bwidth = this.borderWidthB;
        bcolor = this.borderColourB;
        borderWidthTB = this.borderWidthB;
      }
      borderRadius = specRadius - borderWidthTB;
      var newCorner = document.createElement("div");
      newCorner.style.height = this.spec.get(cc + 'Ru');
      newCorner.style.width  = this.spec.get(cc + 'Ru');
      newCorner.style.position = "absolute";
      newCorner.style.fontSize = "1px";
      newCorner.style.overflow = "hidden";
      // THE FOLLOWING BLOCK OF CODE CREATES A ROUNDED CORNER
      // ---------------------------------------------------- TOP
      var intx, inty, outsideColour;
      var trans = filter ? parseInt(/alpha\(opacity.(\d+)\)/.exec(filter)[1]) : 100; // IE8 bug fix
      // Cycle the x-axis
      for (intx = 0; intx < specRadius; ++intx) {
        // Calculate the value of y1 which identifies the pixels inside the border
        var y1 = (intx + 1 >= borderRadius) ? -1 : Math.floor(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow(intx + 1, 2))) - 1;
        // Calculate y2 and y3 only if there is a border defined
        if (borderRadius != specRadius) {
          var y2 = (intx >= borderRadius) ? -1 : Math.ceil(Math.sqrt(Math.pow(borderRadius, 2) - Math.pow(intx, 2)));
          var y3 = (intx + 1 >= specRadius) ? -1 : Math.floor(Math.sqrt(Math.pow(specRadius, 2) - Math.pow((intx+1), 2))) - 1;
        }
        // Calculate y4
        var y4 = (intx >= specRadius) ? -1 : Math.ceil(Math.sqrt(Math.pow(specRadius, 2) - Math.pow(intx, 2)));
        // Draw bar on inside of the border with foreground colour
        if (y1 > -1) this.drawPixel(intx, 0, this.boxColour, trans, (y1 + 1), newCorner, true, specRadius);
        // Draw border/foreground antialiased pixels and border only if there is a border defined
        if (borderRadius != specRadius) {
          // Cycle the y-axis
          if (this.spec.antiAlias) {
            for (inty = y1 + 1; inty < y2; ++inty) {
              // For each of the pixels that need anti aliasing between the foreground and border colour draw single pixel divs
              if (this.backgroundImage !== "") {
                var borderFract = curvyObject.pixelFraction(intx, inty, borderRadius) * 100;
                this.drawPixel(intx, inty, bcolor, trans, 1, newCorner, borderFract >= 30, specRadius);
              }
              else if (this.boxColour !== 'transparent') {
                var pixelcolour = curvyObject.BlendColour(this.boxColour, bcolor, curvyObject.pixelFraction(intx, inty, borderRadius));
                this.drawPixel(intx, inty, pixelcolour, trans, 1, newCorner, false, specRadius);
              }
              else this.drawPixel(intx, inty, bcolor, trans >> 1, 1, newCorner, false, specRadius);
            }
            // Draw bar for the border
            if (y3 >= y2) {
              if (y2 == -1) y2 = 0;
              this.drawPixel(intx, y2, bcolor, trans, (y3 - y2 + 1), newCorner, false, 0);
            }
            outsideColour = bcolor;  // Set the colour for the outside AA curve
            inty = y3;               // start_pos - 1 for y-axis AA pixels
          }
          else { // no antiAlias
            if (y3 > y1) { // NB condition was >=, changed to avoid zero-height divs
              this.drawPixel(intx, (y1 + 1), bcolor, trans, (y3 - y1), newCorner, false, 0);
            }
          }
        }
        else {
          outsideColour = this.boxColour;  // Set the colour for the outside curve
          inty = y1;               // start_pos - 1 for y-axis AA pixels
        }
        // Draw aa pixels?
        if (this.spec.antiAlias && this.boxColour !== 'transparent') {
          // Cycle the y-axis and draw the anti aliased pixels on the outside of the curve
          while (++inty < y4) {
            // For each of the pixels that need anti aliasing between the foreground/border colour & background draw single pixel divs
            this.drawPixel(intx, inty, outsideColour, (curvyObject.pixelFraction(intx, inty , specRadius) * trans), 1, newCorner, borderWidthTB <= 0, specRadius);
          }
        }
      }
      // END OF CORNER CREATION
      // ---------------------------------------------------- END

      /*
      Now we have a new corner we need to reposition all the pixels unless
      the current corner is the bottom right.
      */
      // Loop through all children (pixel bars)
      var k;
      for (t = 0, k = newCorner.childNodes.length; t < k; ++t) {
        // Get current pixel bar
        var pixelBar = newCorner.childNodes[t];
        // Get current top and left properties
        var pixelBarTop    = parseInt(pixelBar.style.top);
        var pixelBarLeft   = parseInt(pixelBar.style.left);
        var pixelBarHeight = parseInt(pixelBar.style.height);
        // Reposition pixels
        if (cc == "tl" || cc == "bl") {
          pixelBar.style.left = (specRadius - pixelBarLeft - 1) + "px"; // Left
        }
        if (cc == "tr" || cc == "tl"){
          pixelBar.style.top =  (specRadius - pixelBarHeight - pixelBarTop) + "px"; // Top
        }
        pixelBar.style.backgroundRepeat = this.backgroundRepeat;

        if (this.backgroundImage) switch(cc) {
          case "tr":
            pixelBar.style.backgroundPosition = (this.backgroundPosX - this.borderWidthL + specRadius - clientWidth - pixelBarLeft) + "px " + (this.backgroundPosY + pixelBarHeight + pixelBarTop + this.borderWidth - specRadius) + "px";
          break;
          case "tl":
            pixelBar.style.backgroundPosition = (this.backgroundPosX - specRadius + pixelBarLeft + 1 + this.borderWidthL) + "px " + (this.backgroundPosY - specRadius + pixelBarHeight + pixelBarTop + this.borderWidth) + "px";
          break;
          case "bl":
            pixelBar.style.backgroundPosition = (this.backgroundPosX - specRadius + pixelBarLeft + 1 + this.borderWidthL) + "px " + (this.backgroundPosY - clientHeight - this.borderWidth + (curvyBrowser.quirksMode ? pixelBarTop : -pixelBarTop) + specRadius) + "px";
          break;
          case "br":
            if (curvyBrowser.quirksMode) {
              pixelBar.style.backgroundPosition = (this.backgroundPosX - this.borderWidthL - clientWidth + specRadius - pixelBarLeft) + "px " + (this.backgroundPosY - clientHeight - this.borderWidth + pixelBarTop + specRadius) + "px";
            } else {
              pixelBar.style.backgroundPosition = (this.backgroundPosX - this.borderWidthL - clientWidth + specRadius - pixelBarLeft) + "px " + (this.backgroundPosY - clientHeight - this.borderWidth + specRadius - pixelBarTop) + "px";
            }
          //break;
        }
      }

      // Position the container
      switch (cc) {
        case "tl":
          newCorner.style.top = newCorner.style.left = "0";
          this.topContainer.appendChild(newCorner);
        break;
        case "tr":
          newCorner.style.top = newCorner.style.right = "0";
          this.topContainer.appendChild(newCorner);
        break;
        case "bl":
          newCorner.style.bottom = newCorner.style.left = "0";
          this.bottomContainer.appendChild(newCorner);
        break;
        case "br":
          newCorner.style.bottom = newCorner.style.right = "0";
          this.bottomContainer.appendChild(newCorner);
        //break;
      }
    }

    /*
      The last thing to do is draw the rest of the filler DIVs.
    */

    // Find out which corner has the bigger radius and get the difference amount
    var radiusDiff = {
      t : this.spec.radiusdiff('t'),
      b : this.spec.radiusdiff('b')
    };

    for (var z in radiusDiff) {
      if (typeof z === 'function') continue; // for prototype, mootools frameworks
      if (!this.spec.get(z + 'R')) continue; // no need if no corners
      if (radiusDiff[z]) {
        // Get the type of corner that is the smaller one
        var smallerCornerType = (this.spec[z + "lR"] < this.spec[z + "rR"]) ? z + "l" : z + "r";

        // First we need to create a DIV for the space under the smaller corner
        var newFiller = document.createElement("div");
        newFiller.style.height = radiusDiff[z] + "px";
        newFiller.style.width  =  this.spec.get(smallerCornerType + 'Ru');
        newFiller.style.position = "absolute";
        newFiller.style.fontSize = "1px";
        newFiller.style.overflow = "hidden";
        newFiller.style.backgroundColor = this.boxColour;
        if (filter) newFiller.style.filter = filter; // IE8 bug fix
        // Set background image with original features
        newFiller.style.backgroundImage = this.backgroundImage;
        newFiller.style.backgroundRepeat = this.backgroundRepeat;

        // Position filler
        switch (smallerCornerType) {
          case "tl":
            newFiller.style.bottom =
            newFiller.style.left   = "0";
            newFiller.style.borderLeft = this.borderStringL;
            // Set background image in original position
            newFiller.style.backgroundPosition = this.backgroundPosX + "px " + (this.borderWidth + this.backgroundPosY - this.spec.tlR) + "px";
            this.topContainer.appendChild(newFiller);
          break;
          case "tr":
            newFiller.style.bottom =
            newFiller.style.right  = "0";
            newFiller.style.borderRight = this.borderStringR;
            // Set background image in original position
            newFiller.style.backgroundPosition = (this.backgroundPosX - this.boxWidth + this.spec.trR) + "px " + (this.borderWidth + this.backgroundPosY - this.spec.trR) + "px";
            this.topContainer.appendChild(newFiller);
          break;
          case "bl":
            newFiller.style.top    =
            newFiller.style.left   = "0";
            newFiller.style.borderLeft = this.borderStringL;
            // Set background image in original position
            newFiller.style.backgroundPosition = this.backgroundPosX + "px " + (this.backgroundPosY - this.borderWidth - this.boxHeight + radiusDiff[z] + this.spec.blR) + "px";
            this.bottomContainer.appendChild(newFiller);
          break;
          case "br":
            newFiller.style.top    =
            newFiller.style.right  = "0";
            newFiller.style.borderRight = this.borderStringR;
            // Set background image in original position.
            newFiller.style.backgroundPosition = (this.borderWidthL + this.backgroundPosX - this.boxWidth + this.spec.brR) + "px " + (this.backgroundPosY - this.borderWidth - this.boxHeight + radiusDiff[z] + this.spec.brR) + "px";
            this.bottomContainer.appendChild(newFiller);
          //break;
        }
      }

      // Create the bar to fill the gap between each corner horizontally
      var newFillerBar = document.createElement("div");
      if (filter) newFillerBar.style.filter = filter; // IE8 bug fix
      newFillerBar.style.position = "relative";
      newFillerBar.style.fontSize = "1px";
      newFillerBar.style.overflow = "hidden";
      newFillerBar.style.width = this.fillerWidth(z);
      newFillerBar.style.backgroundColor = this.boxColour;
      newFillerBar.style.backgroundImage = this.backgroundImage;
      newFillerBar.style.backgroundRepeat= this.backgroundRepeat;

      switch (z) {
        case "t":
          // Top Bar
          if (this.topContainer) {
            if (curvyBrowser.quirksMode) {
              newFillerBar.style.height = 100 + topMaxRadius + "px";
            } else {
              newFillerBar.style.height = 100 + topMaxRadius - this.borderWidth + "px";
            }
            newFillerBar.style.marginLeft  = this.spec.tlR ? (this.spec.tlR - this.borderWidthL) + "px" : "0";
            newFillerBar.style.borderTop   = this.borderString;
            if (this.backgroundImage) {
              var x_offset = this.spec.tlR ?
                (this.borderWidthL + this.backgroundPosX - this.spec.tlR) + "px " : this.backgroundPosX + "px ";
              newFillerBar.style.backgroundPosition  = x_offset + this.backgroundPosY + "px";
              // Reposition the box's background image
              this.shell.style.backgroundPosition = this.backgroundPosX + "px " + (this.backgroundPosY - topMaxRadius + this.borderWidthL) + "px";
            }
            this.topContainer.appendChild(newFillerBar);
          }
        break;
        case "b":
          if (this.bottomContainer) {
            // Bottom Bar
            if (curvyBrowser.quirksMode) {
              newFillerBar.style.height     = botMaxRadius + "px";
            } else {
              newFillerBar.style.height     = botMaxRadius - this.borderWidthB + "px";
            }
            newFillerBar.style.marginLeft   = this.spec.blR ? (this.spec.blR - this.borderWidthL) + "px" : "0";
            newFillerBar.style.borderBottom = this.borderStringB;
            if (this.backgroundImage) {
              var x_offset = this.spec.blR ?
                (this.backgroundPosX + this.borderWidthL - this.spec.blR) + "px " : this.backgroundPosX + "px ";
              newFillerBar.style.backgroundPosition = x_offset + (this.backgroundPosY - clientHeight - this.borderWidth + botMaxRadius) + "px";
            }
            this.bottomContainer.appendChild(newFillerBar);
          }
        //break;
      }
    }

    // style content container
    this.contentContainer.style.position = "absolute";
    // contentContainer.style.border = "1px dotted #000"; // DEBUG, comment for production
    this.contentContainer.className    = "autoPadDiv";
    this.contentContainer.style.left   = this.borderWidthL + "px";
    // Get padding amounts
    // Apply top padding
    this.contentContainer.style.paddingTop = this.topPadding + "px";
    this.contentContainer.style.top = this.borderWidth + "px";
    // skip bottom padding - it doesn't show!
    // Apply left and right padding
    this.contentContainer.style.paddingLeft = this.leftPadding + "px";
    this.contentContainer.style.paddingRight = this.rightPadding + "px";
    z = clientWidth;
    if (!curvyBrowser.quirksMode) z -= this.leftPadding + this.rightPadding;
    this.contentContainer.style.width = z + "px";
    this.contentContainer.style.textAlign = curvyBrowser.get_style(this.box, 'textAlign');
    this.box.style.textAlign = 'left'; // important otherwise layout goes wild

    this.box.appendChild(this.contentContainer);
    if (boxDisp) boxDisp.style.display = boxDispSave;
  };
  if (this.backgroundImage) {
    backgroundPosX = this.backgroundCheck(backgroundPosX);
    backgroundPosY = this.backgroundCheck(backgroundPosY);
    if (this.backgroundObject) {
      this.backgroundObject.holdingElement = this;
      this.dispatch = this.applyCorners;
      this.applyCorners = function() {
        if (this.backgroundObject.complete)
          this.dispatch();
        else this.backgroundObject.onload = new Function('curvyObject.dispatch(this.holdingElement);');
      };
    }
  }
}

curvyObject.prototype.backgroundCheck = function(style) {
  if (style === 'top' || style === 'left' || parseInt(style) === 0) return 0;
  if (!(/^[-\d.]+px$/.test(style))  && !this.backgroundObject) {
    this.backgroundObject = new Image;
    var imgName = function(str) {
      var matches = /url\("?([^'"]+)"?\)/.exec(str);
      return (matches ? matches[1] : str);
    };
    this.backgroundObject.src = imgName(this.backgroundImage);
  }
  return style;
};

curvyObject.dispatch = function(obj) {
  if ('dispatch' in obj)
    obj.dispatch();
  else throw obj.newError('No dispatch function');
};

// append a pixel DIV to newCorner

curvyObject.prototype.drawPixel = function(intx, inty, colour, transAmount, height, newCorner, image, cornerRadius) {
  var pixel = document.createElement("div");
  pixel.style.height   = height + "px";
  pixel.style.width    = "1px";
  pixel.style.position = "absolute";
  pixel.style.fontSize = "1px";
  pixel.style.overflow = "hidden";
  var topMaxRadius = this.spec.get('tR');
  pixel.style.backgroundColor = colour;
  // Don't apply background image to border pixels
  if (image && this.backgroundImage !== "") {
    pixel.style.backgroundImage = this.backgroundImage;
    pixel.style.backgroundPosition  = "-" + (this.boxWidth - (cornerRadius - intx) + this.borderWidth) + "px -" + ((this.boxHeight + topMaxRadius + inty) - this.borderWidth) + "px";
  }
  // Set opacity if the transparency is anything other than 100
  if (transAmount != 100) curvyObject.setOpacity(pixel, transAmount);
  // Set position
  pixel.style.top = inty + "px";
  pixel.style.left = intx + "px";
  newCorner.appendChild(pixel);
};

curvyObject.prototype.fillerWidth = function(tb) {
  var b_width, f_width;
  b_width = curvyBrowser.quirksMode ? 0 : this.spec.radiusCount(tb) * this.borderWidthL;
  if ((f_width = this.boxWidth - this.spec.radiusSum(tb) + b_width) < 0)
    throw this.newError("Radius exceeds box width");
  return f_width + 'px';
};

curvyObject.prototype.errmsg = function(msg, gravity) {
  var extradata = "\ntag: " + this.box.tagName;
  if (this.box.id) extradata += "\nid: " + this.box.id;
  if (this.box.className) extradata += "\nclass: " + this.box.className;
  var parent;
  if ((parent = this.box.parentNode) === null)
    extradata += "\n(box has no parent)";
  else {
    extradata += "\nParent tag: " + parent.tagName;
    if (parent.id) extradata += "\nParent ID: " + parent.id;
    if (parent.className) extradata += "\nParent class: " + parent.className;
  }
  if (gravity === undefined) gravity = 'warning';
  return 'curvyObject ' + gravity + ":\n" + msg + extradata;
};

curvyObject.prototype.newError = function(msg) {
  return new Error(this.errmsg(msg, 'exception'));
};

// ------------- UTILITY FUNCTIONS

//  Convert a number 0..255 to hex


curvyObject.IntToHex = function(strNum) {
  var hexdig = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' ];

  return hexdig[strNum >>> 4] + '' + hexdig[strNum & 15];
};

/*
  Blends the two colours by the fraction
  returns the resulting colour as a string in the format "#FFFFFF"
*/

curvyObject.BlendColour = function(Col1, Col2, Col1Fraction) {
  if (Col1 === 'transparent' || Col2 === 'transparent') throw this.newError('Cannot blend with transparent');
  if (Col1.charAt(0) !== '#') {
    //curvyCorners.alert('Found colour1 ' + Col1 + ': please let us know you saw this report.');
    Col1 = curvyObject.format_colour(Col1);
  }
  if (Col2.charAt(0) !== '#') {
    //curvyCorners.alert('Found colour2 ' + Col2 + ': please let us know you saw this report.');
    Col2 = curvyObject.format_colour(Col2);
  }
  var red1 = parseInt(Col1.substr(1, 2), 16);
  var green1 = parseInt(Col1.substr(3, 2), 16);
  var blue1 = parseInt(Col1.substr(5, 2), 16);
  var red2 = parseInt(Col2.substr(1, 2), 16);
  var green2 = parseInt(Col2.substr(3, 2), 16);
  var blue2 = parseInt(Col2.substr(5, 2), 16);

  if (Col1Fraction > 1 || Col1Fraction < 0) Col1Fraction = 1;

  var endRed = Math.round((red1 * Col1Fraction) + (red2 * (1 - Col1Fraction)));
  if (endRed > 255) endRed = 255;
  if (endRed < 0) endRed = 0;

  var endGreen = Math.round((green1 * Col1Fraction) + (green2 * (1 - Col1Fraction)));
  if (endGreen > 255) endGreen = 255;
  if (endGreen < 0) endGreen = 0;

  var endBlue = Math.round((blue1 * Col1Fraction) + (blue2 * (1 - Col1Fraction)));
  if (endBlue > 255) endBlue = 255;
  if (endBlue < 0) endBlue = 0;

  return "#" + curvyObject.IntToHex(endRed) + curvyObject.IntToHex(endGreen)+ curvyObject.IntToHex(endBlue);
};

/*
  For a pixel cut by the line determines the fraction of the pixel on the 'inside' of the
  line.  Returns a number between 0 and 1
*/

curvyObject.pixelFraction = function(x, y, r) {
  var fraction;
  var rsquared = r * r;

  /*
    determine the co-ordinates of the two points on the perimeter of the pixel that the
    circle crosses
  */
  var xvalues = new Array(2);
  var yvalues = new Array(2);
  var point = 0;
  var whatsides = "";

  // x + 0 = Left
  var intersect = Math.sqrt(rsquared - Math.pow(x, 2));

  if (intersect >= y && intersect < (y + 1)) {
    whatsides = "Left";
    xvalues[point] = 0;
    yvalues[point] = intersect - y;
    ++point;
  }
  // y + 1 = Top
  intersect = Math.sqrt(rsquared - Math.pow(y + 1, 2));

  if (intersect >= x && intersect < (x + 1)) {
    whatsides += "Top";
    xvalues[point] = intersect - x;
    yvalues[point] = 1;
    ++point;
  }
  // x + 1 = Right
  intersect = Math.sqrt(rsquared - Math.pow(x + 1, 2));

  if (intersect >= y && intersect < (y + 1)) {
    whatsides += "Right";
    xvalues[point] = 1;
    yvalues[point] = intersect - y;
    ++point;
  }
  // y + 0 = Bottom
  intersect = Math.sqrt(rsquared - Math.pow(y, 2));

  if (intersect >= x && intersect < (x + 1)) {
    whatsides += "Bottom";
    xvalues[point] = intersect - x;
    yvalues[point] = 0;
  }

  /*
    depending on which sides of the perimeter of the pixel the circle crosses calculate the
    fraction of the pixel inside the circle
  */
  switch (whatsides) {
    case "LeftRight":
      fraction = Math.min(yvalues[0], yvalues[1]) + ((Math.max(yvalues[0], yvalues[1]) - Math.min(yvalues[0], yvalues[1])) / 2);
    break;

    case "TopRight":
      fraction = 1 - (((1 - xvalues[0]) * (1 - yvalues[1])) / 2);
    break;

    case "TopBottom":
      fraction = Math.min(xvalues[0], xvalues[1]) + ((Math.max(xvalues[0], xvalues[1]) - Math.min(xvalues[0], xvalues[1])) / 2);
    break;

    case "LeftBottom":
      fraction = yvalues[0] * xvalues[1] / 2;
    break;

    default:
      fraction = 1;
  }

  return fraction;
};

// Returns an array of rgb values

curvyObject.rgb2Array = function(rgbColour) {
  // Remove rgb()
  var rgbValues = rgbColour.substring(4, rgbColour.indexOf(")"));

  // Split RGB into array
  return rgbValues.split(/,\s*/);
};

// This function converts CSS rgb(x, x, x) to hexadecimal

curvyObject.rgb2Hex = function(rgbColour) {
  try {
    // Get array of RGB values
    var rgbArray = curvyObject.rgb2Array(rgbColour);

    // Get RGB values
    var red   = parseInt(rgbArray[0]);
    var green = parseInt(rgbArray[1]);
    var blue  = parseInt(rgbArray[2]);

    // Build hex colour code
    var hexColour = "#" + curvyObject.IntToHex(red) + curvyObject.IntToHex(green) + curvyObject.IntToHex(blue);
  }
  catch (e) {
    var msg = 'getMessage' in e ? e.getMessage() : e.message;
    throw new Error("Error (" + msg + ") converting RGB value to Hex in rgb2Hex");
  }

  return hexColour;
};

/*
  Function by Simon Willison from sitepoint.com
  Modified by Cameron Cooke adding Safari's rgba support
*/

curvyObject.setOpacity = function(obj, opacity) {
  opacity = (opacity == 100) ? 99.999 : opacity;

  if (curvyBrowser.isSafari && obj.tagName != "IFRAME") {
    // Get array of RGB values
    var rgbArray = curvyObject.rgb2Array(obj.style.backgroundColor);

    // Get RGB values
    var red   = parseInt(rgbArray[0]);
    var green = parseInt(rgbArray[1]);
    var blue  = parseInt(rgbArray[2]);

    // Safari using RGBA support
    obj.style.backgroundColor = "rgba(" + red + ", " + green + ", " + blue + ", " + opacity/100 + ")";
  }
  else if (typeof obj.style.opacity !== "undefined") { // W3C
    obj.style.opacity = opacity / 100;
  }
  else if (typeof obj.style.MozOpacity !== "undefined") { // Older Mozilla
    obj.style.MozOpacity = opacity / 100;
  }
  else if (typeof obj.style.filter !== "undefined") { // IE
    obj.style.filter = "alpha(opacity=" + opacity + ")";
  }
  else if (typeof obj.style.KHTMLOpacity !== "undefined") { // Older KHTML-based browsers
    obj.style.KHTMLOpacity = opacity / 100;
  }
};


// Cross browser add event wrapper

curvyCorners.addEvent = function(elm, evType, fn, useCapture) {
  if (elm.addEventListener) {
    elm.addEventListener(evType, fn, useCapture);
    return true;
  }
  if (elm.attachEvent) return elm.attachEvent('on' + evType, fn);
  elm['on' + evType] = fn;
  return false;
};
if (typeof addEvent === 'undefined') addEvent = curvyCorners.addEvent; // only if necessary

// Gets the computed colour.
curvyObject.getComputedColour = function(colour) {
  var d = document.createElement('DIV');
  d.style.backgroundColor = colour;
  document.body.appendChild(d);

  if (window.getComputedStyle) { // Mozilla, Opera, Chrome, Safari
    var rtn = document.defaultView.getComputedStyle(d, null).getPropertyValue('background-color');
    d.parentNode.removeChild(d);
    if (rtn.substr(0, 3) === "rgb") rtn = curvyObject.rgb2Hex(rtn);
    return rtn;
  }
  else { // IE
    var rng = document.body.createTextRange();
    rng.moveToElementText(d);
    rng.execCommand('ForeColor', false, colour);
    var iClr = rng.queryCommandValue('ForeColor');
    var rgb = "rgb("+(iClr & 0xFF)+", "+((iClr & 0xFF00)>>8)+", "+((iClr & 0xFF0000)>>16)+")";
    d.parentNode.removeChild(d);
    rng = null;
    return curvyObject.rgb2Hex(rgb);
  }
};

// convert colour name, rgb() and #RGB to #RRGGBB
curvyObject.format_colour = function(colour) {
  // Make sure colour is set and not transparent
  if (colour !== "" && colour !== "transparent") {
    // RGB Value?
    if (colour.substr(0, 3) === "rgb") {
      // Get HEX aquiv.
      colour = curvyObject.rgb2Hex(colour);
    }
    else if (colour.charAt(0) !== '#') {
      // Convert colour name to hex value
      colour = curvyObject.getComputedColour(colour);
    }
    else if (colour.length === 4) {
      // 3 chr colour code add remainder
      colour = "#" + colour.charAt(1) + colour.charAt(1) + colour.charAt(2) + colour.charAt(2) + colour.charAt(3) + colour.charAt(3);
    }
  }
  return colour;
};

// Get elements by class by Dustin Diaz / CPKS
// NB if searchClass is a class name, it MUST be preceded by '.'

curvyCorners.getElementsByClass = function(searchClass, node) {
  var classElements = new Array;
  if (node === undefined) node = document;
  searchClass = searchClass.split('.'); // see if there's a tag in there
  var tag = '*'; // prepare for no tag
  if (searchClass.length === 1) {
    tag = searchClass[0];
    searchClass = false;
  }
  else {
    if (searchClass[0]) tag = searchClass[0];
    searchClass = searchClass[1];
  }
  var i, els, elsLen;
  if (tag.charAt(0) === '#') {
    els = document.getElementById(tag.substr(1));
    if (els) classElements.push(els);
  }
  else {
    els = node.getElementsByTagName(tag);
    elsLen = els.length;
    if (searchClass) {
      var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
      for (i = 0; i < elsLen; ++i) {
        if (pattern.test(els[i].className)) classElements.push(els[i]);
      }
    }
    else for (i = 0; i < elsLen; ++i) classElements.push(els[i]);
  }
  return classElements;
};

curvyCorners.getElementsBySelector = function(selectors, parent) {
  var ret;
  var sel = selectors[0];
  if (parent === undefined) parent = document;
  if (sel.indexOf('#') === -1)
    ret = curvyCorners.getElementsByClass(sel, parent);
  else {
    var t = parent.getElementById(sel.substr(1));
    if (!t) return [];
    ret = [t];
  }
  if (selectors.length > 1) {
    var subret = [];
    for (var i = ret.length; --i >= 0; )
      subret = subret.concat(curvyCorners.getElementsBySelector(selectors.slice(1), ret[i]));
    ret = subret;
  }
  return ret;
};

if (curvyBrowser.supportsCorners) {
  var curvyCornersNoAutoScan = true; // it won't do anything anyway.
  curvyCorners.init = function() {}; // make it harmless
}
else {

  // autoscan code

  curvyCorners.scanStyles = function() {
    function units(num) {
      if (!parseInt(num)) return 'px'; // '0' becomes '0px' for simplicity's sake
      var matches = /^[\d.]+(\w+)$/.exec(num);
      return matches[1];
    }
    var t, i, j;

    if (curvyBrowser.isIE) {
      function procIEStyles(rule) {
        var style = rule.style, allR, tR, tL, bR, bL;

        if (curvyBrowser.ieVer > 6.0) {
          allR = style['-moz-border-radius'] || 0;
          tR   = style['-moz-border-radius-topright'] || 0;
          tL   = style['-moz-border-radius-topleft'] || 0;
          bR   = style['-moz-border-radius-bottomright'] || 0;
          bL   = style['-moz-border-radius-bottomleft'] || 0;
        }
        else {
          allR = style['moz-border-radius'] || 0;
          tR   = style['moz-border-radius-topright'] || 0;
          tL   = style['moz-border-radius-topleft'] || 0;
          bR   = style['moz-border-radius-bottomright'] || 0;
          bL   = style['moz-border-radius-bottomleft'] || 0;
        }
        if (allR) {
          var t = allR.split('/'); // ignore elliptical spec.
          t = t[0].split(/\s+/);
          if (t[t.length - 1] === '') t.pop();
          switch (t.length) {
            case 3:
              tL = t[0];
              tR = bL = t[1];
              bR = t[2];
              allR = false;
            break;
            case 2:
              tL = bR = t[0];
              tR = bL = t[1];
              allR = false;
            case 1:
            break;
            case 4:
              tL = t[0];
              tR = t[1];
              bR = t[2];
              bL = t[3];
              allR = false;
            break;
            default:
              curvyCorners.alert('Illegal corners specification: ' + allR);
            //break;
          }
        }
        if (allR || tL || tR || bR || bL) {
          var settings = new curvyCnrSpec(rule.selectorText);
          if (allR)
            settings.setcorner(null, null, parseInt(allR), units(allR));
          else {
            if (tR) settings.setcorner('t', 'r', parseInt(tR), units(tR));
            if (tL) settings.setcorner('t', 'l', parseInt(tL), units(tL));
            if (bL) settings.setcorner('b', 'l', parseInt(bL), units(bL));
            if (bR) settings.setcorner('b', 'r', parseInt(bR), units(bR));
          }
          curvyCorners(settings);
        }
      }
      for (t = 0; t < document.styleSheets.length; ++t) {
        try {
          if (document.styleSheets[t].imports) {
            for (i = 0; i < document.styleSheets[t].imports.length; ++i)
              for (j = 0; j < document.styleSheets[t].imports[i].rules.length; ++j)
                procIEStyles(document.styleSheets[t].imports[i].rules[j]);
          }
          for (i = 0; i < document.styleSheets[t].rules.length; ++i)
            procIEStyles(document.styleSheets[t].rules[i]);
        }
        catch (e) {
          if (typeof curvyCornersVerbose !== 'undefined' && curvyCornersVerbose)
            alert(e.message + " - ignored");
        } // catch but ignore any permission error
      }
    }
    else if (curvyBrowser.isOp) {
      for (t = 0; t < document.styleSheets.length; ++t) {
        if (operasheet.contains_border_radius(t)) {
          j = new operasheet(t);
          for (i in j.rules) if (!isNaN(i))
            curvyCorners(j.rules[i]);
        }
      }
    }
    else curvyCorners.alert('Scanstyles does nothing in Webkit/Firefox/Opera');
  };

  // Dean Edwards/Matthias Miller/John Resig

  curvyCorners.init = function() {
    // quit if this function has already been called
    if (arguments.callee.done) return;

    // flag this function so we don't do the same thing twice
    arguments.callee.done = true;

    // kill the timer
    if (curvyBrowser.isWebKit && curvyCorners.init.timer) {
      clearInterval(curvyCorners.init.timer);
      curvyCorners.init.timer = null;
    }

    // do stuff
    curvyCorners.scanStyles();
  };
}

if (typeof curvyCornersNoAutoScan === 'undefined' || curvyCornersNoAutoScan === false) {
  if (curvyBrowser.isOp)
    document.addEventListener("DOMContentLoaded", curvyCorners.init, false);
  else curvyCorners.addEvent(window, 'load', curvyCorners.init, false);
};

