/// <reference path="../../prototype/1.6.1.0/prototype.js" />

var $Body;
var $Head;

var undefined;
var debug = false;

var Seips = {
	version: "3.5c",
	queryParams: null,
	SetCookie: function (cookieName, value, isSession) {

		if (!isSession) {
			var date = new Date(2010, 12, 31);
			document.cookie = cookieName + "=" + escape(value) + ";path=/;expires=" + date.toGMTString();
		} else {
			document.cookie = cookieName + "=" + escape(value) + ";path=/";
		}
	},
	GetCookie: function (cookieName) {
		var aCookie = document.cookie.split(";");
		for (var i = 0; i < aCookie.length; i++) {
			var aCrumb = aCookie[i].split("=");
			if (aCrumb[0].replace(" ", "") == cookieName)
				return unescape(aCrumb[1]);
		}
		return null;
	},
	LoadScript: function (sname, fname, callback) {
		sname = "js" + sname;
		if ($(sname)) { // Already exists
			return;
		}
		var script = new Element("script", {
			id: sname,
			type: "text/javascript",
			src: fname
		});
		$Head.appendChild(script);
		if (callback != null) {
			script.onload = function () { callback(); };
			script.onreadystatechange = function () { callback(); };
		}
	}
};

Seips.Basic = {
	initialize: function () {
		// parse queryParams for reuse
		Seips.queryParams = location.search.toQueryParams();

		// hide empty columns
		Seips.Basic.columnsFix();

		// watermarks in textboxes
		Seips.Basic.Watermarks();

		// Set debug mode cookie if ? parameter present
		if (Seips.queryParams.debug != undefined) {
			Seips.SetCookie("Debug", Seips.queryParams.debug, true);
		}

		// Set Ajax default handlers
		Seips.Basic.setUpAjaxDefaults();

		// Create an AjaxStatusIndicator panel for UI notifications
		Seips.Basic.StatusIndicator.create();
		// Create an AlertBox panel for UI error notifications.
		Seips.Basic.AlertBox.create();

		// read debug mode from cookie
		if (Seips.GetCookie("Debug") != null) {
			debug = (Seips.GetCookie("Debug") == "true");
		}

		// IE 6 fix - runs out of order
		if ($Body == undefined || $Body == null) {
			$Body = $(document.body).addClassName("loaded");
			$Head = $(document.body.previousSibling);
			Seips.Zoom.initialize();
			Seips.MainValidator = new Seips.Validation("aspnetForm");
		}
		if ($("currentDate") != null) {
			$("currentDate").update((new Date()).format("EE, MMM d, yyyy"));
		}
		// add calendars
		$$("div.fBlock input.Calendar").each(function (el) {
			el.picker = new Control.DatePicker(el, { icon: '/RootImg/ic/calendar.png', locale: 'en_GB' });
		});
		$$("div.fBlock input.TimeCalendar").each(function (el) {
			el.picker = new Control.DatePicker(el, { icon: '/RootImg/ic/calendar.png', locale: 'en_GB', timePicker: true, timePickerAdjacent: true });
		});

		// zebra stripe tables
		$$('table.Zebra tr:nth-child(odd)').invoke("addClassName", "alt");

		// IE fix add console object
		if (typeof console == "undefined" || console == null) {
			console = {
				log: function (msg) { if (debug) alert(msg); }
			}
		}

		if (location.hash != "") {
			var el = $(location.hash.substring(1));
			if (el != null)
				el.addClassName("navtarget");
		}

		// Initialise embedded youtube anchors
		var prototubeOptions = {
			overlay: true,
			imagePreview: true,
			playerWidth: 425,
			playerHeight: 350,
			fs:1,
			hd: 0,
			showinfo: 0
		};
		$$("a[href^=http://www.youtube.com/v]").each(function (a) {
			new ProtoTube(a, prototubeOptions);
		});
		$$("a[href^=http://www.youtube.com/watch?v]").each(function (a) {
			new ProtoTube(a, prototubeOptions);
		});
	},
	columnsFix: function () {
		// first get rid of any Whitespace only nodes.
		$("body1").cleanWhitespace();
		$("body3").cleanWhitespace();

		// hide left or right columns if they have no remaining children
		if ($("body1").descendants().length == 0)
			$("body1").hide();
		if ($("body3").descendants().length == 0)
			$("body3").hide();
	},
	Watermarks: function () {
		// watermarks
		$$('input[type=text]').each(function (el) {
			var watermark = (el.hasAttribute("data-watermark")) ? el.getAttribute("data-watermark") : "";
			if (watermark != "") {
				if (el.value == '' || el.value == watermark) {
					el.value = watermark;
					el.addClassName("watermark");
				}
				el.observe("focus", Seips.Basic.FocusTextbox);
				el.observe("blur", Seips.Basic.BlurTextbox);
			}
		});
	},
	FocusTextbox: function (evt) {
		var el = $(evt.element());
		var watermark = (el.hasAttribute("data-watermark")) ? el.getAttribute("data-watermark") : "";
		if (el.value == watermark) {
			el.value = "";
			el.removeClassName("watermark");
		}
		el.select();
	},
	BlurTextbox: function (evt) {
		var el = $(evt.element());
		var watermark = (el.hasAttribute("data-watermark")) ? el.getAttribute("data-watermark") : "";
		if (el.value == "") {
			el.value = watermark;
			el.addClassName("watermark");
		}
	},
	setUpAjaxDefaults: function () {
		// Set up a global AJAX Exception handler (outputs to Firebug console)
		Ajax.Responders.register({
			onCreate: function (instance, xhrObj) {
				// update status indicator to show new call
				Seips.Basic.StatusIndicator.show(instance.url);
				// log to developer console
				console.log(instance.url, " - started");
			},
			onComplete: function (instance, xhrObj, jsonResult) {
				// remove status indicator for finished call
				Seips.Basic.StatusIndicator.hide(instance.url);
				// log to developer console
				console.log(instance, " - ", instance.url, " - complete");
				var errorCode = xhrObj.getHeader("X-Ajax-Error");
				if (errorCode != null) {
					Seips.Basic.AlertBox.show((errorCode == "-1") ? "An unrecordable error occurred." : "Please report error id: " + errorCode + " and details of what you were doing when the error occurred to the WP technical helpdesk (x????)", errorCode);
					console.log(instance.url, " - error code - ", errorCode);
				}
			},
			onException: function (instance, excObj, json) {
				// log exception to developer console.
				// TODO: some sort of error handling / failure alert for ordinary users
				if (typeof console == "object") {
					console.log("AJAX Exception");
					console.log(instance, excObj, json);
				} else
					Seips.ConfirmDialog.show("Ajax error: ", excObj);
			},
			onFailure: function () {
				Seips.ConfirmDialog.show("Error", "An unrecognised Ajax error occurred.");
				// log failure to developer console.
				// TODO: some sort of error handling / failure alert for ordinary users
				//				if (typeof console == "object")
				//				//					console.log("Ajax request failed. Args = %o ", arguments);
				//				//				else
				//					alert("Ajax request has failed.");
			}
		});
	},
	StatusIndicator: {
		create: function () {
			var html = new Element("div", { "id": "AjaxStatusPanel" }).update("<h3>Waiting for...</h3><p><img src='/RootImg/seips/progressdisc.gif' alt='Waiting...' title='Waiting for data' /></p><ul></ul>").hide();
			$("aspnetForm").insert({ after: html });
		},
		show: function (url) {
			var ul = $("AjaxStatusPanel").down("ul");
			$("AjaxStatusPanel").show();
			var fname = Seips.Basic.StatusIndicator.getFname(url);
			var li = new Element("li", { "id": "asp_" + fname }).update(fname);
			ul.insert(li);
		},
		hide: function (url) {
			var ul = $("AjaxStatusPanel").down("ul");
			var fname = Seips.Basic.StatusIndicator.getFname(url);
			$("asp_" + fname).remove();
			if ($("AjaxStatusPanel").down("ul").childElements().length == 0) {
				$("AjaxStatusPanel").hide();
			}
		},
		getFname: function (url) {
			var parts = url.split("/");
			var fname = parts[parts.length - 1];
			return fname.split(".")[0];
		}
	},
	AlertBox: {
		active: false,
		create: function (msg) {
			var html = new Element("div", { "id": "AjaxErrorPanel" }).update("<div class='Mask'><!-- --></div><div class='content'><h3><a href='#close' title='close'>close</a>Error...</h3><p></p></div>").hide();
			$("aspnetForm").insert({ after: html });
			$("AjaxErrorPanel").down("a").observe("click", Seips.Basic.AlertBox.hide);
		},
		show: function (msg, errorCode) {
			$("AjaxErrorPanel").down("p").update(msg);
			$("AjaxErrorPanel").show();
			console.log("error: ", msg);
		},
		hide: function (evt) {
			evt.stop();
			$("AjaxErrorPanel").hide();
		}
	}
};

Seips.ConfirmDialog = {
	active: false,
	callback: null,
	width: 400,
	initialize: function () {
		if ($("S3Alert") == null) {
			var html = new Element("div", { "id": "S3Alert" }).update("<div class='Mask'><!-- --></div><div class='window'><div class='header'><h3><span>Title</span><a href='#close' title='close'>x</a></h3></div><div class='contents'><div class='msg'>Message</div><p class='bigButtons'><input type='button' id='S3AlertOK' class='ClickOnce' value='OK' /> <input type='button' id='S3AlertCancel' class='ClickOnce' value='Cancel' /></p></div></div>").hide();
			$("aspnetForm").insert({ after: html });
			$("S3Alert").down("h3 a").observe("click", Seips.ConfirmDialog.hide);
			$("S3Alert").select("input.ClickOnce").invoke("observe", "click", Seips.ConfirmDialog.hide);
		}
	},
	show: function (title, msg, fadeOut, okCallback, showCancel) {
		$("S3Alert").down("h3 span").update(title);
		$("S3Alert").down("div.msg").update(msg);
		$("S3Alert").down("div.window").setStyle({ left: Math.round((Element.getWidth(document.body) - Seips.ConfirmDialog.width) / 2) + "px" });
		$("S3Alert").show();
		if (showCancel)
			$("S3AlertCancel").show();
		else
			$("S3AlertCancel").hide();
		Seips.ConfirmDialog.callback = okCallback;
	},
	hide: function (evt) {
		evt.stop();
		var el = evt.element();
		$("S3Alert").hide();
		if (el.id == "S3AlertOK" && Seips.ConfirmDialog.callback != null)
			Seips.ConfirmDialog.callback();
	}
}

Seips.Zoom = {
	curZoom: 100,
	_scales: $A([80, 100, 125, 145]),
	initialize: function () {
		if ($("textResizer") == null) return;
		var first = $("textResizer").update("");
		var _template = new Template("<li id='#{id}'><a href='\#ZoomTo#{scale}Percent' title='Text size #{label}' onclick='return Seips.Zoom.ZoomTo(#{scale});'>A<span class='textOnly'> (#{label})</span></a> </li>");

		first.insert("<li>Text size:</li>");
		[{ scale: 80, label: "small", id: "z1" }, { scale: 100, label: "normal", id: "z2" },
			{ scale: 125, label: "large", id: "z3" }, { scale: 145, label: "largest", id: "z4"}].each(function (li) {
				first.insert(_template.evaluate(li));
			});

		// check if zoom already set.
		if (Seips.GetCookie("selectedZoom") != null) {
			Seips.Zoom.ZoomTo(Seips.GetCookie("selectedZoom"));
		}
	},

	ZoomTo: function (scale) {
		$("aspnetForm").setStyle({ 'fontSize': scale + "%" });
		$R(1, 4).each(function (n) {
			$("z" + n).firstChild.className = "";
		});
		Seips.Zoom.curZoom = scale;

		if (scale == 80) document.getElementById("z1").firstChild.className = "on";
		if (scale == 100) document.getElementById("z2").firstChild.className = "on";
		if (scale == 125) document.getElementById("z3").firstChild.className = "on";
		if (scale == 145) document.getElementById("z4").firstChild.className = "on";

		Seips.SetCookie("selectedZoom", scale, true);

		return false;
	}
};

$(document).observe("dom:loaded", function () { Seips.Basic.initialize(); });

/*
 * Control.DatePicker
 * 
 * Transforms an ordinary input textbox into an interactive date picker.
 * When the textbox is clicked (or the down arrow is pressed), a calendar
 * appears that the user can browse through and select a date.
 *
 * Features:
 *  - Allows user to specify a date format
 *  - Easy to localize
 *  - Customizable by CSS
 *
 * Written and maintained by Jeremy Jongsma (jeremy@jongsma.org)
 */
if (window.Control == undefined) Control = {};

Control.DatePicker = Class.create();
Control.DatePicker.prototype = {
	initialize: function(element, options) {
		this.element = $(element);
		this.i18n = new Control.DatePicker.i18n(options && options.locale ? options.locale : 'en_GB');
		options = this.i18n.inheritOptions(options);
		this.options = Object.extend({
				onClick: this.pickerClicked.bind(this),
				onHover: this.dateHover.bind(this),
				onSelect: this.datePicked.bind(this)
			}, options || {});
		this.options.currentFormat = this.options.timePicker ? this.options.dateTimeFormat : this.options.dateFormat;
		this.options.date = DateFormat.parseFormat(this.element.value, this.options.currentFormat);
		this.datepicker = new Control.DatePickerPanel(this.options);

		this.originalValue = null;
		this.hideTimeout = null;

		if (this.options.icon) {
			this.icon = document.createElement('img');
			this.icon.src = this.options.icon;
			this.icon.title = this.tr('Open calendar');
			this.icon.className = 'inputExtension';
			var topOffset = /MSIE/.test(navigator.userAgent) ? '1px' : '3px';
			Element.setStyle(this.icon, {'position': 'relative', 'left': '-18px', 'top': topOffset});
			Element.insertAfter(this.icon, this.element);
			Event.observe(this.icon, 'click', this.togglePicker.bindAsEventListener(this));
		} else {
			Event.observe(this.element, 'click', this.togglePicker.bindAsEventListener(this));
		}

		this.hidePickerListener = this.delayedHide.bindAsEventListener(this);
		Event.observe(this.element, 'keypress', this.keyHandler.bindAsEventListener(this));
		Event.observe(document, 'keypress', this.docKeyHandler.bindAsEventListener(this));

		this.pickerActive = false;
	},
	tr: function(str) {
		return this.i18n.tr(str);
	},
	delayedHide: function(e) {
		this.hideTimeout = setTimeout(this.hide.bind(this), 100);
	},
	pickerClicked: function() {
		if (this.hideTimeout) {
			clearTimeout(this.hideTimeout);
			this.hideTimeout = null;
		}
	},
	datePicked: function(date) {
		this.element.value = DateFormat.format(date, this.options.currentFormat);
		this.element.focus();
		this.hide();
	},
	dateHover: function(date) {
		if (this.hideTimeout) {
			clearTimeout(this.hideTimeout);
			this.hideTimeout = null;
		}
		if (this.pickerActive)
			this.element.value = DateFormat.format(date, this.options.currentFormat);
	},
	togglePicker: function(e) {
		if (this.pickerActive) {
			this.element.value = this.originalValue;
			this.hide();
		} else {
			this.show();
		}
		Event.stop(e);
		return false;
	},
	docKeyHandler: function(e) {
		if (e.keyCode == Event.KEY_ESC)
			if (this.pickerActive) {
				this.element.value = this.originalValue;
				this.hide();
			}

	},
	keyHandler: function(e) {
		switch (e.keyCode) {
			case Event.KEY_ESC:
				if (this.pickerActive)
					this.element.value = this.originalValue;
			case Event.KEY_TAB:
				this.hide();
				return;
			case Event.KEY_DOWN:	
				if (!this.pickerActive)
					this.show();
		}
		if (this.pickerActive)
			return false;
	},
	hide: function() {
		if(this.pickerActive) {
			this.datepicker.releaseKeys();
			Element.remove(this.datepicker.element);
			Event.stopObserving(document, 'click', this.hidePickerListener, true);
			this.pickerActive = false;
		}
	},
	show: function () {
		if (!this.pickerActive) {
			this.originalValue = this.element.value;
			var pos = Position.cumulativeOffset(this.element);
			var dim = Element.getDimensions(this.element);
			var pickerTop = /MSIE/.test(navigator.userAgent) ? (pos[1] + dim.height) + 'px' : (pos[1] + dim.height - 1) + 'px';
			this.datepicker.element.style.top = pickerTop;
			this.datepicker.element.style.left = pos[0] + 'px';
			this.datepicker.selectDate(DateFormat.parseFormat(this.element.value, this.options.currentFormat));
			this.datepicker.captureKeys();
			document.body.appendChild(this.datepicker.element);
			Event.observe(document, 'click', this.hidePickerListener, true);
			this.pickerActive = true;
			this.pickerClicked();
		}
	}
};

Control.DatePicker.i18n = Class.create();
Object.extend(Control.DatePicker.i18n, {
	baseLocales: {
		'us': {
			dateTimeFormat: 'MM/dd/yyyy HH:mm',
			dateFormat: 'MM/dd/yyyy',
			firstWeekDay: 0,
			weekend: [0,6]
		},
		'eu': {
			dateTimeFormat: 'dd/MM/yyyy HH:mm',
			dateFormat: 'dd/MM/yyyy',
			firstWeekDay: 1,
			weekend: [0,6]
		},
		'iso8601': {
			dateTimeFormat: 'yyyy-MM-dd HH:mm',
			dateFormat: 'yyyy-MM-dd',
			firstWeekDay: 1,
			weekend: [0,6]
		}
	},
	createLocale: function(base, lang) {
		return Object.extend(Object.clone(Control.DatePicker.i18n.baseLocales[base]), {'language': lang});
	}
});
Control.DatePicker.i18n.prototype = {
	initialize: function(code) {
		var lang = code.charAt(2) == '_' ? code.substring(0,2) : code;
		var locale = (Control.DatePicker.Locale[code] || Control.DatePicker.Locale[lang]);
		this.opts = Object.clone(locale || {});
		var language = locale ? Control.DatePicker.Language[locale.language] : null;
		if (language) Object.extend(this.opts, language);
	},
	opts: null,
	inheritOptions: function(options) {
		if (!this.opts) this.setLocale('en_US');
		return Object.extend(this.opts, options || {});
	},
	tr: function(str) {
		return this.opts && this.opts.strings ? this.opts.strings[str] || str : str;
	}
};

Control.DatePicker.Locale = {};
with (Control.DatePicker) {
	// Full locale definitions not needed if countries use the language default format
	// Datepicker will fallback to the language default; i.e. 'es_AR' will use 'es'
	Locale['es'] = i18n.createLocale('eu', 'es');
	Locale['en'] = i18n.createLocale('us', 'en');
	Locale['en_GB'] = i18n.createLocale('eu', 'en');
	Locale['en_AU'] = Locale['en_GB'];
	Locale['de'] = i18n.createLocale('eu', 'de');
	Locale['es_iso8601'] = i18n.createLocale('iso8601', 'es');
	Locale['en_iso8601'] = i18n.createLocale('iso8601', 'en');
	Locale['de_iso8601'] = i18n.createLocale('iso8601', 'de');
}

Control.DatePicker.Language = {
	'es': {
		months: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Augosto', 'Septiembre', 'Octubre', 'Novimbre', 'Diciembre'],
		days: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa'],
		strings: {
			'Now': 'Ahora',
			'Today': 'Hoy',
			'Time': 'Hora',
			'Exact minutes': 'Minuto exacto',
			'Select Date and Time': 'Selecciona Dia y Hora',
			'Open calendar': 'Abre calendario'
		}
	},
	'de': { 
		months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'], 
		days: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'], 
		strings: { 
			'Now': 'Jetzt', 
			'Today': 'Heute', 
			'Time': 'Zeit', 
			'Exact minutes': 'Exakte minuten', 
			'Select Date and Time': 'Zeit und Datum Auswählen',
			'Open calendar': 'Kalender öffnen'
		}
	}	
};

Control.DatePickerPanel = Class.create();
Object.extend(Control.DatePickerPanel.prototype, {
	initialize: function(options) {
		this.i18n = new Control.DatePicker.i18n(options && options.locale ? options.locale : 'en_GB');
		options = this.i18n.inheritOptions(options);
		this.options = Object.extend({
						className: 'datepickerControl',
						closeOnToday: true,
						selectToday: true,
						showOnFocus: false,
						timePicker: false,
						firstWeekDay: 0,
						weekend: [0,6],
						months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
						days: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
					}, options || {});
		// Make sure first weekday is in the correct range
		with (this.options)
			if (isNaN(firstWeekDay*1)) firstWeekDay = 0;
			else firstWeekDay = firstWeekDay % 7;

		this.keysCaptured = false;
		this.calendarCont = null;
		this.currentDate = this.options.date ? this.options.date : new Date();
		this.dayOfWeek = 0;
		this.minInterval = 5;

		this.selectedDay = null;
		this.selectedHour = null;
		this.selectedMinute = null;
		this.selectedAmPm = null;

		this.currentDays = [];
		this.hourCells = [];
		this.minuteCells = [];
		this.otherMinutes = null;
		this.amCell = null;
		this.pmCell = null;

		this.element = this.createPicker();
		this.selectDate(this.currentDate);
	},
	createPicker: function() {
		var elt = document.createElement('div');
		elt.style.position = 'absolute';
		elt.className = this.options.className;
		this.calendarCont = this.drawCalendar(elt, this.currentDate);

		Event.observe(elt, 'click', this.clickHandler.bindAsEventListener(this));
		Event.observe(elt, 'dblclick', this.dblClickHandler.bindAsEventListener(this));
		this.documentKeyListener = this.keyHandler.bindAsEventListener(this);
		if (this.options.captureKeys)
			this.captureKeys();
		
		return elt;
	},
	tr: function(str) {
		return this.i18n.tr(str);
	},
	captureKeys: function() {
		Event.observe(document, 'keypress', this.documentKeyListener, true);
		this.keysCaptured = true;
	},
	releaseKeys: function() {
		Event.stopObserving(document, 'keypress', this.documentKeyListener, true);
		this.keysCaptured = false;
	},
	setDate: function(date) {
		if (date) {
			// Clear container
			while (this.calendarCont.firstChild)
				this.calendarCont.removeChild(this.calendarCont.firstChild);
			this.calendarCont.appendChild(this.createCalendar(date));
		}
	},
	drawCalendar: function(container, date) {
		var calCont = container;
		var calTable = this.createCalendar(date);

		if (this.options.timePicker) {
			var timeTable;
			if (this.options.timePickerAdjacent) {
				var rows = 0;

				var adjTable = document.createElement('table');
				adjTable.cellSpacing = 0;
				adjTable.cellPadding = 0;
				adjTable.border = 0;
				
				row = adjTable.insertRow(0);

				cell = row.insertCell(0);
				cell.vAlign = 'top';
				cell.appendChild(calTable);
				calCont = cell;

				cell = row.insertCell(1);
				cell.style.width = '5px';

				cell = row.insertCell(2);
				cell.vAlign = 'top';
				timeTable = document.createElement('table');
				timeTable.cellSpacing = 0;
				timeTable.cellPadding = 0;
				timeTable.border = 0;
				cell.appendChild(timeTable);

				container.appendChild(adjTable);

				row = timeTable.insertRow(rows++);
				row.className = 'monthLabel';
				cell = row.insertCell(0);
				cell.colSpan = 7;
				cell.innerHTML = this.tr('Time');

				row = timeTable.insertRow(rows++);
				cell = row.insertCell(0);
				cell.colSpan = 7;
				cell.style.height = '1px';

			} else {
				container.appendChild(calTable);
				timeTable = calTable;
				var rows = calTable.rows.length;

				row = timeTable.insertRow(rows++);
				cell = row.insertCell(0);
				cell.colSpan = 7;

				var hr = document.createElement('hr');
				Element.setStyle(hr, {'color': 'gray', 'backgroundColor': 'gray', 'height': '1px', 'border': '0', 'marginTop': '3px', 'marginBottom': '3px', 'padding': '0'});
				cell.appendChild(hr);
			}

			for (var j = 0; j < 2; ++j) {
				row = timeTable.insertRow(rows++);
				for (var i = 0; i < 6; ++i){
					cell = row.insertCell(i);
					cell.className = 'hour';
					cell.width = '14%';
					cell.innerHTML = (j*6)+i+1;
					cell.onclick = this.hourClickedListener((j*6)+i+1);
					this.hourCells[(j*6)+i] = cell;
				}
				cell = row.insertCell(i);
				cell.className = 'ampm';
				cell.width = '14%';
				if (j) {
					cell.innerHTML = this.tr('PM');
					cell.onclick = this.pmClickedListener();
					this.pmCell = cell;
				} else {
					cell.innerHTML = this.tr('AM');
					cell.onclick = this.amClickedListener();
					this.amCell = cell;
				}
			}

			row = timeTable.insertRow(rows++);
			cell = row.insertCell(0);
			cell.colSpan = 6;

			var hr = document.createElement('hr');
			Element.setStyle(hr, {'color': '#CCCCCC', 'backgroundColor': '#CCCCCC', 'height': '1px', 'border': '0', 'marginTop': '2px', 'marginBottom': '2px', 'padding': '0'});
			cell.appendChild(hr);
			cell = row.insertCell(1);

			for (var j = 0; j < (10/this.minInterval); ++j) {
				row = timeTable.insertRow(rows++);
				for (var i = 0; i < 6; ++i){
					cell = row.insertCell(i);
					cell.className = 'minute';
					cell.width = '14%';
					var minval = ((j*6+i)*this.minInterval);
					if (minval < 10) minval = '0'+minval;
					cell.innerHTML = ':'+minval;
					cell.onclick = this.minuteClickedListener(minval);
					this.minuteCells[(j*6)+i] = cell;
				}
				cell = row.insertCell(i);
				cell.width = '14%';
			}

			row = timeTable.insertRow(rows++);
			cell = row.insertCell(0);
			//cell.className = 'otherminute';
			cell.style.textAlign = 'right';
			cell.colSpan = 5;
			cell.innerHTML = '<i>'+this.tr('Exact minutes')+':</i>';

			cell = row.insertCell(1);
			cell.className = 'otherminute';
			var otherInput = document.createElement('input');
			otherInput.type = 'text';
			otherInput.maxLength = 2;
			otherInput.style.width = '2em';
			var inputTimeout = null;
			otherInput.onkeyup = function(e) {
						if (!isNaN(otherInput.value)) {
							clearTimeout(inputTimeout);
							inputTimeout = setTimeout(function () {
									this.currentDate.setMinutes(otherInput.value);
									this.dateClicked(this.currentDate);
								}.bind(this), 500);
						}
					}.bindAsEventListener(this);
			otherInput.onkeypress = function(e) {
						if (e.keyCode == Event.KEY_RETURN)
							if (this.options.onSelect) this.options.onSelect(this.currentDate);
					}.bindAsEventListener(this);
			// Remove event key capture to allow use of arrow keys
			otherInput.onfocus = this.releaseKeys.bindAsEventListener(this);
			otherInput.onblur = this.captureKeys.bindAsEventListener(this);
			this.otherMinutes = otherInput;
			cell.appendChild(otherInput);
			// Padding cell
			cell = row.insertCell(2);

			row = timeTable.insertRow(rows++);
			cell = row.insertCell(0);
			cell.colSpan = 7;

			hr = document.createElement('hr');
			Element.setStyle(hr, {'color': 'gray', 'backgroundColor': 'gray', 'height': '1px', 'border': '0', 'marginTop': '3px', 'marginBottom': '3px', 'padding': '0'});
			cell.appendChild(hr);

			row = timeTable.insertRow(rows++);
			cell = row.insertCell(0);
			cell.colSpan = 7;

			selectButton = document.createElement('input');
			selectButton.type = 'button';
			selectButton.value = this.tr('Select Date and Time');
			selectButton.onclick = function(e) {
						this.options.onSelect && this.options.onSelect(this.currentDate);
					}.bindAsEventListener(this);
			cell.appendChild(selectButton);

		} else {
			calCont.appendChild(calTable);
		}

		return calCont;

	},
	createCalendar: function(date) {
		this.currentDate = date;
		this.currentDays = [];

		var today = new Date();
		var previousYear = new Date(date.getFullYear() - 1, date.getMonth(), 1)
		var previousMonth = new Date(date.getFullYear(), date.getMonth() - 1, 1)
		var nextMonth = new Date(date.getFullYear(), date.getMonth() + 1, 1)
		var nextYear = new Date(date.getFullYear() + 1, date.getMonth(), 1)

		var row;
		var cell;
		var rows = 0;

		var calTable = document.createElement('table');
		calTable.cellSpacing = 0;
		calTable.cellPadding = 0;
		calTable.border = 0;

		row = calTable.insertRow(rows++);
		row.className = 'monthLabel';
		cell = row.insertCell(0);
		cell.colSpan = 7;
		cell.innerHTML = this.monthName(date.getMonth()) + ' ' + date.getFullYear();

		row = calTable.insertRow(rows++);
		row.className = 'navigation';

		cell = row.insertCell(0);
		cell.className = 'navbutton';
		cell.title = this.monthName(previousYear.getMonth()) + ' ' + previousYear.getFullYear();
		cell.onclick = this.movePreviousYearListener();
		cell.innerHTML = '&lt;&lt;';

		cell = row.insertCell(1);
		cell.className = 'navbutton';
		cell.title = this.monthName(previousMonth.getMonth()) + ' ' + previousMonth.getFullYear();
		cell.onclick = this.movePreviousMonthListener();
		cell.innerHTML = '&lt;';

		cell = row.insertCell(2);
		cell.colSpan = 3;
		cell.className = 'navbutton';
		cell.title = today.getDate() + ' ' + this.monthName(today.getMonth()) + ' ' + today.getFullYear();
		cell.onclick = this.dateClickedListener(today, true);
		if (this.options.timePicker)
			cell.innerHTML = this.tr('Now');
		else
			cell.innerHTML = this.tr('Today');

		cell = row.insertCell(3);
		cell.className = 'navbutton';
		cell.title = this.monthName(nextMonth.getMonth()) + ' ' + nextMonth.getFullYear();
		cell.onclick = this.moveNextMonthListener();
		cell.innerHTML = '&gt;';

		cell = row.insertCell(4);
		cell.className = 'navbutton';
		cell.title = this.monthName(nextYear.getMonth()) + ' ' + nextYear.getFullYear();
		cell.onclick = this.moveNextYearListener();
		cell.innerHTML = '&gt;&gt;';

		row = calTable.insertRow(rows++);
		row.className = 'dayLabel';
		for (var i = 0; i < 7; ++i){
			cell = row.insertCell(i);
			cell.width = '14%';
			cell.innerHTML = this.dayName((this.options.firstWeekDay + i) % 7);
		}
		
		row = null;
		var workDate = new Date(date.getFullYear(), date.getMonth(), 1);
		var day = workDate.getDay();
		var j = 0;

		// Pad with previous month
		if (day != this.options.firstWeekDay) {
			row = calTable.insertRow(rows++);
			row.className = 'calendarRow';
			workDate.setDate(workDate.getDate() - ((day - this.options.firstWeekDay + 7) % 7));
			day = workDate.getDay();
			while (workDate.getMonth() != date.getMonth()) {
				cell = row.insertCell(row.cells.length);
				this.assignDayClasses(cell, 'dayothermonth', workDate);
				cell.innerHTML = workDate.getDate();
				cell.onclick = this.dateClickedListener(workDate);
				workDate.setDate(workDate.getDate() + 1);
				day = workDate.getDay();
			}
		}

		// Display days
		while (workDate.getMonth() == date.getMonth()) {
			if (day == this.options.firstWeekDay) {
				row = calTable.insertRow(rows++);
				row.className = 'calendarRow';
			}
			cell = row.insertCell(row.cells.length);
			this.assignDayClasses(cell, 'day', workDate);
			cell.innerHTML = workDate.getDate();
			cell.onclick = this.dateClickedListener(workDate);
			this.currentDays[workDate.getDate()] = cell;
			workDate.setDate(workDate.getDate() + 1);
			day = workDate.getDay();
		}

		// Pad with next month
		if (day != this.options.firstWeekDay)
			do {
				cell = row.insertCell(row.cells.length);
				this.assignDayClasses(cell, 'dayothermonth', workDate);
				cell.innerHTML = workDate.getDate();
				var thisDate = new Date(workDate.getTime());
				cell.onclick = this.dateClickedListener(workDate);
				workDate.setDate(workDate.getDate() + 1);
				day = workDate.getDay();
			} while (workDate.getDay() != this.options.firstWeekDay);

		return calTable;
	},
	movePreviousMonthListener: function() {
		return function(e) {
				var prevMonth = new Date(
						this.currentDate.getFullYear(),
						this.currentDate.getMonth() - 1,
						this.currentDate.getDate(),
						this.currentDate.getHours(),
						this.currentDate.getMinutes());
				if (prevMonth.getMonth() != (this.currentDate.getMonth() + 11) % 12) prevMonth.setDate(0);
				this.selectDate(prevMonth);
			}.bindAsEventListener(this);
	},
	moveNextMonthListener: function() {
		return function(e) {
				var nextMonth = new Date(
						this.currentDate.getFullYear(),
						this.currentDate.getMonth() + 1,
						this.currentDate.getDate(),
						this.currentDate.getHours(),
						this.currentDate.getMinutes());
				if (nextMonth.getMonth() != (this.currentDate.getMonth() + 1) % 12) nextMonth.setDate(0);
				this.selectDate(nextMonth);
			}.bindAsEventListener(this);
	},
	moveNextYearListener: function() {
		return function(e) {
				var nextYear = new Date(
						this.currentDate.getFullYear() + 1,
						this.currentDate.getMonth(),
						this.currentDate.getDate(),
						this.currentDate.getHours(),
						this.currentDate.getMinutes());
				if (nextYear.getMonth() != this.currentDate.getMonth()) nextYear.setDate(0);
				this.selectDate(nextYear);
			}.bindAsEventListener(this);
	},
	movePreviousYearListener: function() {
		return function(e) {
				var prevYear = new Date(
						this.currentDate.getFullYear() - 1,
						this.currentDate.getMonth(),
						this.currentDate.getDate(),
						this.currentDate.getHours(),
						this.currentDate.getMinutes());
				if (prevYear.getMonth() != this.currentDate.getMonth()) prevYear.setDate(0);
				this.selectDate(prevYear);
			}.bindAsEventListener(this);
	},
	dateClickedListener: function(date, timeOverride) {
		var dateCopy = new Date(date.getTime());
		return function(e) {
				if (!timeOverride) {
					dateCopy.setHours(this.currentDate.getHours());
					dateCopy.setMinutes(this.currentDate.getMinutes());
				}
				this.dateClicked(dateCopy);
			}.bindAsEventListener(this);
	},
	hourClickedListener: function(hour) {
		return function(e) {
				this.hourClicked(hour);
			}.bindAsEventListener(this);
	},
	minuteClickedListener: function(minutes) {
		return function(e) {
				this.currentDate.setMinutes(minutes);
				this.dateClicked(this.currentDate);
			}.bindAsEventListener(this);
	},
	amClickedListener: function() {
		return function(e) {
				if (this.selectedAmPm == this.pmCell) {
					this.currentDate.setHours(this.currentDate.getHours()-12);
					this.dateClicked(this.currentDate);
				}
			}.bindAsEventListener(this);
	},
	pmClickedListener: function() {
		return function(e) {
				if (this.selectedAmPm == this.amCell) {
					this.currentDate.setHours(this.currentDate.getHours()+12);
					this.dateClicked(this.currentDate);
				}
			}.bindAsEventListener(this);
	},
	assignDayClasses: function(cell, baseClass, date) {
		var today = new Date();
		Element.addClassName(cell, baseClass);
		if (date.getFullYear() == today.getFullYear() && date.getMonth() == today.getMonth() && date.getDate() == today.getDate())
			Element.addClassName(cell, 'today');
		if (this.options.weekend.include(date.getDay()))
			Element.addClassName(cell, 'weekend');
	},
	monthName: function(month) {
		return this.options.months[month];
	},
	dayName: function(day) {
		return this.options.days[day];
	},
	dblClickHandler: function(e) {
		if(this.options.onSelect)
			this.options.onSelect(this.currentDate);
		Event.stop(e);
	},
	clickHandler: function(e) {
		if(this.options.onClick)
			this.options.onClick();
		Event.stop(e);
	},
	hoverHandler: function(e) {
		if(this.options.onHover)
			this.options.onHover(date);
	},
	keyHandler: function(e) {
		var days = 0;
		switch (e.keyCode){
			case Event.KEY_RETURN:
				if (this.options.onSelect) this.options.onSelect(this.currentDate);
				break;
			case Event.KEY_LEFT:
				days = -1;
				break;
			case Event.KEY_UP:
				days = -7;
				break;
			case Event.KEY_RIGHT:
				days = 1;
				break;
			case Event.KEY_DOWN:
				days = 7;
				break;
			case 33: // PgUp
				var lastMonth = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() - 1, this.currentDate.getDate());
				days = -this.getDaysOfMonth(lastMonth);
				break;
			case 34: // PgDn
				days = this.getDaysOfMonth(this.currentDate);
				break;
			case 13: // enter-key (forms without submit buttons)
				this.dateClicked(this.currentDate);
				break;
			default:
				return;
		}
		if (days != 0) {
			var moveDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), this.currentDate.getDate() + days);
			moveDate.setHours(this.currentDate.getHours());
			moveDate.setMinutes(this.currentDate.getMinutes());
			this.selectDate(moveDate);
		}
		Event.stop(e);
		return false;
	},
	getDaysOfMonth: function(date) {
		var lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
		return lastDay.getDate();
	},
	getNextMonth: function(month, year, increment) {
		if (p_Month == 11) return [0, year + 1];
		else return [month + 1, year];
	},
	getPrevMonth: function(month, year, increment) {
		if (p_Month == 0) return [11, year - 1];
		else return [month - 1, year];
	},
	dateClicked: function(date) {
		if (date) {
			if (!this.options.timePicker && this.options.onSelect)
				this.options.onSelect(date);
			this.selectDate(date);
		}
	},
	hourClicked: function(hour) {
		if (hour == 12) {
			if (this.selectedAmPm == this.amCell)
				hour = 0;
		} else if (this.selectedAmPm == this.pmCell) {
			hour += 12;
		}
		this.currentDate.setHours(hour);
		this.dateClicked(this.currentDate);
	},
	selectDate: function(date) {
		if (date) {
			if (date.getMonth() != this.currentDate.getMonth()
					|| date.getFullYear() != this.currentDate.getFullYear())
				this.setDate(date);
			else
				this.currentDate = date;

			if (date.getDate() < this.currentDays.length) {
				if (this.selectedDay)
					Element.removeClassName(this.selectedDay, 'current');
				this.selectedDay = this.currentDays[date.getDate()];
				Element.addClassName(this.selectedDay, 'current');
			}

			if (this.options.timePicker) {
				var hours = date.getHours();
				if (this.selectedHour)
					Element.removeClassName(this.selectedHour, 'current');
				this.selectedHour = this.hourCells[hours % 12 ? (hours % 12) - 1 : 11];
				Element.addClassName(this.selectedHour, 'current');

				if (this.selectedAmPm)
					Element.removeClassName(this.selectedAmPm, 'current');
				this.selectedAmPm = (hours < 12 ? this.amCell : this.pmCell);
				Element.addClassName(this.selectedAmPm, 'current');

				var minutes = date.getMinutes();
				if (this.selectedMinute)
					Element.removeClassName(this.selectedMinute, 'current');
				Element.removeClassName(this.otherMinutes, 'current');
				if (minutes % this.minInterval == 0) {
					this.otherMinutes.value = null;
					this.selectedMinute = this.minuteCells[minutes / this.minInterval];
					Element.addClassName(this.selectedMinute, 'current');
				} else {
					this.otherMinutes.value = minutes;
					Element.addClassName(this.otherMinutes, 'current');
				}
			}

			if (this.options.onHover)
				this.options.onHover(date);
		}
	}
});

/*--------------------------------------------------------------------------
| Proto Check, version 1.0
| (c) 2008 Neil Harrison
| Released under the terms and conditions of the
| Creative Commons Attribution-Share Alike
| http://creativecommons.org/licenses/by-sa/3.0/
*--------------------------------------------------------------------------*/
ProtoCheck = Class.create({
   initialize: function(options) {
      this.options = {
         checkClass:             'pc_checkbox',
         radioClass:             'pc_radiobutton',
         checkOnClass:           'pc_check_checked',
         checkOffClass:          'pc_check_unchecked',
         radioOnClass:           'pc_radio_checked',
         radioOffClass:          'pc_radio_unchecked',
         checkOnDisabledClass:   'pc_check_checked_disabled',
         checkOffDisabledClass:  'pc_check_unchecked_disabled',
         radioOnDisabledClass:   'pc_radio_checked_disabled',
         radioOffDisabledClass:  'pc_radio_unchecked_disabled',
         focusClass:             'pc_focus'
      };
      Object.extend(this.options, options || { });
      this.classez               = [];
      this.disClassez            = [];
      this.classez.checkbox      = {"on": this.options.checkOnClass, "off": this.options.checkOffClass};
      this.disClassez.checkbox   = {"on": this.options.checkOnDisabledClass, "off": this.options.checkOffDisabledClass};
      this.classez.radio         = {"on": this.options.radioOnClass, "off": this.options.radioOffClass};
      this.disClassez.radio      = {"on": this.options.radioOnDisabledClass, "off": this.options.radioOffDisabledClass};
      var elements = $$("label."+this.options.checkClass).concat($$("label."+this.options.radioClass));
      elements.each(function(label) {
         var element = label.down();
         element.setStyle({position:'absolute',left:'-9999px'});
         if (element.checked) {
            this.check(element, label);
         } else {
            this.uncheck(element, label);
         }
         if (!element.disabled) {
            element.observe("click", function(ev) {
               this.click(ev);
            }.bind(this));
            element.observe("focus", function(ev) {
               this.focus(ev);
            }.bind(this));
            element.observe("blur", function(ev) {
               this.blur(ev);
            }.bind(this));
            if (this.fixIE) {
               label.observe("click", function(ev) {
                  this.clickIE6(ev);
               }.bind(this));
            }
         }
      }.bind(this));
   },
   fixIE: (function(agent){
      var version = new RegExp('MSIE ([\\d.]+)').exec(agent);
      return version ? (parseFloat(version[1]) <= 6) : false;
   })(navigator.userAgent),
   check: function(element, label) {
      var css = element.disabled ? this.disClassez[element.type] : this.classez[element.type];
      label.addClassName(css.on).removeClassName(css.off);
   },
   uncheck: function(element, label) {
      var css = element.disabled ? this.disClassez[element.type] : this.classez[element.type];
      label.addClassName(css.off).removeClassName(css.on);
   },
   focus: function(ev) {
      var label = ev.element().up();
      label.addClassName(this.options.focusClass);
   },
   blur: function(ev) {
      var label = ev.element().up();
      label.removeClassName(this.options.focusClass);
   },
   click: function(ev) {
      var element = ev.element();
      var label = element.up();
      this.update(ev, element, label);
   },
   clickIE6: function(ev) {
      var label = ev.element();
      if (label.nodeName == "LABEL") {
         var element = label.down();
         element.click();
      }
   },
   update: function(ev, element, label) {
      if (label.hasClassName(this.options.checkClass)) {
         if (element.checked) {
            this.check(element, label);
         } else {
            this.uncheck(element, label);
         }
      }
      if (label.hasClassName(this.options.radioClass)) {
         $$("input[name="+element.name+"]").each(function(but) {
            if (element != but) {
               this.uncheck(but, but.up());
            }
         }.bind(this));
         this.check(element, label);
      }
      element.focus();
   }
});
/**
	ProtoTube v1b BETA 27.04.2009
	Copyright (c) 2008 Filippo Buratti; info [at] cssrevolt.com [dot] com; http://www.filippoburatti.net/

	Permission is hereby granted, free of charge, to any person obtaining a copy
	of this software and associated documentation files (the "Software"), to deal
	in the Software without restriction, including without limitation the rights
	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
	copies of the Software, and to permit persons to whom the Software is
	furnished to do so, subject to the following conditions:

	The above copyright notice and this permission notice shall be included in
	all copies or substantial portions of the Software.

	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
	THE SOFTWARE.
*/
var ProtoTube = Class.create({
	
	initialize: function(element, options) {
		
		this.element 	= $(element);
		var url 		= this.element.readAttribute('href');
		this.videoID 	=	url.replace(/^[^v]+v.(.{11}).*/,"$1");
		this.body = $$('body')[0];
		this.html = $$('html')[0];
		
		Prototype.Browser.IE6 = Prototype.Browser.IE && parseInt(navigator.userAgent.substring(navigator.userAgent.indexOf("MSIE")+5)) == 6;
		
		this.options 	= {	
			overlay: true, // if false embed the video player directly		
			// overlay and preview options
			duration: 0.5, // overlay appare/fade effect
			opacity: 0.8,  // overlay opacity
			imagePreview: true, // show video thumb
			imageID: 1, // 0,1,2,3			
			// player configuration
			playerWidth: 425,
			playerHeight: 350,
			fs: 1, // fullscreen button
			autoplay:0,
			loop:0,
			hd:0, // High definition
			showinfo:0, // show video title and rating before start 
			rel:1, // show related video at end			
			// You Tube url
			youtubeVideoUrl: 'http://www.youtube.com/v/',
			youtubeImageUrl: 'http://img.youtube.com/vi/'
		};
		Object.extend(this.options, options || {});
			
		this.options.overlay ? this.setupPreviewOverlay() : this.directEmbed();	
		
	},
	
	setupPreviewOverlay: function() {
			if (this.options.imagePreview){ this.getImagePreview(); }		
			this.addOverlayMarkup();
			Event.observe(this.element, "click", this.showProtoTube.bindAsEventListener(this));		
			Event.observe(this.overlay, 'click', this.hideProtoTube.bindAsEventListener(this));
			Event.observe(this.ProtoTube, 'click',  function(event) { Event.stop(event) });
	},
	
	directEmbed: function() {			
		this.getVideoEmbed(this.element);	
	},
	
	addOverlayMarkup: function(){
		this.ProtoTube = new Element('div', {className:'prototube'});
		this.wrapper = new Element('div').update('<p>Loading video from You Tube...</p>');
		this.ProtoTube.insert(this.wrapper);
		this.overlay = new Element('div', {className:'overlay'});
		this.overlay.insert(this.ProtoTube);
		this.body.insert(this.overlay.hide());
	},

	showProtoTube: function (event) {
		Event.stop(event);
		this.toggleTroubleElements('hidden');
		this.getVideoEmbed(this.wrapper);
		this.ProtoTube.setStyle({ width: this.options.playerWidth+"px", height: this.options.playerHeight+"px", marginTop: "-"+ this.options.playerHeight/2 +"px", marginLeft: "-"+ this.options.playerWidth/2 +"px" });	
		if (Prototype.Browser.IE6) { this.prepareIE('100%', 'hidden'); }
		new Effect.Appear(this.overlay, { duration: this.options.duration,  from: 0.0, to: this.options.opacity });
	},
	
	hideProtoTube: function() {	
		new Effect.Fade(
				this.overlay, { 
					duration: this.options.duration, 
					afterFinish:function() { 
						this.toggleTroubleElements('visible');
						if (Prototype.Browser.IE6) { this.prepareIE("auto", "auto"); }
					}.bind(this)
				});
		},
	
	getVideoEmbed: function(wrapper) {
		var wrapperID = wrapper.identify();
		var flashvars = {
			fs: this.options.fs,
			autoplay: this.options.autoplay,
			loop: this.options.loop,
			hd: this.options.hd,
			showinfo: this.options.showinfo,
			rel: this.options.rel
	
		};
		var params = { 
			allowScriptAccess: "always",
			allowFullScreen: true,
			menu: false
		};
		var atts = { };
		swfobject.embedSWF(this.options.youtubeVideoUrl+this.videoID, wrapperID, this.options.playerWidth, this.options.playerHeight, "9", null, flashvars, params, atts);
	},
	
	getImagePreview: function() {	
		this.image =  new Image();	
		this.element.update(this.image);
		this.image.src  = this.options.youtubeImageUrl + this.videoID + "/" + this.options.imageID + ".jpg";				
	},
	
	toggleTroubleElements: function(visibility) {
		$$('select', 'object', 'embed').each(function(node) { node.style.visibility = visibility });
	},
	
	prepareIE: function(height, overflow) {
		this.body.setStyle({ height: height, overflow: overflow });	
		this.html.setStyle({ height: height, overflow: overflow }); 
	}

});
Hash.prototype.without = function() {
    var values = $A(arguments);
	var retHash = $H();
    this.each(function(entry) {
		if(!values.include(entry.key))
			retHash.set(entry.key, entry.value);
    });
	return retHash;
}

Element.insertAfter = function(insert, element) {
	if (element.nextSibling) element.parentNode.insertBefore(insert, element.nextSibling);
	else element.parentNode.appendChild(insert);
}

// Fix exceptions thrown thrown when removing an element with no parent
Element._remove = Element.remove;
Element.remove = function(element) {
	element = $(element);
	if (element.parentNode)
		return Element._remove(element);
}

DateFormat = Class.create();
Object.extend(DateFormat, {
	MONTH_NAMES: ['January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],
	DAY_NAMES: ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sun','Mon','Tue','Wed','Thu','Fri','Sat'],
	LZ: function(x) {return(x<0||x>9?"":"0")+x},
	compareDates: function(date1,dateformat1,date2,dateformat2) {
		var d1=DateFormat.parseFormat(date1,dateformat1);
		var d2=DateFormat.parseFormat(date2,dateformat2);
		if (d1==0 || d2==0) return -1;
		else if (d1 > d2) return 1;
		return 0;
	},
	format: function(date,format) {
		format=format+"";
		var result="";
		var i_format=0;
		var c="";
		var token="";
		var y=date.getYear()+"";
		var M=date.getMonth()+1;
		var d=date.getDate();
		var E=date.getDay();
		var H=date.getHours();
		var m=date.getMinutes();
		var s=date.getSeconds();
		var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
		// Convert real date parts into formatted versions
		var value=new Object();
		if (y.length < 4) {y=""+(y-0+1900);}
		value["y"]=""+y;
		value["yyyy"]=y;
		value["yy"]=y.substring(2,4);
		value["M"]=M;
		value["MM"]=DateFormat.LZ(M);
		value["MMM"]=DateFormat.MONTH_NAMES[M-1];
		value["NNN"]=DateFormat.MONTH_NAMES[M+11];
		value["d"]=d;
		value["dd"]=DateFormat.LZ(d);
		value["E"]=DateFormat.DAY_NAMES[E+7];
		value["EE"]=DateFormat.DAY_NAMES[E];
		value["H"]=H;
		value["HH"]=DateFormat.LZ(H);
		if (H==0){value["h"]=12;}
		else if (H>12){value["h"]=H-12;}
		else {value["h"]=H;}
		value["hh"]=DateFormat.LZ(value["h"]);
		if (H>11){value["K"]=H-12;} else {value["K"]=H;}
		value["k"]=H+1;
		value["KK"]=DateFormat.LZ(value["K"]);
		value["kk"]=DateFormat.LZ(value["k"]);
		if (H > 11) { value["a"]="PM"; }
		else { value["a"]="AM"; }
		value["m"]=m;
		value["mm"]=DateFormat.LZ(m);
		value["s"]=s;
		value["ss"]=DateFormat.LZ(s);
		while (i_format < format.length) {
			c=format.charAt(i_format);
			token="";
			while ((format.charAt(i_format)==c) && (i_format < format.length))
				token += format.charAt(i_format++);
			if (value[token] != null) result += value[token];
			else result += token;
		}
		return result;
	},
	_isInteger: function(val) {
		var digits="1234567890";
		for (var i=0; i < val.length; i++)
			if (digits.indexOf(val.charAt(i))==-1) return false;
		return true;
	},
	_getInt: function(str,i,minlength,maxlength) {
		for (var x=maxlength; x>=minlength; x--) {
			var token=str.substring(i,i+x);
			if (token.length < minlength) return null;
			if (DateFormat._isInteger(token)) return token;
		}
		return null;
	},
	parseFormat: function(val,format) {
		val=val+"";
		format=format+"";
		var i_val=0;
		var i_format=0;
		var c="";
		var token="";
		var token2="";
		var x,y;
		var now=new Date();
		var year=now.getYear();
		var month=now.getMonth()+1;
		var date=1;
		var hh=now.getHours();
		var mm=now.getMinutes();
		var ss=now.getSeconds();
		var ampm="";
		
		while (i_format < format.length) {
			// Get next token from format string
			c=format.charAt(i_format);
			token="";
			while ((format.charAt(i_format)==c) && (i_format < format.length))
				token += format.charAt(i_format++);
			// Extract contents of value based on format token
			if (token=="yyyy" || token=="yy" || token=="y") {
				if (token=="yyyy") x=4;y=4;
				if (token=="yy") x=2;y=2;
				if (token=="y") x=2;y=4;
				year=DateFormat._getInt(val,i_val,x,y);
				if (year==null) return 0;
				i_val += year.length;
				if (year.length==2) {
					if (year > 70) year=1900+(year-0);
					else year=2000+(year-0);
				}
			} else if (token=="MMM"||token=="NNN") {
				month=0;
				for (var i=0; i<DateFormat.MONTH_NAMES.length; i++) {
					var month_name=DateFormat.MONTH_NAMES[i];
					if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
						if (token=="MMM"||(token=="NNN"&&i>11)) {
							month=i+1;
							if (month>12) month -= 12;
							i_val += month_name.length;
							break;
						}
					}
				}
				if ((month < 1)||(month>12)) return 0;
			} else if (token=="EE"||token=="E") {
				for (var i=0; i<DateFormat.DAY_NAMES.length; i++) {
					var day_name=DateFormat.DAY_NAMES[i];
					if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
						i_val += day_name.length;
						break;
					}
				}
			} else if (token=="MM"||token=="M") {
				month=DateFormat._getInt(val,i_val,token.length,2);
				if(month==null||(month<1)||(month>12)) return 0;
				i_val+=month.length;
			} else if (token=="dd"||token=="d") {
				date=DateFormat._getInt(val,i_val,token.length,2);
				if(date==null||(date<1)||(date>31)) return 0;
				i_val+=date.length;
			} else if (token=="hh"||token=="h") {
				hh=DateFormat._getInt(val,i_val,token.length,2);
				if(hh==null||(hh<1)||(hh>12)) return 0;
				i_val+=hh.length;
			} else if (token=="HH"||token=="H") {
				hh=DateFormat._getInt(val,i_val,token.length,2);
				if(hh==null||(hh<0)||(hh>23)) return 0;
				i_val+=hh.length;
			} else if (token=="KK"||token=="K") {
				hh=DateFormat._getInt(val,i_val,token.length,2);
				if(hh==null||(hh<0)||(hh>11)) return 0;
				i_val+=hh.length;
			} else if (token=="kk"||token=="k") {
				hh=DateFormat._getInt(val,i_val,token.length,2);
				if(hh==null||(hh<1)||(hh>24)) return 0;
				i_val+=hh.length;hh--;
			} else if (token=="mm"||token=="m") {
				mm=DateFormat._getInt(val,i_val,token.length,2);
				if(mm==null||(mm<0)||(mm>59)) return 0;
				i_val+=mm.length;
			} else if (token=="ss"||token=="s") {
				ss=DateFormat._getInt(val,i_val,token.length,2);
				if(ss==null||(ss<0)||(ss>59)) return 0;
				i_val+=ss.length;
			} else if (token=="a") {
				if (val.substring(i_val,i_val+2).toLowerCase()=="am") ampm="AM";
				else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") ampm="PM";
				else return 0;
				i_val+=2;
			} else {
				if (val.substring(i_val,i_val+token.length)!=token) return 0;
				else i_val+=token.length;
			}
		}
		// If there are any trailing characters left in the value, it doesn't match
		if (i_val != val.length) return 0;
		// Is date valid for month?
		if (month==2) {
			// Check for leap year
			if (((year%4==0)&&(year%100 != 0)) || (year%400==0)) { // leap year
				if (date > 29) return 0;
			} else if (date > 28) {
				return 0;
			}
		}
		if ((month==4)||(month==6)||(month==9)||(month==11))
			if (date > 30) return 0;
		// Correct hours value
		if (hh<12 && ampm=="PM") hh=hh-0+12;
		else if (hh>11 && ampm=="AM") hh-=12;
		var newdate=new Date(year,month-1,date,hh,mm,ss);
		return newdate;
	},
	parse: function(val, format) {
		if (format) {
			return DateFormat.parseFormat(val, format);
		} else {
			var preferEuro=(arguments.length==2)?arguments[1]:false;
			var generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d');
			var monthFirst=new Array('M/d/y','M-d-y','M.d.y','MMM-d','M/d','M-d');
			var dateFirst =new Array('d/M/y','d-M-y','d.M.y','d-MMM','d/M','d-M');
			var checkList=[generalFormats,preferEuro?dateFirst:monthFirst,preferEuro?monthFirst:dateFirst];
			var d=null;
			for (var i=0; i<checkList.length; i++) {
				var l=checkList[i];
				for (var j=0; j<l.length; j++) {
					d=DateFormat.parseFormat(val,l[j]);
					if (d!=0) return new Date(d);
				}
			}
			return null;
		}
	}
});

DateFormat.prototype = {
	initialize: function(format) { this.format = format; },
	parse: function(value) { return DateFormat.parseFormat(value, this.format); },
	format: function(value) { return DateFormat.format(value, this.format); }
}

Date.prototype.format = function(format) {
	return DateFormat.format(this, format);
}

/*
prototypeUtils.js from http://jehiah.com/
Licensed under Creative Commons.
version 1.0 December 20 2005

Contains:
+ Form.Element.setValue()
+ unpackToForm()

*/

/* Form.Element.setValue("fieldname/id","valueToSet") */
Form.Element.setValue = function(element,newValue) {
    element_id = element;
    element = $(element);
    if (!element){element = document.getElementsByName(element_id)[0];}
    if (!element){return false;}
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.SetSerializers[method](element,newValue);
}

Form.Element.SetSerializers = {
  input: function(element,newValue) {
    switch (element.type.toLowerCase()) {
      case 'submit':
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.SetSerializers.textarea(element,newValue);
      case 'checkbox':
      case 'radio':
        return Form.Element.SetSerializers.inputSelector(element,newValue);
    }
    return false;
  },

  inputSelector: function(element,newValue) {
    fields = document.getElementsByName(element.name);
    for (var i=0;i<fields.length;i++){
      if (fields[i].value == newValue){
        fields[i].checked = true;
      }
    }
  },

  textarea: function(element,newValue) {
    element.value = newValue;
  },

  select: function(element,newValue) {
    var value = '', opt, index = element.selectedIndex;
    for (var i=0;i< element.options.length;i++){
      if (element.options[i].value == newValue){
        element.selectedIndex = i;
        return true;
      }        
    }
  }
}

function unpackToForm(data){
   for (i in data){
     Form.Element.setValue(i,data[i].toString());
   }
}
/* End prototypeUtils.js from http://jehiah.com/ */

/* SWFObject v2.1 <http://code.google.com/p/swfobject/>
	Copyright (c) 2007-2008 Geoff Stearns, Michael Williams, and Bobby van der Sluis
	This software is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var b="undefined",Q="object",n="Shockwave Flash",p="ShockwaveFlash.ShockwaveFlash",P="application/x-shockwave-flash",m="SWFObjectExprInst",j=window,K=document,T=navigator,o=[],N=[],i=[],d=[],J,Z=null,M=null,l=null,e=false,A=false;var h=function(){var v=typeof K.getElementById!=b&&typeof K.getElementsByTagName!=b&&typeof K.createElement!=b,AC=[0,0,0],x=null;if(typeof T.plugins!=b&&typeof T.plugins[n]==Q){x=T.plugins[n].description;if(x&&!(typeof T.mimeTypes!=b&&T.mimeTypes[P]&&!T.mimeTypes[P].enabledPlugin)){x=x.replace(/^.*\s+(\S+\s+\S+$)/,"$1");AC[0]=parseInt(x.replace(/^(.*)\..*$/,"$1"),10);AC[1]=parseInt(x.replace(/^.*\.(.*)\s.*$/,"$1"),10);AC[2]=/r/.test(x)?parseInt(x.replace(/^.*r(.*)$/,"$1"),10):0}}else{if(typeof j.ActiveXObject!=b){var y=null,AB=false;try{y=new ActiveXObject(p+".7")}catch(t){try{y=new ActiveXObject(p+".6");AC=[6,0,21];y.AllowScriptAccess="always"}catch(t){if(AC[0]==6){AB=true}}if(!AB){try{y=new ActiveXObject(p)}catch(t){}}}if(!AB&&y){try{x=y.GetVariable("$version");if(x){x=x.split(" ")[1].split(",");AC=[parseInt(x[0],10),parseInt(x[1],10),parseInt(x[2],10)]}}catch(t){}}}}var AD=T.userAgent.toLowerCase(),r=T.platform.toLowerCase(),AA=/webkit/.test(AD)?parseFloat(AD.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,q=false,z=r?/win/.test(r):/win/.test(AD),w=r?/mac/.test(r):/mac/.test(AD);/*@cc_on q=true;@if(@_win32)z=true;@elif(@_mac)w=true;@end@*/return{w3cdom:v,pv:AC,webkit:AA,ie:q,win:z,mac:w}}();var L=function(){if(!h.w3cdom){return }f(H);if(h.ie&&h.win){try{K.write("<script id=__ie_ondomload defer=true src=//:><\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r<q;r++){o[r]()}}function f(q){if(e){q()}else{o[o.length]=q}}function R(r){if(typeof j.addEventListener!=b){j.addEventListener("load",r,false)}else{if(typeof K.addEventListener!=b){K.addEventListener("load",r,false)}else{if(typeof j.attachEvent!=b){I(j,"onload",r)}else{if(typeof j.onload=="function"){var q=j.onload;j.onload=function(){q();r()}}else{j.onload=r}}}}}function H(){var t=N.length;for(var q=0;q<t;q++){var u=N[q].id;if(h.pv[0]>0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u<v;u++){if(y[u].nodeName=="DATA"){w.setAttribute("src",y[u].nodeValue)}else{w.setAttribute(y[u].nodeName,y[u].nodeValue)}}}var x=q.childNodes;if(x){var z=x.length;for(var r=0;r<z;r++){if(x[r].nodeType==1&&x[r].nodeName=="PARAM"){w.setAttribute(x[r].getAttribute("name"),x[r].getAttribute("value"))}}}t.parentNode.replaceChild(w,t)}}function k(w){A=true;var u=C(w.id);if(u){if(w.altContentId){var y=C(w.altContentId);if(y){M=y;l=w.altContentId}}else{M=G(u)}if(!(/%$/.test(w.width))&&parseInt(w.width,10)<310){w.width="310"}if(!(/%$/.test(w.height))&&parseInt(w.height,10)<137){w.height="137"}K.title=K.title.slice(0,47)+" - Flash Player Installation";var z=h.ie&&h.win?"ActiveX":"PlugIn",q=K.title,r="MMredirectURL="+j.location+"&MMplayerType="+z+"&MMdoctitle="+q,x=w.id;if(h.ie&&h.win&&u.readyState!=4){var t=a("div");x+="SWFObjectNew";t.setAttribute("id",x);u.parentNode.insertBefore(t,u);u.style.display="none";var v=function(){u.parentNode.removeChild(u)};I(j,"onload",v)}U({data:w.expressInstall,id:m,width:w.width,height:w.height},{flashvars:r},x)}}function O(t){if(h.ie&&h.win&&t.readyState!=4){var r=a("div");t.parentNode.insertBefore(r,t);r.parentNode.replaceChild(G(t),r);t.style.display="none";var q=function(){t.parentNode.removeChild(t)};I(j,"onload",q)}else{t.parentNode.replaceChild(G(t),t)}}function G(v){var u=a("div");if(h.win&&h.ie){u.innerHTML=v.innerHTML}else{var r=v.getElementsByTagName(Q)[0];if(r){var w=r.childNodes;if(w){var q=w.length;for(var t=0;t<q;t++){if(!(w[t].nodeType==1&&w[t].nodeName=="PARAM")&&!(w[t].nodeType==8)){u.appendChild(w[t].cloneNode(true))}}}}}return u}function U(AG,AE,t){var q,v=C(t);if(v){if(typeof AG.id==b){AG.id=t}if(h.ie&&h.win){var AF="";for(var AB in AG){if(AG[AB]!=Object.prototype[AB]){if(AB.toLowerCase()=="data"){AE.movie=AG[AB]}else{if(AB.toLowerCase()=="styleclass"){AF+=' class="'+AG[AB]+'"'}else{if(AB.toLowerCase()!="classid"){AF+=" "+AB+'="'+AG[AB]+'"'}}}}}var AD="";for(var AA in AE){if(AE[AA]!=Object.prototype[AA]){AD+='<param name="'+AA+'" value="'+AE[AA]+'" />'}}v.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+AF+">"+AD+"</object>";i[i.length]=AG.id;q=C(AG.id)}else{if(h.webkit&&h.webkit<312){var AC=a("embed");AC.setAttribute("type",P);for(var z in AG){if(AG[z]!=Object.prototype[z]){if(z.toLowerCase()=="data"){AC.setAttribute("src",AG[z])}else{if(z.toLowerCase()=="styleclass"){AC.setAttribute("class",AG[z])}else{if(z.toLowerCase()!="classid"){AC.setAttribute(z,AG[z])}}}}}for(var y in AE){if(AE[y]!=Object.prototype[y]){if(y.toLowerCase()!="movie"){AC.setAttribute(y,AE[y])}}}v.parentNode.replaceChild(AC,v);q=AC}else{var u=a(Q);u.setAttribute("type",P);for(var x in AG){if(AG[x]!=Object.prototype[x]){if(x.toLowerCase()=="styleclass"){u.setAttribute("class",AG[x])}else{if(x.toLowerCase()!="classid"){u.setAttribute(x,AG[x])}}}}for(var w in AE){if(AE[w]!=Object.prototype[w]&&w.toLowerCase()!="movie"){F(u,w,AE[w])}}v.parentNode.replaceChild(u,v);q=u}}}return q}function F(t,q,r){var u=a("param");u.setAttribute("name",q);u.setAttribute("value",r);t.appendChild(u)}function X(r){var q=C(r);if(q&&(q.nodeName=="OBJECT"||q.nodeName=="EMBED")){if(h.ie&&h.win){if(q.readyState==4){B(r)}else{j.attachEvent("onload",function(){B(r)})}}else{q.parentNode.removeChild(q)}}}function B(t){var r=C(t);if(r){for(var q in r){if(typeof r[q]=="function"){r[q]=null}}r.parentNode.removeChild(r)}}function C(t){var q=null;try{q=K.getElementById(t)}catch(r){}return q}function a(q){return K.createElement(q)}function I(t,q,r){t.attachEvent(q,r);d[d.length]=[t,q,r]}function c(t){var r=h.pv,q=t.split(".");q[0]=parseInt(q[0],10);q[1]=parseInt(q[1],10)||0;q[2]=parseInt(q[2],10)||0;return(r[0]>q[0]||(r[0]==q[0]&&r[1]>q[1])||(r[0]==q[0]&&r[1]==q[1]&&r[2]>=q[2]))?true:false}function V(v,r){if(h.ie&&h.mac){return }var u=K.getElementsByTagName("head")[0],t=a("style");t.setAttribute("type","text/css");t.setAttribute("media","screen");if(!(h.ie&&h.win)&&typeof K.createTextNode!=b){t.appendChild(K.createTextNode(v+" {"+r+"}"))}u.appendChild(t);if(h.ie&&h.win&&typeof K.styleSheets!=b&&K.styleSheets.length>0){var q=K.styleSheets[K.styleSheets.length-1];if(typeof q.addRule==Q){q.addRule(v,r)}}}function W(t,q){var r=q?"visible":"hidden";if(e&&C(t)){C(t).style.visibility=r}else{V("#"+t,"visibility:"+r)}}function g(s){var r=/[\\\"<>\.;]/;var q=r.exec(s)!=null;return q?encodeURIComponent(s):s}var D=function(){if(h.ie&&h.win){window.attachEvent("onunload",function(){var w=d.length;for(var v=0;v<w;v++){d[v][0].detachEvent(d[v][1],d[v][2])}var t=i.length;for(var u=0;u<t;u++){X(i[u])}for(var r in h){h[r]=null}h=null;for(var q in swfobject){swfobject[q]=null}swfobject=null})}}();return{registerObject:function(u,q,t){if(!h.w3cdom||!u||!q){return }var r={};r.id=u;r.swfVersion=q;r.expressInstall=t?t:false;N[N.length]=r;W(u,false)},getObjectById:function(v){var q=null;if(h.w3cdom){var t=C(v);if(t){var u=t.getElementsByTagName(Q)[0];if(!u||(u&&typeof t.SetVariable!=b)){q=t}else{if(typeof u.SetVariable!=b){q=u}}}}return q},embedSWF:function(x,AE,AB,AD,q,w,r,z,AC){if(!h.w3cdom||!x||!AE||!AB||!AD||!q){return }AB+="";AD+="";if(c(q)){W(AE,false);var AA={};if(AC&&typeof AC===Q){for(var v in AC){if(AC[v]!=Object.prototype[v]){AA[v]=AC[v]}}}AA.data=x;AA.width=AB;AA.height=AD;var y={};if(z&&typeof z===Q){for(var u in z){if(z[u]!=Object.prototype[u]){y[u]=z[u]}}}if(r&&typeof r===Q){for(var t in r){if(r[t]!=Object.prototype[t]){if(typeof y.flashvars!=b){y.flashvars+="&"+t+"="+r[t]}else{y.flashvars=t+"="+r[t]}}}}f(function(){U(AA,y,AE);if(AA.id==AE){W(AE,true)}})}else{if(w&&!A&&c("6.0.65")&&(h.win||h.mac)){A=true;W(AE,false);f(function(){var AF={};AF.id=AF.altContentId=AE;AF.width=AB;AF.height=AD;AF.expressInstall=w;k(AF)})}}},getFlashPlayerVersion:function(){return{major:h.pv[0],minor:h.pv[1],release:h.pv[2]}},hasFlashPlayerVersion:c,createSWF:function(t,r,q){if(h.w3cdom){return U(t,r,q)}else{return undefined}},removeSWF:function(q){if(h.w3cdom){X(q)}},createCSS:function(r,q){if(h.w3cdom){V(r,q)}},addDomLoadEvent:f,addLoadEvent:R,getQueryParamValue:function(v){var u=K.location.search||K.location.hash;if(v==null){return g(u)}if(u){var t=u.substring(1).split("&");for(var r=0;r<t.length;r++){if(t[r].substring(0,t[r].indexOf("="))==v){return g(t[r].substring((t[r].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(A&&M){var q=C(m);if(q){q.parentNode.replaceChild(M,q);if(l){W(l,true);if(h.ie&&h.win){M.style.display="block"}}M=null;l=null;A=false}}}}}();
/*
 * Copyright (c) 2006 Jonathan Weiss <jw@innerewut.de>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */


/* tooltip-0.1.js - Small tooltip library on top of Prototype 
 * by Jonathan Weiss <jw@innerewut.de> distributed under the BSD license. 
 *
 * Unlike other libraries it does not declare its own tooltip 
 * div or window. It relies on an already existing div or element defined by you to display as 
 * the tooltip. This element will be placed (and shown) near the mouse pointer when a trigger-element is moused-over.
 * 
 *
 * Usage: 
 *   <script src="/javascripts/prototype.js" type="text/javascript"></script>
 *   <script src="/javascripts/tooltip.js" type="text/javascript"></script>
 *   <script type="text/javascript">
 *     var my_tooltip = new Tooltip('id_of_trigger_element', 'id_of_tooltip_to_show_element')
 *   </script>
 * 
 * Now whenever you trigger a mouseOver on the `trigger` element, the tooltip element will
 * be shown. On o mouseOut the tooltip disappears. 
 * 
 * Example:
 * 
 *   <script src="/javascripts/prototype.js" type="text/javascript"></script>
 *   <script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
 *   <script src="/javascripts/tooltip.js" type="text/javascript"></script>
 *
 *   <div id='tooltip' style="display:none; margin: 5px; background-color: red;">
 *     Detail infos on product 1....<br />
 *   </div>
 *
 *   <div id='product_1'>
 *     This is product 1
 *   </div>
 *
 *   <script type="text/javascript">
 *     var my_tooltip = new Tooltip('product_1', 'tooltip')
 *   </script>
 *
 * You can use my_tooltip.destroy() to remove the event observers and thereby the tooltip.
 */

var Tooltip = Class.create();
Tooltip.prototype = {
	initialize: function (element, tool_tip) {
		var options = Object.extend({
			default_css: false,
			margin: "0px",
			padding: "5px",
			backgroundColor: "#d6d6fc",
			delta_x: 5,
			delta_y: 5,
			zindex: 1000,
			timeout: 5000
		}, arguments[1] || {});

		this.element = $(element);
		this.tool_tip = $(tool_tip);

		this.options = options;

		// hide the tool-tip by default
		this.tool_tip.hide();

		this.eventMouseOver = this.showTooltip.bindAsEventListener(this);
		this.eventMouseOut = this.hideTooltip.bindAsEventListener(this);

		this.registerEvents();
	},

	destroy: function () {
		Event.stopObserving(this.element, "mouseover", this.eventMouseOver);
		Event.stopObserving(this.element, "mouseout", this.eventMouseOut);
	},

	registerEvents: function () {
		Event.observe(this.element, "mouseover", this.eventMouseOver);
		Event.observe(this.element, "mouseout", this.eventMouseOut);
	},

	showTooltip: function (event) {
		Event.stop(event);
		// get Mouse position
		var mouse_x = Event.pointerX(event);
		var mouse_y = Event.pointerY(event);


		// decide if wee need to switch sides for the tooltip
		var dimensions = Element.getDimensions(this.tool_tip);
		var element_width = dimensions.width;
		var element_height = dimensions.height;

		if ((element_width + mouse_x) >= (this.getWindowWidth() - this.options.delta_x)) { // too big for X
			mouse_x = mouse_x - element_width;
			// apply delta to make sure that the mouse is not on the tool-tip
			mouse_x = mouse_x - this.options.delta_x;
		} else {
			mouse_x = mouse_x + this.options.delta_x;
		}

		if ((element_height + mouse_y) >= (this.getWindowHeight() - this.options.delta_y)) { // too big for Y
			mouse_y = mouse_y - element_height;
			// apply delta to make sure that the mouse is not on the tool-tip
			mouse_y = mouse_y - this.options.delta_y;
		} else {
			mouse_y = mouse_y + this.options.delta_y;
		}

		// now set the right styles
		this.setStyles(mouse_x, mouse_y);


		// finally show the Tooltip
		//new Effect.Appear(this.tool_tip);
		Element.show(this.tool_tip);
		Tooltip.active = this.tool_tip;
		setTimeout("Element.hide(Tooltip.active)", this.options.timeout);
	},

	setStyles: function (x, y) {
		// set the right styles to position the tool tip
		Element.setStyle(this.tool_tip, { position: 'absolute',
			top: y + "px",
			left: x + "px",
			zindex: this.options.zindex
		});

		// apply default theme if wanted
		if (this.options.default_css) {
			Element.setStyle(this.tool_tip, { margin: this.options.margin,
				padding: this.options.padding,
				backgroundColor: this.options.backgroundColor,
				zindex: this.options.zindex
			});
		}
	},

	hideTooltip: function (event) {
		//new Effect.Fade(this.tool_tip);
		Element.hide(this.tool_tip);
	},

	getWindowHeight: function () {
		var innerHeight;
		if (navigator.appVersion.indexOf('MSIE') > 0) {
			innerHeight = document.body.clientHeight;
		} else {
			innerHeight = window.innerHeight;
		}
		return innerHeight;
	},

	getWindowWidth: function () {
		var innerWidth;
		if (navigator.appVersion.indexOf('MSIE') > 0) {
			innerWidth = document.body.clientWidth;
		} else {
			innerWidth = window.innerWidth;
		}
		return innerWidth;
	}

}

/// <reference path="../../prototype/1.6.1.0/prototype.js" />
/// <reference path="common.js" />
Seips.Validation = Class.create({
	initialize: function (form) {

		if ($(form)) {
			// need a collection for custom validators that can be attached as requirements for form submission
			var customValidators = $A();
			this.customValidators = customValidators;
			this.formName = form;

			$(form).getElements().each(function (el) { el.validators = $A(); });

			var local = this;

			// required fields
			$(form).select(".v-required").each(function (el) {
				// local.CheckRequired(el);
				if (el.tagName.toLowerCase() == "span") {
					el.select("input").each(function (el2) {
						el2.observe("blur", local.blurRequired.bindAsEventListener(local));
						el2.validators.push(local.CheckRequired.curry(el2));
					});
				} else {
					el.observe("blur", local.blurRequired.bindAsEventListener(local));
					el.validators.push(local.CheckRequired.curry(el));
					el.writeAttribute("aria-required", "true");
				}
			});


			// email fields
			$(form).select(".v-email").each(function (el) {
				// local.CheckEmail(el);
				el.observe("blur", local.blurEmail.bindAsEventListener(local));
				el.validators.push(local.CheckEmail.curry(el));
			});

			// matching fields
			$(form).select(".v-match").each(function (el) {
				// local.CheckMatch(el);
				el.observe("blur", local.blurMatch.bindAsEventListener(local));
				local.getMatchField(el).observe("blur", local.blurMatch.bindAsEventListener(local));
				el.validators.push(local.CheckMatch.curry(el).bind(local));
			});

			// numeric
			$(form).select(".v-numeric").each(function (el) {
				// local.CheckNumeric(el);
				el.observe("blur", local.blurNumeric.bindAsEventListener(local));
				el.validators.push(local.CheckNumeric.curry(el));
			});

			// date
			$(form).select(".v-date").each(function (el) {
				// local.CheckDate(el);
				el.observe("blur", local.blurDate.bindAsEventListener(local));
				el.validators.push(local.CheckDate.curry(el));
			});

			// url
			$(form).select(".v-url").each(function (el) {
				el.observe("blur", local.blurUrl.bindAsEventListener(local));
				el.validators.push(local.CheckUrl.curry(el));
			});

			// maxLength
			$(form).select(".v-length").each(function (el) {
				el.validators.push(local.CheckLength.curry(el));
				el.observe("keyup", local.blurLength.bindAsEventListener(local));
			});

			$(form).observe("submit", this.formSubmitValidation.bindAsEventListener(this));
		}
	},
	formSubmitValidation: function (evt) {
		if (!this.CheckFormIsValid(this.formName)) {
			evt.stop();
			Seips.ConfirmDialog.show("Error", "Fix highlighted form errors/missing values.");
		}
	},
	CheckFormIsValid: function (form) {
		form = $(form);
		form.getElements().each(
			function (el) {
				el.validators.each(
					function (f) { f(); }
				);
			}
		);
		var valid = true;
		valid = valid
			&& (form.select(".error-r").length == 0)
			&& (form.select(".error-m").length == 0)
			&& (form.select(".error-e").length == 0)
			&& (form.select(".error-n").length == 0)
			&& (form.select(".error-l").length == 0);
		if (this.customValidators != undefined && this.customValidators != null) {
			this.customValidators.each(function (v) {
				valid = valid && v.check();
			});
		}
		return valid;
	},
	destroy: function () {
	},
	blurRequired: function (evt) {
		this.CheckRequired($(evt.element()));
	},
	blurEmail: function (evt) {
		this.CheckEmail($(evt.element()));
	},
	blurMatch: function (evt) {
		this.CheckMatch($(evt.element()));
	},
	blurNumeric: function (evt) {
		this.CheckNumeric($(evt.element()));
	},
	blurDate: function (evt) {
		this.CheckDate($(evt.element()));
	},
	blurUrl: function (evt) {
		this.CheckUrl($(evt.element()));
	},
	blurLength: function (evt) {
		this.CheckLength($(evt.element()));
	},
	CheckLength: function (el) {
		var valid = true;
		var value = el.value.strip();

		var maxlength = 0;
		if (value != "") {
			var classes = el.className.split(" ");
			var max = classes.find(function (s) { return s.startsWith("vchars-"); });
			if (max != null && max != undefined) {
				max = max.replace("vchars-", "");
				if (value.length > max) valid = false;
			}
		}
		var container = el.up("div.fBlock");
		if (!valid) {
			container.addClassName("error-l");
			el.writeAttribute("aria-invalid", "true");
			if (container.select("p").length == 0) {
				container.insert("<p class='error'>! Max: 500 characters.</p>");
			}
		} else {
			container.removeClassName("error-l");
			el.writeAttribute("aria-invalid", "false");
			container.select("p").invoke("remove");
		}
	},
	CheckUrl: function (el) {
		var url = el.value.strip();
		if (url != "" && url.indexOf("/") != 0 && url.indexOf("http://") != 0 && url.indexOf("mailto:") != 0 && url.indexOf("https://") != 0 && url.indexOf("ftp://") != 0) {
			el.value = "http://" + url;
		}
	},
	CheckDate: function (el) {
		var valid = true;
		valid = (el.value != "") ? (!isNaN(Date.parse(el.value))) : true;
		var container = el.up("div.fBlock");
		if (!valid) {
			container.addClassName("error-d");
			el.writeAttribute("aria-invalid", "true");
			
		} else {
			container.removeClassName("error-d");
			el.writeAttribute("aria-invalid", "false");
			
		}
	},
	CheckNumeric: function (el) {
		var valid = true;
		valid = (el.value != "") ? (parseFloat(el.value).toString() == el.value) : true;
		var container = el.up("div.fBlock");
		if (!valid) {
			container.addClassName("error-n");
			el.writeAttribute("aria-invalid", "true");
		} else {
			container.removeClassName("error-n");
			el.writeAttribute("aria-invalid", "false");
		}
	},
	CheckEmail: function (el) {
		var valid = true;
		valid = (el.value != null && el.value.strip() != '' && el.value.indexOf("@") > 0);
		var container = el.up("div.fBlock");
		if (!valid) {
			container.addClassName("error-e");
			el.writeAttribute("aria-invalid", "true");
		} else {
			container.removeClassName("error-e");
			el.writeAttribute("aria-invalid", "false");
		}
	},
	CheckMatch: function (el) {
		var valid = true;
		var matchField = this.getMatchField(el);
		if ($(el).offsetHeight > 0)
			valid = (matchField.value == el.value);

		var container = $(el.up("div.fBlock"));
		var matchContainer = $(matchField.up("div.fBlock"));
		if (!valid) {
			container.addClassName("error-m");
			matchContainer.addClassName("error-m");
			el.writeAttribute("aria-invalid", "true");
		} else {
			container.removeClassName("error-m");
			matchContainer.removeClassName("error-m");
			el.writeAttribute("aria-invalid", "false");
		}
	},
	getMatchField: function (el) {
		var classes = el.className.split(" ");
		var matchField = classes.find(function (s) { return s.startsWith("m-"); });
		if (matchField != null && matchField != undefined) {
			matchField = matchField.replace("m-", "");
		} else {
			// this is not the field with the match validation rule, so find field that references this field as a match validation
			matchField = $(el.up("form")).select(".m-" + el.id)[0].id;
		}
		return $(matchField);
	},
	CheckRequired: function (el) {
		var tag = el.tagName.toLowerCase();
		var valid = true;

		if ($(el).offsetHeight > 0)
			switch (tag) {
				case 'input':
					switch (el.type.toLowerCase()) {
						case 'text':
							valid = (el.value != null && el.value.strip() != '');
							break;
						case 'radio':
							// check at least one radio in containing scope is checked
							var group = $(el).up(".fBlock").select("input[type=radio]");
							valid = group.any(function (r) { return r.checked; });
							break;
						case 'checkbox':
							break;
					}
					break;
				case 'select':
					valid = ($F(el) != '');
					break;
				case 'textarea':
					valid = (el.value != null && el.value.strip() != '');
					break;
			}
		var container = el.up("div.fBlock");
		if (!valid) {
			container.addClassName("error-r");
			el.writeAttribute("aria-invalid", "true");
		} else {
			container.removeClassName("error-r");
			el.writeAttribute("aria-invalid", "false");
		}
	}

});


