

/*  Copyright Mihai Bazon, 2002-2005  |  www.bazon.net/mishoo
 * -----------------------------------------------------------
 *
 * The DHTML Calendar, version 1.0 "It is happening again"
 *
 * Details and latest version at:
 * www.dynarch.com/projects/calendar
 *
 * This script is developed by Dynarch.com.  Visit us at www.dynarch.com.
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 */

// $Id: calendar.js,v 1.51 2005/03/07 16:44:31 mishoo Exp $

/** The Calendar object constructor. */
Calendar = function (firstDayOfWeek, dateStr, onSelected, onClose) {
	// member variables
	this.activeDiv = null;
	this.currentDateEl = null;
	this.getDateStatus = null;
	this.getDateToolTip = null;
	this.getDateText = null;
	this.timeout = null;
	this.onSelected = onSelected || null;
	this.onClose = onClose || null;
	this.dragging = false;
	this.hidden = false;
	this.minYear = 1970;
	this.maxYear = 2050;
	this.dateFormat = Calendar._TT["DEF_DATE_FORMAT"];
	this.ttDateFormat = Calendar._TT["TT_DATE_FORMAT"];
	this.isPopup = true;
	this.weekNumbers = true;
	this.firstDayOfWeek = typeof firstDayOfWeek == "number" ? firstDayOfWeek : Calendar._FD; // 0 for Sunday, 1 for Monday, etc.
	this.showsOtherMonths = false;
	this.dateStr = dateStr;
	this.ar_days = null;
	this.showsTime = false;
	this.time24 = true;
	this.yearStep = 2;
	this.hiliteToday = true;
	this.multiple = null;
	// HTML elements
	this.table = null;
	this.element = null;
	this.tbody = null;
	this.firstdayname = null;
	// Combo boxes
	this.monthsCombo = null;
	this.yearsCombo = null;
	this.hilitedMonth = null;
	this.activeMonth = null;
	this.hilitedYear = null;
	this.activeYear = null;
	// Information
	this.dateClicked = false;

	// one-time initializations
	if (typeof Calendar._SDN == "undefined") {
		// table of short day names
		if (typeof Calendar._SDN_len == "undefined")
			Calendar._SDN_len = 3;
		var ar = new Array();
		for (var i = 8; i > 0;) {
			ar[--i] = Calendar._DN[i].substr(0, Calendar._SDN_len);
		}
		Calendar._SDN = ar;
		// table of short month names
		if (typeof Calendar._SMN_len == "undefined")
			Calendar._SMN_len = 3;
		ar = new Array();
		for (var i = 12; i > 0;) {
			ar[--i] = Calendar._MN[i].substr(0, Calendar._SMN_len);
		}
		Calendar._SMN = ar;
	}
};

// ** constants

/// "static", needed for event handlers.
Calendar._C = null;

/// detect a special case of "web browser"
Calendar.is_ie = ( /msie/i.test(navigator.userAgent) &&
		   !/opera/i.test(navigator.userAgent) );

Calendar.is_ie5 = ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );

/// detect Opera browser
Calendar.is_opera = /opera/i.test(navigator.userAgent);

/// detect KHTML-based browsers
Calendar.is_khtml = /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

// BEGIN: UTILITY FUNCTIONS; beware that these might be moved into a separate
//        library, at some point.

Calendar.getAbsolutePos = function(el) {
	var SL = 0, ST = 0;
	var is_div = /^div$/i.test(el.tagName);
	if (is_div && el.scrollLeft)
		SL = el.scrollLeft;
	if (is_div && el.scrollTop)
		ST = el.scrollTop;
	var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
	if (el.offsetParent) {
		var tmp = this.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
};

Calendar.isRelated = function (el, evt) {
	var related = evt.relatedTarget;
	if (!related) {
		var type = evt.type;
		if (type == "mouseover") {
			related = evt.fromElement;
		} else if (type == "mouseout") {
			related = evt.toElement;
		}
	}
	while (related) {
		if (related == el) {
			return true;
		}
		related = related.parentNode;
	}
	return false;
};

Calendar.removeClass = function(el, className) {
	if (!(el && el.className)) {
		return;
	}
	var cls = el.className.split(" ");
	var ar = new Array();
	for (var i = cls.length; i > 0;) {
		if (cls[--i] != className) {
			ar[ar.length] = cls[i];
		}
	}
	el.className = ar.join(" ");
};

Calendar.addClass = function(el, className) {
	Calendar.removeClass(el, className);
	el.className += " " + className;
};

// FIXME: the following 2 functions totally suck, are useless and should be replaced immediately.
Calendar.getElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.currentTarget;
	while (f.nodeType != 1 || /^div$/i.test(f.tagName))
		f = f.parentNode;
	return f;
};

Calendar.getTargetElement = function(ev) {
	var f = Calendar.is_ie ? window.event.srcElement : ev.target;
	while (f.nodeType != 1)
		f = f.parentNode;
	return f;
};

Calendar.stopEvent = function(ev) {
	ev || (ev = window.event);
	if (Calendar.is_ie) {
		ev.cancelBubble = true;
		ev.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
};

Calendar.addEvent = function(el, evname, func) {
	if (el.attachEvent) { // IE
		el.attachEvent("on" + evname, func);
	} else if (el.addEventListener) { // Gecko / W3C
		el.addEventListener(evname, func, true);
	} else {
		el["on" + evname] = func;
	}
};

Calendar.removeEvent = function(el, evname, func) {
	if (el.detachEvent) { // IE
		el.detachEvent("on" + evname, func);
	} else if (el.removeEventListener) { // Gecko / W3C
		el.removeEventListener(evname, func, true);
	} else {
		el["on" + evname] = null;
	}
};

Calendar.createElement = function(type, parent) {
	var el = null;
	if (document.createElementNS) {
		// use the XHTML namespace; IE won't normally get here unless
		// _they_ "fix" the DOM2 implementation.
		el = document.createElementNS("http://www.w3.org/1999/xhtml", type);
	} else {
		el = document.createElement(type);
	}
	if (typeof parent != "undefined") {
		parent.appendChild(el);
	}
	return el;
};

// END: UTILITY FUNCTIONS

// BEGIN: CALENDAR STATIC FUNCTIONS

/** Internal -- adds a set of events to make some element behave like a button. */
Calendar._add_evs = function(el) {
	with (Calendar) {
		addEvent(el, "mouseover", dayMouseOver);
		addEvent(el, "mousedown", dayMouseDown);
		addEvent(el, "mouseout", dayMouseOut);
		if (is_ie) {
			addEvent(el, "dblclick", dayMouseDblClick);
			el.setAttribute("unselectable", true);
		}
	}
};

Calendar.findMonth = function(el) {
	if (typeof el.month != "undefined") {
		return el;
	} else if (typeof el.parentNode.month != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.findYear = function(el) {
	if (typeof el.year != "undefined") {
		return el;
	} else if (typeof el.parentNode.year != "undefined") {
		return el.parentNode;
	}
	return null;
};

Calendar.showMonthsCombo = function () {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var mc = cal.monthsCombo;
	if (cal.hilitedMonth) {
		Calendar.removeClass(cal.hilitedMonth, "hilite");
	}
	if (cal.activeMonth) {
		Calendar.removeClass(cal.activeMonth, "active");
	}
	var mon = cal.monthsCombo.getElementsByTagName("div")[cal.date.getMonth()];
	Calendar.addClass(mon, "active");
	cal.activeMonth = mon;
	var s = mc.style;
	s.display = "block";
	if (cd.navtype < 0)
		s.left = cd.offsetLeft + "px";
	else {
		var mcw = mc.offsetWidth;
		if (typeof mcw == "undefined")
			// Konqueror brain-dead techniques
			mcw = 50;
		s.left = (cd.offsetLeft + cd.offsetWidth - mcw) + "px";
	}
	s.top = (cd.offsetTop + cd.offsetHeight) + "px";
};

Calendar.showYearsCombo = function (fwd) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	var cal = cal;
	var cd = cal.activeDiv;
	var yc = cal.yearsCombo;
	if (cal.hilitedYear) {
		Calendar.removeClass(cal.hilitedYear, "hilite");
	}
	if (cal.activeYear) {
		Calendar.removeClass(cal.activeYear, "active");
	}
	cal.activeYear = null;
	var Y = cal.date.getFullYear() + (fwd ? 1 : -1);
	var yr = yc.firstChild;
	var show = false;
	for (var i = 12; i > 0; --i) {
		if (Y >= cal.minYear && Y <= cal.maxYear) {
			yr.innerHTML = Y;
			yr.year = Y;
			yr.style.display = "block";
			show = true;
		} else {
			yr.style.display = "none";
		}
		yr = yr.nextSibling;
		Y += fwd ? cal.yearStep : -cal.yearStep;
	}
	if (show) {
		var s = yc.style;
		s.display = "block";
		if (cd.navtype < 0)
			s.left = cd.offsetLeft + "px";
		else {
			var ycw = yc.offsetWidth;
			if (typeof ycw == "undefined")
				// Konqueror brain-dead techniques
				ycw = 50;
			s.left = (cd.offsetLeft + cd.offsetWidth - ycw) + "px";
		}
		s.top = (cd.offsetTop + cd.offsetHeight) + "px";
	}
};

// event handlers

Calendar.tableMouseUp = function(ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	if (cal.timeout) {
		clearTimeout(cal.timeout);
	}
	var el = cal.activeDiv;
	if (!el) {
		return false;
	}
	var target = Calendar.getTargetElement(ev);
	ev || (ev = window.event);
	Calendar.removeClass(el, "active");
	if (target == el || target.parentNode == el) {
		Calendar.cellClick(el, ev);
	}
	var mon = Calendar.findMonth(target);
	var date = null;
	if (mon) {
		date = new Date(cal.date);
		if (mon.month != date.getMonth()) {
			date.setMonth(mon.month);
			cal.setDate(date);
			cal.dateClicked = false;
			cal.callHandler();
		}
	} else {
		var year = Calendar.findYear(target);
		if (year) {
			date = new Date(cal.date);
			if (year.year != date.getFullYear()) {
				date.setFullYear(year.year);
				cal.setDate(date);
				cal.dateClicked = false;
				cal.callHandler();
			}
		}
	}
	with (Calendar) {
		removeEvent(document, "mouseup", tableMouseUp);
		removeEvent(document, "mouseover", tableMouseOver);
		removeEvent(document, "mousemove", tableMouseOver);
		cal._hideCombos();
		_C = null;
		return stopEvent(ev);
	}
};

Calendar.tableMouseOver = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return;
	}
	var el = cal.activeDiv;
	var target = Calendar.getTargetElement(ev);
	if (target == el || target.parentNode == el) {
		Calendar.addClass(el, "hilite active");
		Calendar.addClass(el.parentNode, "rowhilite");
	} else {
		if (typeof el.navtype == "undefined" || (el.navtype != 50 && (el.navtype == 0 || Math.abs(el.navtype) > 2)))
			Calendar.removeClass(el, "active");
		Calendar.removeClass(el, "hilite");
		Calendar.removeClass(el.parentNode, "rowhilite");
	}
	ev || (ev = window.event);
	if (el.navtype == 50 && target != el) {
		var pos = Calendar.getAbsolutePos(el);
		var w = el.offsetWidth;
		var x = ev.clientX;
		var dx;
		var decrease = true;
		if (x > pos.x + w) {
			dx = x - pos.x - w;
			decrease = false;
		} else
			dx = pos.x - x;

		if (dx < 0) dx = 0;
		var range = el._range;
		var current = el._current;
		var count = Math.floor(dx / 10) % range.length;
		for (var i = range.length; --i >= 0;)
			if (range[i] == current)
				break;
		while (count-- > 0)
			if (decrease) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
		var newval = range[i];
		el.innerHTML = newval;

		cal.onUpdateTime();
	}
	var mon = Calendar.findMonth(target);
	if (mon) {
		if (mon.month != cal.date.getMonth()) {
			if (cal.hilitedMonth) {
				Calendar.removeClass(cal.hilitedMonth, "hilite");
			}
			Calendar.addClass(mon, "hilite");
			cal.hilitedMonth = mon;
		} else if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
	} else {
		if (cal.hilitedMonth) {
			Calendar.removeClass(cal.hilitedMonth, "hilite");
		}
		var year = Calendar.findYear(target);
		if (year) {
			if (year.year != cal.date.getFullYear()) {
				if (cal.hilitedYear) {
					Calendar.removeClass(cal.hilitedYear, "hilite");
				}
				Calendar.addClass(year, "hilite");
				cal.hilitedYear = year;
			} else if (cal.hilitedYear) {
				Calendar.removeClass(cal.hilitedYear, "hilite");
			}
		} else if (cal.hilitedYear) {
			Calendar.removeClass(cal.hilitedYear, "hilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.tableMouseDown = function (ev) {
	if (Calendar.getTargetElement(ev) == Calendar.getElement(ev)) {
		return Calendar.stopEvent(ev);
	}
};

Calendar.calDragIt = function (ev) {
	var cal = Calendar._C;
	if (!(cal && cal.dragging)) {
		return false;
	}
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posX = ev.pageX;
		posY = ev.pageY;
	}
	cal.hideShowCovered();
	var st = cal.element.style;
	st.left = (posX - cal.xOffs) + "px";
	st.top = (posY - cal.yOffs) + "px";
	return Calendar.stopEvent(ev);
};

Calendar.calDragEnd = function (ev) {
	var cal = Calendar._C;
	if (!cal) {
		return false;
	}
	cal.dragging = false;
	with (Calendar) {
		removeEvent(document, "mousemove", calDragIt);
		removeEvent(document, "mouseup", calDragEnd);
		tableMouseUp(ev);
	}
	cal.hideShowCovered();
};

Calendar.dayMouseDown = function(ev) {
	var el = Calendar.getElement(ev);
	if (el.disabled) {
		return false;
	}
	var cal = el.calendar;
	cal.activeDiv = el;
	Calendar._C = cal;
	if (el.navtype != 300) with (Calendar) {
		if (el.navtype == 50) {
			el._current = el.innerHTML;
			addEvent(document, "mousemove", tableMouseOver);
		} else
			addEvent(document, Calendar.is_ie5 ? "mousemove" : "mouseover", tableMouseOver);
		addClass(el, "hilite active");
		addEvent(document, "mouseup", tableMouseUp);
	} else if (cal.isPopup) {
		cal._dragStart(ev);
	}
	if (el.navtype == -1 || el.navtype == 1) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout("Calendar.showMonthsCombo()", 250);
	} else if (el.navtype == -2 || el.navtype == 2) {
		if (cal.timeout) clearTimeout(cal.timeout);
		cal.timeout = setTimeout((el.navtype > 0) ? "Calendar.showYearsCombo(true)" : "Calendar.showYearsCombo(false)", 250);
	} else {
		cal.timeout = null;
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseDblClick = function(ev) {
	Calendar.cellClick(Calendar.getElement(ev), ev || window.event);
	if (Calendar.is_ie) {
		document.selection.empty();
	}
};

Calendar.dayMouseOver = function(ev) {
	var el = Calendar.getElement(ev);
	if (Calendar.isRelated(el, ev) || Calendar._C || el.disabled) {
		return false;
	}
	if (el.ttip) {
		if (el.ttip.substr(0, 1) == "_") {
			el.ttip = el.caldate.print(el.calendar.ttDateFormat) + el.ttip.substr(1);
		}
		el.calendar.tooltips.innerHTML = el.ttip;
	}
	if (el.navtype != 300) {
		Calendar.addClass(el, "hilite");
		if (el.caldate) {
			Calendar.addClass(el.parentNode, "rowhilite");
		}
	}
	return Calendar.stopEvent(ev);
};

Calendar.dayMouseOut = function(ev) {
	with (Calendar) {
		var el = getElement(ev);
		if (isRelated(el, ev) || _C || el.disabled)
			return false;
		removeClass(el, "hilite");
		if (el.caldate)
			removeClass(el.parentNode, "rowhilite");
		if (el.calendar)
			el.calendar.tooltips.innerHTML = _TT["SEL_DATE"];
		return stopEvent(ev);
	}
};

/**
 *  A generic "click" handler :) handles all types of buttons defined in this
 *  calendar.
 */
Calendar.cellClick = function(el, ev) {
	var cal = el.calendar;
	var closing = false;
	var newdate = false;
	var date = null;
	if (typeof el.navtype == "undefined") {
		if (cal.currentDateEl) {
			Calendar.removeClass(cal.currentDateEl, "selected");
			Calendar.addClass(el, "selected");
			closing = (cal.currentDateEl == el);
			if (!closing) {
				cal.currentDateEl = el;
			}
		}
		cal.date.setDateOnly(el.caldate);
		date = cal.date;
		var other_month = !(cal.dateClicked = !el.otherMonth);
		if (!other_month && !cal.currentDateEl)
			cal._toggleMultipleDate(new Date(date));
		else
			newdate = !el.disabled;
		// a date was clicked
		if (other_month)
			cal._init(cal.firstDayOfWeek, date);
	} else {
		if (el.navtype == 200) {
			Calendar.removeClass(el, "hilite");
			cal.callCloseHandler();
			return;
		}
		date = new Date(cal.date);
		if (el.navtype == 0)
			date.setDateOnly(new Date()); // TODAY
		// unless "today" was clicked, we assume no date was clicked so
		// the selected handler will know not to close the calenar when
		// in single-click mode.
		// cal.dateClicked = (el.navtype == 0);
		cal.dateClicked = false;
		var year = date.getFullYear();
		var mon = date.getMonth();
		function setMonth(m) {
			var day = date.getDate();
			var max = date.getMonthDays(m);
			if (day > max) {
				date.setDate(max);
			}
			date.setMonth(m);
		};
		switch (el.navtype) {
		    case 400:
			Calendar.removeClass(el, "hilite");
			var text = Calendar._TT["ABOUT"];
			if (typeof text != "undefined") {
				text += cal.showsTime ? Calendar._TT["ABOUT_TIME"] : "";
			} else {
				// FIXME: this should be removed as soon as lang files get updated!
				text = "Help and about box text is not translated into this language.\n" +
					"If you know this language and you feel generous please update\n" +
					"the corresponding file in \"lang\" subdir to match calendar-en.js\n" +
					"and send it back to <mihai_bazon@yahoo.com> to get it into the distribution  ;-)\n\n" +
					"Thank you!\n" +
					"http://dynarch.com/mishoo/calendar.epl\n";
			}
			alert(text);
			return;
		    case -2:
			if (year > cal.minYear) {
				date.setFullYear(year - 1);
			}
			break;
		    case -1:
			if (mon > 0) {
				setMonth(mon - 1);
			} else if (year-- > cal.minYear) {
				date.setFullYear(year);
				setMonth(11);
			}
			break;
		    case 1:
			if (mon < 11) {
				setMonth(mon + 1);
			} else if (year < cal.maxYear) {
				date.setFullYear(year + 1);
				setMonth(0);
			}
			break;
		    case 2:
			if (year < cal.maxYear) {
				date.setFullYear(year + 1);
			}
			break;
		    case 100:
			cal.setFirstDayOfWeek(el.fdow);
			return;
		    case 50:
			var range = el._range;
			var current = el.innerHTML;
			for (var i = range.length; --i >= 0;)
				if (range[i] == current)
					break;
			if (ev && ev.shiftKey) {
				if (--i < 0)
					i = range.length - 1;
			} else if ( ++i >= range.length )
				i = 0;
			var newval = range[i];
			el.innerHTML = newval;
			cal.onUpdateTime();
			return;
		    case 0:
			// TODAY will bring us here
			if ((typeof cal.getDateStatus == "function") &&
			    cal.getDateStatus(date, date.getFullYear(), date.getMonth(), date.getDate())) {
				return false;
			}
			break;
		}
		if (!date.equalsTo(cal.date)) {
			cal.setDate(date);
			newdate = true;
		} else if (el.navtype == 0)
			newdate = closing = true;
	}
	if (newdate) {
		ev && cal.callHandler();
	}
	if (closing) {
		Calendar.removeClass(el, "hilite");
		ev && cal.callCloseHandler();
	}
};

// END: CALENDAR STATIC FUNCTIONS

// BEGIN: CALENDAR OBJECT FUNCTIONS

/**
 *  This function creates the calendar inside the given parent.  If _par is
 *  null than it creates a popup calendar inside the BODY element.  If _par is
 *  an element, be it BODY, then it creates a non-popup calendar (still
 *  hidden).  Some properties need to be set before calling this function.
 */
Calendar.prototype.create = function (_par) {
	var parent = null;
	if (! _par) {
		// default parent is the document body, in which case we create
		// a popup calendar.
		parent = document.getElementsByTagName("body")[0];
		this.isPopup = true;
	} else {
		parent = _par;
		this.isPopup = false;
	}
	this.date = this.dateStr ? new Date(this.dateStr) : new Date();

	var table = Calendar.createElement("table");
	this.table = table;
	table.cellSpacing = 0;
	table.cellPadding = 0;
	table.calendar = this;
	Calendar.addEvent(table, "mousedown", Calendar.tableMouseDown);

	var div = Calendar.createElement("div");
	this.element = div;
	div.className = "calendar";
	if (this.isPopup) {
		div.style.position = "absolute";
		div.style.display = "none";
	}
	div.appendChild(table);

	var thead = Calendar.createElement("thead", table);
	var cell = null;
	var row = null;

	var cal = this;
	var hh = function (text, cs, navtype) {
		cell = Calendar.createElement("td", row);
		cell.colSpan = cs;
		cell.className = "button";
		if (navtype != 0 && Math.abs(navtype) <= 2)
			cell.className += " nav";
		Calendar._add_evs(cell);
		cell.calendar = cal;
		cell.navtype = navtype;
		cell.innerHTML = "<div unselectable='on'>" + text + "</div>";
		return cell;
	};

	row = Calendar.createElement("tr", thead);
	var title_length = 6;
	(this.isPopup) && --title_length;
	(this.weekNumbers) && ++title_length;

	hh("?", 1, 400).ttip = Calendar._TT["INFO"];
	this.title = hh("", title_length, 300);
	this.title.className = "title";
	if (this.isPopup) {
		this.title.ttip = Calendar._TT["DRAG_TO_MOVE"];
		this.title.style.cursor = "move";
		hh("&#x00d7;", 1, 200).ttip = Calendar._TT["CLOSE"];
	}

	row = Calendar.createElement("tr", thead);
	row.className = "headrow";

	this._nav_py = hh("&#x00ab;", 1, -2);
	this._nav_py.ttip = Calendar._TT["PREV_YEAR"];

	this._nav_pm = hh("&#x2039;", 1, -1);
	this._nav_pm.ttip = Calendar._TT["PREV_MONTH"];

	this._nav_now = hh(Calendar._TT["TODAY"], this.weekNumbers ? 4 : 3, 0);
	this._nav_now.ttip = Calendar._TT["GO_TODAY"];

	this._nav_nm = hh("&#x203a;", 1, 1);
	this._nav_nm.ttip = Calendar._TT["NEXT_MONTH"];

	this._nav_ny = hh("&#x00bb;", 1, 2);
	this._nav_ny.ttip = Calendar._TT["NEXT_YEAR"];

	// day names
	row = Calendar.createElement("tr", thead);
	row.className = "daynames";
	if (this.weekNumbers) {
		cell = Calendar.createElement("td", row);
		cell.className = "name wn";
		cell.innerHTML = Calendar._TT["WK"];
	}
	for (var i = 7; i > 0; --i) {
		cell = Calendar.createElement("td", row);
		if (!i) {
			cell.navtype = 100;
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}
	this.firstdayname = (this.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
	this._displayWeekdays();

	var tbody = Calendar.createElement("tbody", table);
	this.tbody = tbody;

	for (i = 6; i > 0; --i) {
		row = Calendar.createElement("tr", tbody);
		if (this.weekNumbers) {
			cell = Calendar.createElement("td", row);
		}
		for (var j = 7; j > 0; --j) {
			cell = Calendar.createElement("td", row);
			cell.calendar = this;
			Calendar._add_evs(cell);
		}
	}

	if (this.showsTime) {
		row = Calendar.createElement("tr", tbody);
		row.className = "time";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = 2;
		cell.innerHTML = Calendar._TT["TIME"] || "&nbsp;";

		cell = Calendar.createElement("td", row);
		cell.className = "time";
		cell.colSpan = this.weekNumbers ? 4 : 3;

		(function(){
			function makeTimePart(className, init, range_start, range_end) {
				var part = Calendar.createElement("span", cell);
				part.className = className;
				part.innerHTML = init;
				part.calendar = cal;
				part.ttip = Calendar._TT["TIME_PART"];
				part.navtype = 50;
				part._range = [];
				if (typeof range_start != "number")
					part._range = range_start;
				else {
					for (var i = range_start; i <= range_end; ++i) {
						var txt;
						if (i < 10 && range_end >= 10) txt = '0' + i;
						else txt = '' + i;
						part._range[part._range.length] = txt;
					}
				}
				Calendar._add_evs(part);
				return part;
			};
			var hrs = cal.date.getHours();
			var mins = cal.date.getMinutes();
			var t12 = !cal.time24;
			var pm = (hrs > 12);
			if (t12 && pm) hrs -= 12;
			var H = makeTimePart("hour", hrs, t12 ? 1 : 0, t12 ? 12 : 23);
			var span = Calendar.createElement("span", cell);
			span.innerHTML = ":";
			span.className = "colon";
			var M = makeTimePart("minute", mins, 0, 59);
			var AP = null;
			cell = Calendar.createElement("td", row);
			cell.className = "time";
			cell.colSpan = 2;
			if (t12)
				AP = makeTimePart("ampm", pm ? "pm" : "am", ["am", "pm"]);
			else
				cell.innerHTML = "&nbsp;";

			cal.onSetTime = function() {
				var pm, hrs = this.date.getHours(),
					mins = this.date.getMinutes();
				if (t12) {
					pm = (hrs >= 12);
					if (pm) hrs -= 12;
					if (hrs == 0) hrs = 12;
					AP.innerHTML = pm ? "pm" : "am";
				}
				H.innerHTML = (hrs < 10) ? ("0" + hrs) : hrs;
				M.innerHTML = (mins < 10) ? ("0" + mins) : mins;
			};

			cal.onUpdateTime = function() {
				var date = this.date;
				var h = parseInt(H.innerHTML, 10);
				if (t12) {
					if (/pm/i.test(AP.innerHTML) && h < 12)
						h += 12;
					else if (/am/i.test(AP.innerHTML) && h == 12)
						h = 0;
				}
				var d = date.getDate();
				var m = date.getMonth();
				var y = date.getFullYear();
				date.setHours(h);
				date.setMinutes(parseInt(M.innerHTML, 10));
				date.setFullYear(y);
				date.setMonth(m);
				date.setDate(d);
				this.dateClicked = false;
				this.callHandler();
			};
		})();
	} else {
		this.onSetTime = this.onUpdateTime = function() {};
	}

	var tfoot = Calendar.createElement("tfoot", table);

	row = Calendar.createElement("tr", tfoot);
	row.className = "footrow";

	cell = hh(Calendar._TT["SEL_DATE"], this.weekNumbers ? 8 : 7, 300);
	cell.className = "ttip";
	if (this.isPopup) {
		cell.ttip = Calendar._TT["DRAG_TO_MOVE"];
		cell.style.cursor = "move";
	}
	this.tooltips = cell;

	div = Calendar.createElement("div", this.element);
	this.monthsCombo = div;
	div.className = "combo";
	for (i = 0; i < Calendar._MN.length; ++i) {
		var mn = Calendar.createElement("div");
		mn.className = Calendar.is_ie ? "label-IEfix" : "label";
		mn.month = i;
		mn.innerHTML = Calendar._SMN[i];
		div.appendChild(mn);
	}

	div = Calendar.createElement("div", this.element);
	this.yearsCombo = div;
	div.className = "combo";
	for (i = 12; i > 0; --i) {
		var yr = Calendar.createElement("div");
		yr.className = Calendar.is_ie ? "label-IEfix" : "label";
		div.appendChild(yr);
	}

	this._init(this.firstDayOfWeek, this.date);
	parent.appendChild(this.element);
};

/** keyboard navigation, only for popup calendars */
Calendar._keyEvent = function(ev) {
	var cal = window._dynarch_popupCalendar;
	if (!cal || cal.multiple)
		return false;
	(Calendar.is_ie) && (ev = window.event);
	var act = (Calendar.is_ie || ev.type == "keypress"),
		K = ev.keyCode;
	if (ev.ctrlKey) {
		switch (K) {
		    case 37: // KEY left
			act && Calendar.cellClick(cal._nav_pm);
			break;
		    case 38: // KEY up
			act && Calendar.cellClick(cal._nav_py);
			break;
		    case 39: // KEY right
			act && Calendar.cellClick(cal._nav_nm);
			break;
		    case 40: // KEY down
			act && Calendar.cellClick(cal._nav_ny);
			break;
		    default:
			return false;
		}
	} else switch (K) {
	    case 32: // KEY space (now)
		Calendar.cellClick(cal._nav_now);
		break;
	    case 27: // KEY esc
		act && cal.callCloseHandler();
		break;
	    case 37: // KEY left
	    case 38: // KEY up
	    case 39: // KEY right
	    case 40: // KEY down
		if (act) {
			var prev, x, y, ne, el, step;
			prev = K == 37 || K == 38;
			step = (K == 37 || K == 39) ? 1 : 7;
			function setVars() {
				el = cal.currentDateEl;
				var p = el.pos;
				x = p & 15;
				y = p >> 4;
				ne = cal.ar_days[y][x];
			};setVars();
			function prevMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() - step);
				cal.setDate(date);
			};
			function nextMonth() {
				var date = new Date(cal.date);
				date.setDate(date.getDate() + step);
				cal.setDate(date);
			};
			while (1) {
				switch (K) {
				    case 37: // KEY left
					if (--x >= 0)
						ne = cal.ar_days[y][x];
					else {
						x = 6;
						K = 38;
						continue;
					}
					break;
				    case 38: // KEY up
					if (--y >= 0)
						ne = cal.ar_days[y][x];
					else {
						prevMonth();
						setVars();
					}
					break;
				    case 39: // KEY right
					if (++x < 7)
						ne = cal.ar_days[y][x];
					else {
						x = 0;
						K = 40;
						continue;
					}
					break;
				    case 40: // KEY down
					if (++y < cal.ar_days.length)
						ne = cal.ar_days[y][x];
					else {
						nextMonth();
						setVars();
					}
					break;
				}
				break;
			}
			if (ne) {
				if (!ne.disabled)
					Calendar.cellClick(ne);
				else if (prev)
					prevMonth();
				else
					nextMonth();
			}
		}
		break;
	    case 13: // KEY enter
		if (act)
			Calendar.cellClick(cal.currentDateEl, ev);
		break;
	    default:
		return false;
	}
	return Calendar.stopEvent(ev);
};

/**
 *  (RE)Initializes the calendar to the given date and firstDayOfWeek
 */
Calendar.prototype._init = function (firstDayOfWeek, date) {
	var today = new Date(),
		TY = today.getFullYear(),
		TM = today.getMonth(),
		TD = today.getDate();
	this.table.style.visibility = "hidden";
	var year = date.getFullYear();
	if (year < this.minYear) {
		year = this.minYear;
		date.setFullYear(year);
	} else if (year > this.maxYear) {
		year = this.maxYear;
		date.setFullYear(year);
	}
	this.firstDayOfWeek = firstDayOfWeek;
	this.date = new Date(date);
	var month = date.getMonth();
	var mday = date.getDate();
	var no_days = date.getMonthDays();

	// calendar voodoo for computing the first day that would actually be
	// displayed in the calendar, even if it's from the previous month.
	// WARNING: this is magic. ;-)
	date.setDate(1);
	var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
	if (day1 < 0)
		day1 += 7;
	date.setDate(-day1);
	date.setDate(date.getDate() + 1);

	var row = this.tbody.firstChild;
	var MN = Calendar._SMN[month];
	var ar_days = this.ar_days = new Array();
	var weekend = Calendar._TT["WEEKEND"];
	var dates = this.multiple ? (this.datesCells = {}) : null;
	for (var i = 0; i < 6; ++i, row = row.nextSibling) {
		var cell = row.firstChild;
		if (this.weekNumbers) {
			cell.className = "day wn";
			cell.innerHTML = date.getWeekNumber();
			cell = cell.nextSibling;
		}
		row.className = "daysrow";
		var hasdays = false, iday, dpos = ar_days[i] = [];
		for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
			iday = date.getDate();
			var wday = date.getDay();
			cell.className = "day";
			cell.pos = i << 4 | j;
			dpos[j] = cell;
			var current_month = (date.getMonth() == month);
			if (!current_month) {
				if (this.showsOtherMonths) {
					cell.className += " othermonth";
					cell.otherMonth = true;
				} else {
					cell.className = "emptycell";
					cell.innerHTML = "&nbsp;";
					cell.disabled = true;
					continue;
				}
			} else {
				cell.otherMonth = false;
				hasdays = true;
			}
			cell.disabled = false;
			cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
			if (dates)
				dates[date.print("%Y%m%d")] = cell;
			if (this.getDateStatus) {
				var status = this.getDateStatus(date, year, month, iday);
				if (this.getDateToolTip) {
					var toolTip = this.getDateToolTip(date, year, month, iday);
					if (toolTip)
						cell.title = toolTip;
				}
				if (status === true) {
					cell.className += " disabled";
					cell.disabled = true;
				} else {
					if (/disabled/i.test(status))
						cell.disabled = true;
					cell.className += " " + status;
				}
			}
			if (!cell.disabled) {
				cell.caldate = new Date(date);
				cell.ttip = "_";
				if (!this.multiple && current_month
				    && iday == mday && this.hiliteToday) {
					cell.className += " selected";
					this.currentDateEl = cell;
				}
				if (date.getFullYear() == TY &&
				    date.getMonth() == TM &&
				    iday == TD) {
					cell.className += " today";
					cell.ttip += Calendar._TT["PART_TODAY"];
				}
				if (weekend.indexOf(wday.toString()) != -1)
					cell.className += cell.otherMonth ? " oweekend" : " weekend";
			}
		}
		if (!(hasdays || this.showsOtherMonths))
			row.className = "emptyrow";
	}
	this.title.innerHTML = Calendar._MN[month] + ", " + year;
	this.onSetTime();
	this.table.style.visibility = "visible";
	this._initMultipleDates();
	// PROFILE
	// this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
};

Calendar.prototype._initMultipleDates = function() {
	if (this.multiple) {
		for (var i in this.multiple) {
			var cell = this.datesCells[i];
			var d = this.multiple[i];
			if (!d)
				continue;
			if (cell)
				cell.className += " selected";
		}
	}
};

Calendar.prototype._toggleMultipleDate = function(date) {
	if (this.multiple) {
		var ds = date.print("%Y%m%d");
		var cell = this.datesCells[ds];
		if (cell) {
			var d = this.multiple[ds];
			if (!d) {
				Calendar.addClass(cell, "selected");
				this.multiple[ds] = date;
			} else {
				Calendar.removeClass(cell, "selected");
				delete this.multiple[ds];
			}
		}
	}
};

Calendar.prototype.setDateToolTipHandler = function (unaryFunction) {
	this.getDateToolTip = unaryFunction;
};

/**
 *  Calls _init function above for going to a certain date (but only if the
 *  date is different than the currently selected one).
 */
Calendar.prototype.setDate = function (date) {
	if (!date.equalsTo(this.date)) {
		this._init(this.firstDayOfWeek, date);
	}
};

/**
 *  Refreshes the calendar.  Useful if the "disabledHandler" function is
 *  dynamic, meaning that the list of disabled date can change at runtime.
 *  Just * call this function if you think that the list of disabled dates
 *  should * change.
 */
Calendar.prototype.refresh = function () {
	this._init(this.firstDayOfWeek, this.date);
};

/** Modifies the "firstDayOfWeek" parameter (pass 0 for Synday, 1 for Monday, etc.). */
Calendar.prototype.setFirstDayOfWeek = function (firstDayOfWeek) {
	this._init(firstDayOfWeek, this.date);
	this._displayWeekdays();
};

/**
 *  Allows customization of what dates are enabled.  The "unaryFunction"
 *  parameter must be a function object that receives the date (as a JS Date
 *  object) and returns a boolean value.  If the returned value is true then
 *  the passed date will be marked as disabled.
 */
Calendar.prototype.setDateStatusHandler = Calendar.prototype.setDisabledHandler = function (unaryFunction) {
	this.getDateStatus = unaryFunction;
};

/** Customization of allowed year range for the calendar. */
Calendar.prototype.setRange = function (a, z) {
	this.minYear = a;
	this.maxYear = z;
};

/** Calls the first user handler (selectedHandler). */
Calendar.prototype.callHandler = function () {
	if (this.onSelected) {
		this.onSelected(this, this.date.print(this.dateFormat));
	}
};

/** Calls the second user handler (closeHandler). */
Calendar.prototype.callCloseHandler = function () {
	if (this.onClose) {
		this.onClose(this);
		this.hide();
	}
	this.hideShowCovered();
};

/** Removes the calendar object from the DOM tree and destroys it. */
Calendar.prototype.destroy = function () {
	var el = this.element.parentNode;
	el.removeChild(this.element);
	Calendar._C = null;
	window._dynarch_popupCalendar = null;
};

/**
 *  Moves the calendar element to a different section in the DOM tree (changes
 *  its parent).
 */
Calendar.prototype.reparent = function (new_parent) {
	var el = this.element;
	el.parentNode.removeChild(el);
	new_parent.appendChild(el);
};

// This gets called when the user presses a mouse button anywhere in the
// document, if the calendar is shown.  If the click was outside the open
// calendar this function closes it.
Calendar._checkCalendar = function(ev) {
	var calendar = window._dynarch_popupCalendar;
	if (!calendar) {
		return false;
	}
	var el = Calendar.is_ie ? Calendar.getElement(ev) : Calendar.getTargetElement(ev);
	for (; el != null && el != calendar.element; el = el.parentNode);
	if (el == null) {
		// calls closeHandler which should hide the calendar.
		window._dynarch_popupCalendar.callCloseHandler();
		return Calendar.stopEvent(ev);
	}
};

/** Shows the calendar. */
Calendar.prototype.show = function () {
	var rows = this.table.getElementsByTagName("tr");
	for (var i = rows.length; i > 0;) {
		var row = rows[--i];
		Calendar.removeClass(row, "rowhilite");
		var cells = row.getElementsByTagName("td");
		for (var j = cells.length; j > 0;) {
			var cell = cells[--j];
			Calendar.removeClass(cell, "hilite");
			Calendar.removeClass(cell, "active");
		}
	}
	this.element.style.display = "block";
	this.hidden = false;
	if (this.isPopup) {
		window._dynarch_popupCalendar = this;
		Calendar.addEvent(document, "keydown", Calendar._keyEvent);
		Calendar.addEvent(document, "keypress", Calendar._keyEvent);
		Calendar.addEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.hideShowCovered();
};

/**
 *  Hides the calendar.  Also removes any "hilite" from the class of any TD
 *  element.
 */
Calendar.prototype.hide = function () {
	if (this.isPopup) {
		Calendar.removeEvent(document, "keydown", Calendar._keyEvent);
		Calendar.removeEvent(document, "keypress", Calendar._keyEvent);
		Calendar.removeEvent(document, "mousedown", Calendar._checkCalendar);
	}
	this.element.style.display = "none";
	this.hidden = true;
	this.hideShowCovered();
};

/**
 *  Shows the calendar at a given absolute position (beware that, depending on
 *  the calendar element style -- position property -- this might be relative
 *  to the parent's containing rectangle).
 */
Calendar.prototype.showAt = function (x, y) {
	var s = this.element.style;
	s.left = x + "px";
	s.top = y + "px";
	this.show();
};

/** Shows the calendar near a given element. */
Calendar.prototype.showAtElement = function (el, opts) {
	var self = this;
	var p = Calendar.getAbsolutePos(el);
	if (!opts || typeof opts != "string") {
		this.showAt(p.x, p.y + el.offsetHeight);
		return true;
	}
	function fixPosition(box) {
		if (box.x < 0)
			box.x = 0;
		if (box.y < 0)
			box.y = 0;
		var cp = document.createElement("div");
		var s = cp.style;
		s.position = "absolute";
		s.right = s.bottom = s.width = s.height = "0px";
		document.body.appendChild(cp);
		var br = Calendar.getAbsolutePos(cp);
		document.body.removeChild(cp);
		if (Calendar.is_ie) {
			br.y += document.body.scrollTop;
			br.x += document.body.scrollLeft;
		} else {
			br.y += window.scrollY;
			br.x += window.scrollX;
		}
		var tmp = box.x + box.width - br.x;
		if (tmp > 0) box.x -= tmp;
		tmp = box.y + box.height - br.y;
		if (tmp > 0) box.y -= tmp;
	};
	this.element.style.display = "block";
	Calendar.continuation_for_the_fucking_khtml_browser = function() {
		var w = self.element.offsetWidth;
		var h = self.element.offsetHeight;
		self.element.style.display = "none";
		var valign = opts.substr(0, 1);
		var halign = "l";
		if (opts.length > 1) {
			halign = opts.substr(1, 1);
		}
		// vertical alignment
		switch (valign) {
		    case "T": p.y -= h; break;
		    case "B": p.y += el.offsetHeight; break;
		    case "C": p.y += (el.offsetHeight - h) / 2; break;
		    case "t": p.y += el.offsetHeight - h; break;
		    case "b": break; // already there
		}
		// horizontal alignment
		switch (halign) {
		    case "L": p.x -= w; break;
		    case "R": p.x += el.offsetWidth; break;
		    case "C": p.x += (el.offsetWidth - w) / 2; break;
		    case "l": p.x += el.offsetWidth - w; break;
		    case "r": break; // already there
		}
		p.width = w;
		p.height = h + 40;
		self.monthsCombo.style.display = "none";
		fixPosition(p);
		self.showAt(p.x, p.y);
	};
	if (Calendar.is_khtml)
		setTimeout("Calendar.continuation_for_the_fucking_khtml_browser()", 10);
	else
		Calendar.continuation_for_the_fucking_khtml_browser();
};

/** Customizes the date format. */
Calendar.prototype.setDateFormat = function (str) {
	this.dateFormat = str;
};

/** Customizes the tooltip date format. */
Calendar.prototype.setTtDateFormat = function (str) {
	this.ttDateFormat = str;
};

/**
 *  Tries to identify the date represented in a string.  If successful it also
 *  calls this.setDate which moves the calendar to the given date.
 */
Calendar.prototype.parseDate = function(str, fmt) {
	if (!fmt)
		fmt = this.dateFormat;
	this.setDate(Date.parseDate(str, fmt));
};

Calendar.prototype.hideShowCovered = function () {
	if (!Calendar.is_ie && !Calendar.is_opera)
		return;
	function getVisib(obj){
		var value = obj.style.visibility;
		if (!value) {
			if (document.defaultView && typeof (document.defaultView.getComputedStyle) == "function") { // Gecko, W3C
				if (!Calendar.is_khtml)
					value = document.defaultView.
						getComputedStyle(obj, "").getPropertyValue("visibility");
				else
					value = '';
			} else if (obj.currentStyle) { // IE
				value = obj.currentStyle.visibility;
			} else
				value = '';
		}
		return value;
	};

	var tags = new Array("applet", "iframe", "select");
	var el = this.element;

	var p = Calendar.getAbsolutePos(el);
	var EX1 = p.x;
	var EX2 = el.offsetWidth + EX1;
	var EY1 = p.y;
	var EY2 = el.offsetHeight + EY1;

	for (var k = tags.length; k > 0; ) {
		var ar = document.getElementsByTagName(tags[--k]);
		var cc = null;

		for (var i = ar.length; i > 0;) {
			cc = ar[--i];

			p = Calendar.getAbsolutePos(cc);
			var CX1 = p.x;
			var CX2 = cc.offsetWidth + CX1;
			var CY1 = p.y;
			var CY2 = cc.offsetHeight + CY1;

			if (this.hidden || (CX1 > EX2) || (CX2 < EX1) || (CY1 > EY2) || (CY2 < EY1)) {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = cc.__msh_save_visibility;
			} else {
				if (!cc.__msh_save_visibility) {
					cc.__msh_save_visibility = getVisib(cc);
				}
				cc.style.visibility = "hidden";
			}
		}
	}
};

/** Internal function; it displays the bar with the names of the weekday. */
Calendar.prototype._displayWeekdays = function () {
	var fdow = this.firstDayOfWeek;
	var cell = this.firstdayname;
	var weekend = Calendar._TT["WEEKEND"];
	for (var i = 0; i < 7; ++i) {
		cell.className = "day name";
		var realday = (i + fdow) % 7;
		if (i) {
			cell.ttip = Calendar._TT["DAY_FIRST"].replace("%s", Calendar._DN[realday]);
			cell.navtype = 100;
			cell.calendar = this;
			cell.fdow = realday;
			Calendar._add_evs(cell);
		}
		if (weekend.indexOf(realday.toString()) != -1) {
			Calendar.addClass(cell, "weekend");
		}
		cell.innerHTML = Calendar._SDN[(i + fdow) % 7];
		cell = cell.nextSibling;
	}
};

/** Internal function.  Hides all combo boxes that might be displayed. */
Calendar.prototype._hideCombos = function () {
	this.monthsCombo.style.display = "none";
	this.yearsCombo.style.display = "none";
};

/** Internal function.  Starts dragging the element. */
Calendar.prototype._dragStart = function (ev) {
	if (this.dragging) {
		return;
	}
	this.dragging = true;
	var posX;
	var posY;
	if (Calendar.is_ie) {
		posY = window.event.clientY + document.body.scrollTop;
		posX = window.event.clientX + document.body.scrollLeft;
	} else {
		posY = ev.clientY + window.scrollY;
		posX = ev.clientX + window.scrollX;
	}
	var st = this.element.style;
	this.xOffs = posX - parseInt(st.left);
	this.yOffs = posY - parseInt(st.top);
	with (Calendar) {
		addEvent(document, "mousemove", calDragIt);
		addEvent(document, "mouseup", calDragEnd);
	}
};

// BEGIN: DATE OBJECT PATCHES

/** Adds the number of days array to the Date object. */
Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

/** Constants used for time computations */
Date.SECOND = 1000 /* milliseconds */;
Date.MINUTE = 60 * Date.SECOND;
Date.HOUR   = 60 * Date.MINUTE;
Date.DAY    = 24 * Date.HOUR;
Date.WEEK   =  7 * Date.DAY;

Date.parseDate = function(str, fmt) {
	var today = new Date();
	var y = 0;
	var m = -1;
	var d = 0;
	var a = str.split(/\W+/);
	var b = fmt.match(/%./g);
	var i = 0, j = 0;
	var hr = 0;
	var min = 0;
	for (i = 0; i < a.length; ++i) {
		if (!a[i])
			continue;
		switch (b[i]) {
		    case "%d":
		    case "%e":
			d = parseInt(a[i], 10);
			break;

		    case "%m":
			m = parseInt(a[i], 10) - 1;
			break;

		    case "%Y":
		    case "%y":
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
			break;

		    case "%b":
		    case "%B":
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { m = j; break; }
			}
			break;

		    case "%H":
		    case "%I":
		    case "%k":
		    case "%l":
			hr = parseInt(a[i], 10);
			break;

		    case "%P":
		    case "%p":
			if (/pm/i.test(a[i]) && hr < 12)
				hr += 12;
			else if (/am/i.test(a[i]) && hr >= 12)
				hr -= 12;
			break;

		    case "%M":
			min = parseInt(a[i], 10);
			break;
		}
	}
	if (isNaN(y)) y = today.getFullYear();
	if (isNaN(m)) m = today.getMonth();
	if (isNaN(d)) d = today.getDate();
	if (isNaN(hr)) hr = today.getHours();
	if (isNaN(min)) min = today.getMinutes();
	if (y != 0 && m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	y = 0; m = -1; d = 0;
	for (i = 0; i < a.length; ++i) {
		if (a[i].search(/[a-zA-Z]+/) != -1) {
			var t = -1;
			for (j = 0; j < 12; ++j) {
				if (Calendar._MN[j].substr(0, a[i].length).toLowerCase() == a[i].toLowerCase()) { t = j; break; }
			}
			if (t != -1) {
				if (m != -1) {
					d = m+1;
				}
				m = t;
			}
		} else if (parseInt(a[i], 10) <= 12 && m == -1) {
			m = a[i]-1;
		} else if (parseInt(a[i], 10) > 31 && y == 0) {
			y = parseInt(a[i], 10);
			(y < 100) && (y += (y > 29) ? 1900 : 2000);
		} else if (d == 0) {
			d = a[i];
		}
	}
	if (y == 0)
		y = today.getFullYear();
	if (m != -1 && d != 0)
		return new Date(y, m, d, hr, min, 0);
	return today;
};

/** Returns the number of days in the current month */
Date.prototype.getMonthDays = function(month) {
	var year = this.getFullYear();
	if (typeof month == "undefined") {
		month = this.getMonth();
	}
	if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
		return 29;
	} else {
		return Date._MD[month];
	}
};

/** Returns the number of day in the year. */
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 / Date.DAY);
};

/** Returns the number of the week in year, as defined in ISO 8601. */
Date.prototype.getWeekNumber = function() {
	var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
	var DoW = d.getDay();
	d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
	var ms = d.valueOf(); // GMT
	d.setMonth(0);
	d.setDate(4); // Thu in Week 1
	return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};

/** Checks date and time equality */
Date.prototype.equalsTo = function(date) {
	return ((this.getFullYear() == date.getFullYear()) &&
		(this.getMonth() == date.getMonth()) &&
		(this.getDate() == date.getDate()) &&
		(this.getHours() == date.getHours()) &&
		(this.getMinutes() == date.getMinutes()));
};

/** Set only the year, month, date parts (keep existing time) */
Date.prototype.setDateOnly = function(date) {
	var tmp = new Date(date);
	this.setDate(1);
	this.setFullYear(tmp.getFullYear());
	this.setMonth(tmp.getMonth());
	this.setDate(tmp.getDate());
};

/** Prints the date in a string according to the given format. */
Date.prototype.print = function (str) {
	var m = this.getMonth();
	var d = this.getDate();
	var y = this.getFullYear();
	var wn = this.getWeekNumber();
	var w = this.getDay();
	var s = {};
	var hr = this.getHours();
	var pm = (hr >= 12);
	var ir = (pm) ? (hr - 12) : hr;
	var dy = this.getDayOfYear();
	if (ir == 0)
		ir = 12;
	var min = this.getMinutes();
	var sec = this.getSeconds();
	s["%a"] = Calendar._SDN[w]; // abbreviated weekday name [FIXME: I18N]
	s["%A"] = Calendar._DN[w]; // full weekday name
	s["%b"] = Calendar._SMN[m]; // abbreviated month name [FIXME: I18N]
	s["%B"] = Calendar._MN[m]; // full month name
	// FIXME: %c : preferred date and time representation for the current locale
	s["%C"] = 1 + Math.floor(y / 100); // the century number
	s["%d"] = (d < 10) ? ("0" + d) : d; // the day of the month (range 01 to 31)
	s["%e"] = d; // the day of the month (range 1 to 31)
	// FIXME: %D : american date style: %m/%d/%y
	// FIXME: %E, %F, %G, %g, %h (man strftime)
	s["%H"] = (hr < 10) ? ("0" + hr) : hr; // hour, range 00 to 23 (24h format)
	s["%I"] = (ir < 10) ? ("0" + ir) : ir; // hour, range 01 to 12 (12h format)
	s["%j"] = (dy < 100) ? ((dy < 10) ? ("00" + dy) : ("0" + dy)) : dy; // day of the year (range 001 to 366)
	s["%k"] = hr;		// hour, range 0 to 23 (24h format)
	s["%l"] = ir;		// hour, range 1 to 12 (12h format)
	s["%m"] = (m < 9) ? ("0" + (1+m)) : (1+m); // month, range 01 to 12
	s["%M"] = (min < 10) ? ("0" + min) : min; // minute, range 00 to 59
	s["%n"] = "\n";		// a newline character
	s["%p"] = pm ? "PM" : "AM";
	s["%P"] = pm ? "pm" : "am";
	// FIXME: %r : the time in am/pm notation %I:%M:%S %p
	// FIXME: %R : the time in 24-hour notation %H:%M
	s["%s"] = Math.floor(this.getTime() / 1000);
	s["%S"] = (sec < 10) ? ("0" + sec) : sec; // seconds, range 00 to 59
	s["%t"] = "\t";		// a tab character
	// FIXME: %T : the time in 24-hour notation (%H:%M:%S)
	s["%U"] = s["%W"] = s["%V"] = (wn < 10) ? ("0" + wn) : wn;
	s["%u"] = w + 1;	// the day of the week (range 1 to 7, 1 = MON)
	s["%w"] = w;		// the day of the week (range 0 to 6, 0 = SUN)
	// FIXME: %x : preferred date representation for the current locale without the time
	// FIXME: %X : preferred time representation for the current locale without the date
	s["%y"] = ('' + y).substr(2, 2); // year without the century (range 00 to 99)
	s["%Y"] = y;		// year with the century
	s["%%"] = "%";		// a literal '%' character

	var re = /%./g;
	if (!Calendar.is_ie5 && !Calendar.is_khtml)
		return str.replace(re, function (par) { return s[par] || par; });

	var a = str.match(re);
	for (var i = 0; i < a.length; i++) {
		var tmp = s[a[i]];
		if (tmp) {
			re = new RegExp(a[i], 'g');
			str = str.replace(re, tmp);
		}
	}

	return str;
};

Date.prototype.__msh_oldSetFullYear = Date.prototype.setFullYear;
Date.prototype.setFullYear = function(y) {
	var d = new Date(this);
	d.__msh_oldSetFullYear(y);
	if (d.getMonth() != this.getMonth())
		this.setDate(28);
	this.__msh_oldSetFullYear(y);
};

// END: DATE OBJECT PATCHES


// global object that remembers the calendar
window._dynarch_popupCalendar = null;


/*****************************************************************************
/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
 * ---------------------------------------------------------------------------
 *
 * The DHTML Calendar
 *
 * Details and latest version at:
 * http://dynarch.com/mishoo/calendar.epl
 *
 * This script is distributed under the GNU Lesser General Public License.
 * Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
 *
 * This file defines helper functions for setting up the calendar.  They are
 * intended to help non-programmers get a working calendar on their site
 * quickly.  This script should not be seen as part of the calendar.  It just
 * shows you what one can do with the calendar, while in the same time
 * providing a quick and simple method for setting it up.  If you need
 * exhaustive customization of the calendar creation process feel free to
 * modify this code to suit your needs (this is recommended and much better
 * than modifying calendar.js itself).
 */

// $Id: calendar-setup.js,v 1.25 2005/03/07 09:51:33 mishoo Exp $

/**
 *  This function "patches" an input field (or other element) to use a calendar
 *  widget for date selection.
 *
 *  The "params" is a single object that can have the following properties:
 *
 *    prop. name   | description
 *  -------------------------------------------------------------------------------------------------
 *   inputField    | the ID of an input field to store the date
 *   displayArea   | the ID of a DIV or other element to show the date
 *   button        | ID of a button or other element that will trigger the calendar
 *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
 *   ifFormat      | date format that will be stored in the input field
 *   daFormat      | the date format that will be used to display the date in displayArea
 *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
 *   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
 *   align         | alignment (default: "Br"); if you don't know what's this see the calendar documentation
 *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
 *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
 *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
 *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
 *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
 *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
 *   onClose       | function that gets called when the calendar is closed.  [default]
 *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
 *   date          | the date that the calendar will be initially displayed to
 *   showsTime     | default: false; if true the calendar will include a time selector
 *   timeFormat    | the time format; can be "12" or "24", default is "12"
 *   electric      | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
 *   step          | configures the step of the years in drop-down boxes; default: 2
 *   position      | configures the calendar absolute position; default: null
 *   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
 *   showOthers    | if "true" (but default: "false") it will show days from other months too
 *
 *  None of them is required, they all have default values.  However, if you
 *  pass none of "inputField", "displayArea" or "button" you'll get a warning
 *  saying "nothing to setup".
 */
Calendar.setup = function (params) {
	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	param_default("inputField",     null);
	param_default("displayArea",    null);
	param_default("button",         null);
	param_default("eventName",      "click");
	param_default("ifFormat",       "%Y/%m/%d");
	param_default("daFormat",       "%Y/%m/%d");
	param_default("singleClick",    true);
	param_default("disableFunc",    null);
	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
	param_default("dateText",       null);
	param_default("firstDay",       null);
	param_default("align",          "Br");
	param_default("range",          [1900, 2999]);
	param_default("weekNumbers",    true);
	param_default("flat",           null);
	param_default("flatCallback",   null);
	param_default("onSelect",       null);
	param_default("onClose",        null);
	param_default("onUpdate",       null);
	param_default("date",           null);
	param_default("showsTime",      false);
	param_default("timeFormat",     "24");
	param_default("electric",       true);
	param_default("step",           2);
	param_default("position",       null);
	param_default("cache",          false);
	param_default("showOthers",     false);
	param_default("multiple",       null);

  var tmp = ["inputField", "displayArea", "button"];
	for (var i in tmp) {
		if (typeof params[tmp[i]] == "string") {
			params[tmp[i]] = document.getElementById(params[tmp[i]]);
		}
	}
	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
		alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
		return false;
	}

	function onSelect(cal) {
		var p = cal.params;
		var update = (cal.dateClicked || p.electric);
		if (update && p.inputField) {
			p.inputField.value = cal.date.print(p.ifFormat);
			if (typeof p.inputField.onchange == "function")
				p.inputField.onchange();
		}
		if (update && p.displayArea)
			p.displayArea.innerHTML = cal.date.print(p.daFormat);
		if (update && typeof p.onUpdate == "function")
			p.onUpdate(cal);
		if (update && p.flat) {
			if (typeof p.flatCallback == "function")
				p.flatCallback(cal);
		}
		if (update && p.singleClick && cal.dateClicked)
			cal.callCloseHandler();
	};

	if (params.flat != null) {
		if (typeof params.flat == "string")
			params.flat = document.getElementById(params.flat);
		if (!params.flat) {
			alert("Calendar.setup:\n  Flat specified but can't find parent.");
			return false;
		}
		var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
		cal.showsOtherMonths = params.showOthers;
		cal.showsTime = params.showsTime;
		cal.time24 = (params.timeFormat == "24");
		cal.params = params;
		cal.weekNumbers = params.weekNumbers;
		cal.setRange(params.range[0], params.range[1]);
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		if (params.ifFormat) {
			cal.setDateFormat(params.ifFormat);
		}
		if (params.inputField && typeof params.inputField.value == "string") {
			cal.parseDate(params.inputField.value);
		}
		cal.create(params.flat);
		cal.show();
		return false;
	}

	var triggerEl = params.button || params.displayArea || params.inputField;
	triggerEl["on" + params.eventName] = function() {
		var dateEl = params.inputField || params.displayArea;
		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
		var mustCreate = false;
		var cal = window.calendar;
		if (dateEl)
			params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
		if (!(cal && params.cache)) {
			window.calendar = cal = new Calendar(params.firstDay,
							     params.date,
							     params.onSelect || onSelect,
							     params.onClose || function(cal){cal.hide();});
							     //function(cal){params.onClose;cal.hide();});
			cal.showsTime = params.showsTime;
			cal.time24 = (params.timeFormat == "24");
			cal.weekNumbers = params.weekNumbers;
			mustCreate = true;
		} else {
			if (params.date)
				cal.setDate(params.date);
			cal.hide();
		}
		if (params.multiple) {
			cal.multiple = {};
			for (var i = params.multiple.length; --i >= 0;) {
				var d = params.multiple[i];
				var ds = d.print("%Y%m%d");
				cal.multiple[ds] = d;
			}
		}
		cal.showsOtherMonths = params.showOthers;
		cal.yearStep = params.step;
		cal.setRange(params.range[0], params.range[1]);
		cal.params = params;
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		cal.setDateFormat(dateFmt);
		if (mustCreate)
			cal.create();
		cal.refresh();
		if (!params.position)
			cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
		else
			cal.showAt(params.position[0], params.position[1]);
		return false;
	};
  
	return cal;
};


// ** I18N

// Calendar EN language
// Author: Mihai Bazon, <mihai_bazon@yahoo.com>
// Encoding: any
// Distributed under the same terms as the calendar itself.

// For translators: please use UTF-8 if possible.  We strongly believe that
// Unicode is the answer to a real internationalized world.  Also please
// include your contact information in the header, as can be seen above.

// full day names
Calendar._DN = new Array
("Neděle",
 "Pondělí",
 "Úterý",
 "Středa",
 "Čtvrtek",
 "Pátek",
 "Sobota",
 "Neděle");

// Please note that the following array of short day names (and the same goes
// for short month names, _SMN) isn't absolutely necessary.  We give it here
// for exemplification on how one can customize the short day names, but if
// they are simply the first N letters of the full name you can simply say:
//
//   Calendar._SDN_len = N; // short day name length
//   Calendar._SMN_len = N; // short month name length
//
// If N = 3 then this is not needed either since we assume a value of 3 if not
// present, to be compatible with translation files that were written before
// this feature.

// short day names
Calendar._SDN = new Array
("Ne",
 "Po",
 "Út",
 "St",
 "Čt",
 "Pá",
 "So",
 "Ne");


// First day of the week. "0" means display Sunday first, "1" means display
// Monday first, etc.
Calendar._FD = 1;
 
Calendar._MN  = new Array('Leden','Únor','Březen','Duben','Květen','Červen','Červenec','Srpen','Září','Říjen','Listopad','Prosinec');

//Calendar._SMN = new Array('Led','Úno','Bře','Dub','Kvě','Črv','Čvc','Srp','Zář','Říj','Lis','Pro');

Calendar._SMN  = new Array('Leden','Únor','Březen','Duben','Květen','Červen','Červenec','Srpen','Září','Říjen','Listopad','Prosinec');


Calendar._TT = {};
Calendar._TT["INFO"] = "O komponentě kalendář";
Calendar._TT["TOGGLE"] = "Změna prvního dne v týdnu";
Calendar._TT["PREV_YEAR"] = "Předchozí rok (přidrž pro menu)";
Calendar._TT["PREV_MONTH"] = "Předchozí měsíc (přidrž pro menu)";
Calendar._TT["GO_TODAY"] = "Dnešní datum";
Calendar._TT["NEXT_MONTH"] = "Další měsíc (přidrž pro menu)";
Calendar._TT["NEXT_YEAR"] = "Další rok (přidrž pro menu)";
Calendar._TT["SEL_DATE"] = "Vyber datum";
Calendar._TT["DRAG_TO_MOVE"] = "Chyť a táhni, pro přesun";
Calendar._TT["PART_TODAY"] = " (dnes)";
Calendar._TT["MON_FIRST"] = "Ukaž jako první Pondělí";


// the following is to inform that "%s" is to be the first day of week
// %s will be replaced with the day name.
Calendar._TT["DAY_FIRST"] = "Zobraz %s první";

// This may be locale-dependent.  It specifies the week-end days, as an array
// of comma-separated numbers.  The numbers are from 0 to 6: 0 means Sunday, 1
// means Monday, etc.
Calendar._TT["WEEKEND"] = "0,6";

Calendar._TT["CLOSE"] = "Zavřít";
Calendar._TT["TODAY"] = "Dnes";
Calendar._TT["TIME_PART"] = "(Shift-)Klikni nebo táhni pro změnu hodnoty";

// date formats
Calendar._TT["DEF_DATE_FORMAT"] = "d.m.yy";
//Calendar._TT["TT_DATE_FORMAT"] = "%a, %b %e";
Calendar._TT["TT_DATE_FORMAT"] = "%A %e.%B %Y";

Calendar._TT["WK"] = "Týden";
Calendar._TT["TIME"] = "Čas:";



$(document).ready(function() {
  
  $(".field.f_color").each(function(){
    fieldType_Color({showField: !$(this).hasClass("field_disabled"), containerId: "container_"+$(this).attr("id"),fieldName: $(this).attr("id"), fieldColor: $(this).find(".ff input").attr("value")});
  });
});

function fieldType_Color(settings)
  {
    settings = jQuery.extend({
      
      fieldName: '',
      containerId: '',
      showField: true,
      fieldColor: '#FFFFFF',
      
      labelSelectColor: 'Vyberte barvu',
      labelOpenColorPicker: 'Zvolit barvu z palety'
      
    },settings);
    
    initialize();
    
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
          //$('#' + settings.fieldName).toggleClass("field_disabled");
        });
        
        settings.container = $('#' + settings.containerId);
      }
    
    function show()
      {
        settings.container.html('');
        settings.container.append('<a href="javascript:void(0);" title="' + settings.labelOpenColorPicker + '"><div style="background-color: ' + settings.fieldColor + '" id="block_color_' + settings.fieldName + '"></div><span>' + settings.labelSelectColor + '</span></a>');
        settings.container.append('<input class="input_hidden" type="hidden" name="' + settings.fieldName + '" id="f_' + settings.fieldName + '" value="' + settings.fieldColor + '" />');
        settings.container.ColorPicker(
            {
                color: settings.fieldColor,
                onShow: function (colpkr) {$(colpkr).fadeIn(500);return false;},
                onHide: function (colpkr) {$('#f_' + settings.fieldName).trigger("validateField");$(colpkr).fadeOut(500);return false;},
                onChange: function (hsb, hex, rgb) {
                  $('#block_color_' + settings.fieldName).css('backgroundColor', '#' + hex);
                  $('#f_' + settings.fieldName).attr("value", '#' + hex);
                }
            });    
      }
      
    function remove()
      {
        $('#' + settings.fieldName + ' .ff').html('');
      }
  
  }



$(document).ready(function() {
  
  $(".field.f_date").each(function(){
    fieldType_Date({showField: !$(this).hasClass("field_disabled"), containerId: "container_"+$(this).attr("id"),fieldName: $(this).attr("id"), fieldType: 'date', fieldDate: $(this).find(".ff input").attr("value")});
  });
  $(".field.f_datetime").each(function(){
    fieldType_Date({showField: !$(this).hasClass("field_disabled"), containerId: "container_"+$(this).attr("id"),fieldName: $(this).attr("id"), fieldType: 'datetime', fieldDate: $(this).find(".ff input").attr("value")});
  });

});

function fieldType_Date(settings)
  {
    settings = jQuery.extend({
      
      fieldName: '',
      containerId: '',
      showField: true,
      fieldType: 'datetime',
      fieldDate: '0000-00-00 00:00:00'
      
    },settings);
    
    initialize();
    
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
        });
        
        settings.container = $('#' + settings.containerId);
      }
    
    function show()
      {
        if(settings.fieldDate == '0000-00-00 00:00:00')
          {
            exd = new Date(); 
            settings.fieldDate = exd.getFullYear()+'-'+(exd.getMonth()+1)+'-'+exd.getDate()+' '+exd.getHours()+':'+exd.getMinutes()+':'+exd.getSeconds();
          }
        
        settings.container.html('');
        settings.container.append('<a href="javascript:void(0);" id="f_' + settings.fieldName + '_link"></a>');
        settings.container.append('<input class="input_hidden" type="hidden" name="' + settings.fieldName + '" id="f_' + settings.fieldName + '" value="' + settings.fieldDate + '" />');
        
        switch(settings.fieldType)
          {
            case "datetime":
              Calendar.setup(
                {
                  inputField     :    "f_" + settings.fieldName,     
                  ifFormat       :    "%Y-%m-%d %I:%M:%S",     
                  displayArea    :    'f_' + settings.fieldName  + '_link',      
                  daFormat       :    "%d. %B %Y %I:%M",
                  align          :    "Tl", 
                  showsTime      :    true,
                  onClose        :    function(){$('#f_' + settings.fieldName + '_link').trigger("validateField");},
                  timeFormat     :    "24", 
                  singleClick    :    true
                });
                $('#f_' + settings.fieldName + '_link').append(Date.parseDate(settings.fieldDate,"%Y-%m-%d %I:%M:%S").print("%d. %B %Y %I:%M"));
                break;
              
            case "date":
              Calendar.setup(
                {
                  inputField     :    "f_" + settings.fieldName,     
                  ifFormat       :    "%Y-%m-%d",     
                  displayArea    :    'f_' + settings.fieldName  + '_link',      
                  daFormat       :    "%d. %B %Y",
                  align          :    "Tl", 
                  showsTime      :    false,
                  onClose        :    function(){$('#f_' + settings.fieldName + '_link').trigger("validateField");},
                  timeFormat     :    "24", 
                  singleClick    :    true
                });
                $('#f_' + settings.fieldName + '_link').append(Date.parseDate(settings.fieldDate,"%Y-%m-%d").print("%d. %B %Y"));
                break;
          }
      }
      
    function remove()
      {
        $('#' + settings.fieldName + ' .ff').html('');
      }
  
  }



$(document).ready(function() {
  $(".f_gallery").each(function(){
    fieldType_File({showField: !$(this).hasClass("field_disabled"), fieldName: $(this).attr("id"),fieldType: "gallery",containerId: "container_"+$(this).attr("id"),fieldFile: FieldFile[$(this).attr("id")]});
  });
  $(".f_files").each(function(){
    fieldType_File({showField: !$(this).hasClass("field_disabled"), fieldName: $(this).attr("id"),fieldType: "files",containerId: "container_"+$(this).attr("id"),fieldFile: FieldFile[$(this).attr("id")]});
  });
  $(".f_file").each(function(){
    fieldType_File({showField: !$(this).hasClass("field_disabled"), fieldName: $(this).attr("id"),fieldType: "file",containerId: "container_"+$(this).attr("id"),fieldFile: FieldFile[$(this).attr("id")]});
  });
  $(".f_image").each(function(){
    fieldType_File({showField: !$(this).hasClass("field_disabled"), fieldName: $(this).attr("id"),fieldType: "image",containerId: "container_"+$(this).attr("id"),fieldFile: FieldFile[$(this).attr("id")]});
  });
}); 

var FLD_FILEMANAGER = "/scripts/components/system/files/";
var FieldFile = new Array();

function fieldType_File(settings)
  {
    settings = jQuery.extend({
      
      fieldName: '',
      fieldType: 'image',
      containerId: '',
      fieldFile: new Array(),
      hiddenFields: '',
      showField: true,
      
      labelOpenManager: 'Otevřít průzkumník',
      labelManager: 'Průzkumník', 
      labelNoFilesSelected: 'Není vybrán žádný soubor',  
      labelRotateImageMinus: 'Otočit obrázek proti směru hodinových ručiček',
      labelRotateImagePlus: 'Otočit obrázek po směru hodinových ručiček',
      labelRotateMinus: 'Otočit proti směru',
      labelRotatePlus: 'Otočit po směru',
      labelRemoveThisFile: 'Odebrat tento soubor',
      labelRemove: 'Odebrat',
      labelMoveItemUp: 'Posunout nahoru',
      labelMoveItemDown: 'Posunout dolů',
      labelMoveUp: 'Nahoru',
      labelMoveDown: 'Dolů',
      labelThumb: 'Náhled',
      labelMainImage: 'Hlavní',
      labelAddFiles: 'Přidat soubory',
      labelSelectFile: 'Vybrat soubor',
      labelFileName: 'Název',
      labelFileDescription: 'Popis',
      imagesOnLine: 6,
      
      idFilesTable: 'default_filestable',
      
      pathIconManager:  FLD_FILEMANAGER + 'icon/ico_filemanager_40x40.png',
      pathDefaultIcon: FLD_FILEMANAGER + 'icon/white/ico_file_20x20.png',
      maxWidth: 126,
      maxHeight: 110
      
		},settings);
		
		initialize();
		
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
          //$('#' + settings.fieldName).toggleClass("field_disabled");
        });
        
        
        settings.idFilesTable = settings.fieldName + '_filestable';
        settings.idButton = settings.fieldName + '_buttonManager';
        settings.idList = settings.fieldName + '_list';
        settings.container = $('#' + settings.containerId);
        settings.multiple = (settings.fieldType == "files" || settings.fieldType == "gallery") ? true : false;
        
        for(x in settings.fieldFile)
          {
            if(settings.fieldFile[x]["order"] == 0){repairFileOrder();break;}
          }
      }
    
    function show()
      {
        settings.container.append('<a class="butt_text bt_filemanager" id="' + settings.idButton + '" title="' + settings.labelOpenManager+ '" href="javascript: void(0);">'+(settings.fieldType == 'gallery' || settings.fieldType == 'files' ? settings.labelAddFiles : settings.labelSelectFile)+'</a>');
        settings.container.append('<div class="block_fileslist bf_'+settings.fieldType+'" id="'+settings.idList+'"></div>');
        showList();
        $('#'+settings.idButton).click(function(){showManager(settings.fieldType);});
      }
    
    function remove()
      {
        settings.container.html('');
      }
    
    function showList()
      {
        var image_no = 1;
        settings.hiddenFields = '';
        $("#" + settings.idList).html('');
        
        settings.fieldFile.sort(function(a, b){return a["order"]-b["order"];});
        
        if(!arrayLength(settings.fieldFile))
          {
            $("#" + settings.idList).append('<strong class="empty_note">' + settings.labelNoFilesSelected + '</strong>');
          }
        else
          {
            switch (settings.fieldType)
              {
                case "file":
                case "files":
                  //$("#" + settings.idList).append('<table cellspacing="0" class="table_fileslist" id="' + settings.idFilesTable + '"></table>');
                  for(x in settings.fieldFile)
                    {
                      showFile(x, image_no);
                      image_no++;
                    }
                  break;
                
                case "image":
                case "gallery":
                  for (x in settings.fieldFile)
                    {
                      showImage(x, image_no);
                      image_no++;
                    }
                  $("#" + settings.idList).append('<div class="cleaner"></div>');
                  break;
              }
            $("#" + settings.idList).append(settings.hiddenFields);
          }
        
        updateThumbnails();
      }
    
    function showManager(type, key)
      {
        var key = key || ''; 
        var filter = new Array();
        var multiple = false;
        var path = '';
        sf = new Array();
        
        if(settings.fieldFile[0])
          {
            path = settings.fieldFile[0]["full"];
          }
        else
          {
            path = '';
          }
        
        switch(type)
          {
            case 'image': 
              
              //sf[0] = path;
              multiple = false;
              filter = ["jpg", "jpeg", "bmp", "gif", "png"];
              break;
            case 'gallery': 
              multiple = true;
              filter = ["jpg", "jpeg", "bmp", "gif", "png"];
              break;
            case 'thumb': 
              multiple = false;
              filter = ["jpg", "jpeg", "bmp", "gif", "png"];
              break;
            case 'file':
              //if(settings.fieldFile[0]){path = settings.fieldFile[0]["full"];}else{path = '';}
              
              //sf[0] = path;
              multiple = false;
              filter = new Array();
              break;
            case 'files':
            default: 
              multiple = true;
              filter = new Array();
              break;
          }
        
        ShowDialogWindow({
          windowID: 'dlg_file', 
          title: settings.labelManager, 
          width: 900, 
          height: 600, 
          callin: function(win){
          
          fileManager({
            //selectedFile: sf,
            Path: path,
            con: win,
            multiple: true,
            Filter: filter
          });
          
          }, 
          callback: function(win){
            switch(type)
              {
                case "thumb": returnThumbnail(win,key);break;
                default: returnFile(win); break;
              } 
            }
          });
      }
    
    function maxImageSize(width, height)
      {
        if(width>=height)
          {
            width = settings.maxWidth; 
            height = (height/width)*settings.maxHeight; 
          }
        else
          {
            width = (width/height)*settings.maxWidth; 
            height = settings.maxHeight; 
          }
        imgSize = new Array(width,height);
        return imgSize;
      }
    
    function showImage(x, arr_key)
      {
        id_blockItem = settings.fieldName + '_item_' + x;
        
        path_thumb = modFilePath((settings.fieldFile[x]["thb"].length ? settings.fieldFile[x]["thb"] : settings.fieldFile[x]["full"])) + '?unique=' + new Date().valueOf();
        
        $("#" + settings.idList).append(
          '\n<div class="block_image' + ((arr_key%settings.imagesOnLine) == 0 ? ' bi_last' : '') + '" id="' + id_blockItem + '">' + 
          '\n<div class="bi_image">' + 
          '\n<img src="' + path_thumb + '" alt="' + settings.fieldFile[x]["caption"] + '" />' + 
          '\n<a class="butt_small bs_rotate_minus" href="javascript:void(0);" title="'+settings.labelRotateImageMinus+'">'+settings.labelRotateMinus+'</a>' + 
          '\n<a class="butt_small bs_rotate_plus" href="javascript:void(0);" title="'+settings.labelRotateImagePlus+'">'+settings.labelRotatePlus+'</a>' +
          '\n</div>' + 
          '<input class="input_default input_caption" type="text" name="'+settings.fieldName+'_caption['+arr_key+']" value="' + (settings.fieldFile[x]["caption"].length ? settings.fieldFile[x]["caption"] : settings.labelFileName) + '" />' +
          '\n<textarea class="input_description" name="'+settings.fieldName+'_description['+arr_key+']">'+(settings.fieldFile[x]["description"].length ? settings.fieldFile[x]["description"] : settings.labelFileDescription)+'</textarea>' +
          
          '\n<a href="javascript:void(0);" id="' + id_blockItem + '_butt_remove" class="butt_small bs_remove" title="' + settings.labelRemoveThisFile + '">'+settings.labelRemove+'</a>' +
          
          (arrayLength(settings.fieldFile)>1 ? 
              '\n<input class="input_radio" type="radio"' + (settings.fieldFile[x]["switch_main"] == 1 ? ' checked="checked"' : '') + ' name="'+settings.fieldName+'_switch_mainimage" value="'+settings.fieldFile[x]["id"]+'" /><label for="'+settings.fieldName+'_switch_mainimage">'+settings.labelMainImage+'</label>' + 
              (settings.fieldFile[x]["order"] > 1 ? '\n<a href="javascript:void(0);" id="' + id_blockItem + '_butt_moveleft" class="butt_small bs_moveleft" title="'+settings.labelMoveItemUp+'"><span>'+settings.labelMoveUp+'</span></a>' : '<span class="butt_small bs_moveleft">'+settings.labelMoveUp+'</span>') + 
              (settings.fieldFile[x]["order"] < arrayLength(settings.fieldFile) ? '\n<a href="javascript:void(0);" id="' + id_blockItem + '_butt_moveright" class="butt_small bs_moveright" title="'+settings.labelMoveItemDown+'"><span>'+settings.labelMoveDown+'</span></a>' : '<span class="butt_small bs_moveright">'+settings.labelMoveDown+'</span>')
              :
              '') + 
          
          '\n</div>\n');
        
        //imgSize = getImgSize(realFilePath(path_thumb));
        
        //var img = $('#' + id_blockItem + ' img');
        //var width = obj.clientWidth;
        //var height = obj.clientHeight;
        
        //maxSize = maxImageSize(width, height);
        
        //var width = img.naturalWidth;
        //var height = img.naturalHeight;
        
       // alert(width + "x" + height + ' -- ' + $('#' + id_blockItem + ' img').width() + "x"+ $('#' + id_blockItem + ' img').height());
        
        //$('#' + id_blockItem + ' img').width(maxSize[0]).height(maxSize[1]);
        $('#' + id_blockItem + ' .input_caption').focus(function(){if(!settings.fieldFile[x]['caption'].length){this.value = '';}});
        $('#' + id_blockItem + ' .input_caption').blur(function(){settings.fieldFile[x]['caption']=this.value;});
        $('#' + id_blockItem + ' .input_description').focus(function(){if(!settings.fieldFile[x]['description'].length){this.value = '';}});
        $('#' + id_blockItem + ' .input_description').blur(function(){settings.fieldFile[x]['description']=this.value;});
        
        $('#' + id_blockItem + ' .bs_remove').click(function(){removeFile(x);});
        $('#' + id_blockItem + ' .bs_moveleft').click(function(){moveFile(x, 0);});
        $('#' + id_blockItem + ' .bs_moveright').click(function(){moveFile(x, 1);});
        $('#' + id_blockItem + ' .bs_rotate_plus').click(function(){rotateImage(settings.fieldFile[x]["full"], 270);});
        $('#' + id_blockItem + ' .bs_rotate_minus').click(function(){rotateImage(settings.fieldFile[x]["full"], 90);});
        
        settings.hiddenFields +=
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_datetime['+arr_key+']" value="'+settings.fieldFile[x]["datetime"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_path['+arr_key+']" value="'+settings.fieldFile[x]["full"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_order['+arr_key+']" value="'+settings.fieldFile[x]["order"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_id['+arr_key+']" value="'+settings.fieldFile[x]["id"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_thb_path['+arr_key+']" value="'+settings.fieldFile[x]["thb"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_new_thb_path['+arr_key+']" value="'+settings.fieldFile[x]["new_thb"]+'" />';
      }  
    
    function showFile(x, arr_key)
      {
        id_blockItem = settings.fieldName + '_item_' + x;
        
        path_icon = modFilePath(FLD_FILEMANAGER + 'icon/white/ico_' + settings.fieldFile[x]["type"] + '_20x20.png');
        
        //if(settings.fieldFile[x]["new_thb"].length){alert(settings.fieldFile[x]["new_thb"]);}
        
        path_thumb = modFilePath((settings.fieldFile[x]["new_thb"].length ? settings.fieldFile[x]["new_thb"] : settings.fieldFile[x]["thb"]));
        
        $("#" + settings.idList).append(
          '\n<div class="block_file" id="' + id_blockItem + '">' +
          (settings.fieldFile[x]["order"] > 1 ? '<a href="javascript:void(0);" class="butt_small bs_moveup" title="'+settings.labelMoveItemUp+'"><span>'+settings.labelMoveUp+'</span></a>' : '<span class="butt_small bs_moveup">'+settings.labelMoveUp+'</span>') +
          (settings.fieldFile[x]["order"] < arrayLength(settings.fieldFile) ? '<a href="javascript:void(0);" class="butt_small bs_movedown" title="'+settings.labelMoveItemDown+'"><span>'+settings.labelMoveDown+'</span></a>' : '<span class="butt_small bs_movedown">'+settings.labelMoveDown+'</span>') +
          '\n<img class="ico_small" src="' + (path_icon ? path_icon : settings.pathDefaultIcon ) + '" />' +
          '</td>' +
          '\n<strong>' + settings.fieldFile[x]["name"] + '</strong>' +
          '<input class="input_default input_caption" type="text" name="'+settings.fieldName+'_caption['+arr_key+']" value="' + (settings.fieldFile[x]["caption"].length ? settings.fieldFile[x]["caption"] : settings.labelFileName) + '" />' +
          '\n<input class="input_default input_description" type="text" name="'+settings.fieldName+'_description['+arr_key+']" value="'+(settings.fieldFile[x]["description"].length ? settings.fieldFile[x]["description"] : settings.labelFileDescription)+'" />' +
          '\n<a class="butt_small bs_remove" href="javascript:void(0);" title="' + settings.labelRemoveThisFile + '">'+settings.labelRemove+'</a>' +
          '\n<a class="butt_small bs_thumbnail" href="javascript:void(0);" title="' + path_thumb + '">' + settings.labelThumb + '</a>' +
          '\n</div>'
          );
        
        $('#' + id_blockItem + ' .input_caption').focus(function(){if(!settings.fieldFile[x]['caption'].length){this.value = '';}});
        $('#' + id_blockItem + ' .input_caption').blur(function(){settings.fieldFile[x]['caption']=this.value;});
        $('#' + id_blockItem + ' .input_description').focus(function(){if(!settings.fieldFile[x]['description'].length){this.value = '';}});
        $('#' + id_blockItem + ' .input_description').blur(function(){settings.fieldFile[x]['description']=this.value;});
        $('#' + id_blockItem + ' .bs_remove').click(function(){removeFile(x);});
        $('#' + id_blockItem + ' .bs_moveup').click(function(){moveFile(x, 0);});
        $('#' + id_blockItem + ' .bs_movedown').click(function(){moveFile(x, 1);});
        $('#' + id_blockItem + ' .bs_thumbnail').click(function(){showManager("thumb", x);});
        
        settings.hiddenFields += 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_datetime['+arr_key+']" value="'+settings.fieldFile[x]["datetime"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_path['+arr_key+']" value="'+settings.fieldFile[x]["full"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_order['+arr_key+']" value="'+settings.fieldFile[x]["order"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_id['+arr_key+']" value="'+settings.fieldFile[x]["id"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_thb_path['+arr_key+']" value="'+settings.fieldFile[x]["thb"]+'" />' + 
          '\n<input class="input_hidden" type="hidden" name="'+settings.fieldName+'_new_thb_path['+arr_key+']" value="'+settings.fieldFile[x]["new_thb"]+'" />';
      }
  
    function rotateImage(file_path, degrees)
      {
        $.post("/index.php", {'initialize_for_ajax' : 'true', 'file': './scripts/components/system/files/mods/mod_rotate_image.php', 'file_path': file_path, 'degrees': degrees}, function(data){showList();});
      }
  
    function removeFile(x)
      {
        for(y in settings.fieldFile)
          {
            if(settings.fieldFile[y]["order"]>settings.fieldFile[x]["order"]) {settings.fieldFile[y]["order"]--;}
          }
        delete settings.fieldFile[x];
        showList();
      }
  
    function moveFile(x, direction)
      {
        nextItem = FindKey(settings.fieldFile, "order", (parseInt(settings.fieldFile[x]["order"])+1));
        peviousItem = FindKey(settings.fieldFile, "order", (parseInt(settings.fieldFile[x]["order"])-1));
        if(direction && nextItem!='undefined')
          {
            settings.fieldFile[x]["order"]++;
            settings.fieldFile[nextItem]["order"]--;
          }
        else if(!direction && peviousItem!='undefined')
          {
            settings.fieldFile[x]["order"]--;
            settings.fieldFile[peviousItem]["order"]++;
          }
        
        showList();
      }
    
    function addFile(path)
      {
        var temp_array = new Array();
        var file_type = path.split(".");
        var file_name = path.split("/");
    
        temp_array["id"]=0;
        temp_array["ico"]="";
        temp_array["type"]=file_type.pop();
        temp_array["name"]=file_name.pop();
        temp_array["caption"]=''; //settings.labelFileName;
        temp_array["description"]=''; //settings.labelFileDescription;
        temp_array["order"]=settings.multiple ? parseInt(arrMaxVal(settings.fieldFile, "order"))+1 : 1;
        temp_array["full"]=path;
        temp_array["thb"]=''; 
        temp_array["new_thb"] = path;
        temp_array["datetime"] = '';
        settings.fieldFile[(settings.multiple ? settings.fieldFile.length : 0)]=temp_array;
      }
     
    function returnFile(win)
      {
        $(win).find("input[name=selected_file]").each(function(){
          addFile(realFilePath($(this).attr("value")));
        });
        //for (a = 0; win.contents().find('#selected_file_'+a).length; a++)
        //  {
        //    if(win.contents().find('#selected_file_'+a).attr("checked"))
        //      {
        //        addFile(win.contents().find('#selected_file_'+a).attr("value"));
        //      }
        // }
        
        showList();
      }
      
    function returnThumbnail(win, x)
      {
        var found = false;
        //for (a = 0; win.contents().find('#selected_file_'+a).length; a++)
        $(win).contents().find("input[name=selected_file]").each(function()
          {
            settings.fieldFile[x]["new_thb"] = modFilePath($(this).attr("value"));
            found = true;
          });
        if(!found)
          {  
            settings.fieldFile[x]["thb"] = '';
            settings.fieldFile[x]["new_thb"] = '';
          }
        showList();
        return found;
      } 
    
    function repairFileOrder()
      {
        var order = 1;
        for(x in settings.fieldFile)
          {
            settings.fieldFile[x]["order"] = order;
            order++;
          }
      }
    
    function updateThumbnails()
      {
        $('#' + settings.containerId + " .block_fileslist a.bs_thumbnail").easyTooltip({
          showThumb: true,
          thumbParam: "title"
        });
      }
  }


$(document).ready(function() {
  
  $(".field.f_html").each(function(){
    fieldType_Html({showField: !$(this).hasClass("field_disabled"), fieldType: 'advanced', containerId: "container_"+$(this).attr("id"), fieldHTML: $(this).find("textarea").text(), fieldName: $(this).attr("id")});
  });
  
  $(".field.f_lighthtml").each(function(){
    fieldType_Html({showField: !$(this).hasClass("field_disabled"), fieldType: 'simple', containerId: "container_"+$(this).attr("id"), fieldHTML: $(this).find("textarea").text(), fieldName: $(this).attr("id")});
  });


        //tinyMCE.init({

        


});

function fieldType_Html(settings)
  {
    settings = jQuery.extend({
      
      fieldName: '',
      fieldHTML: '',
      showField: true,
      fieldType: 'advanced',
      containerId: ''
      
    },settings);
    
    initialize();
    
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
        });
        settings.container = $('#' + settings.containerId);
      }
    
    function show()
      {
        settings.container.html('');
        settings.container.append('<div class="block_editor"><textarea name="' + settings.fieldName + '" id="f_' + settings.fieldName + '">'+settings.fieldHTML+'</textarea></div>');
        
        switch(settings.fieldType)
          {
            case 'advanced':
              settings.container.find('textarea').tinymce({
			
              //debug: true,
              cleanup : true,
              body_class : 'body_html_editor',
              extended_valid_elements : "module[*],field[*],page[*],template[*],embed[*],iframe[*]",
              //custom_elements: 'module,template,field,page',
              script_url : '/scripts/js/tiny_mce/tiny_mce.js',
              theme : "advanced",
			        language: "cs",
			        plugins : "safari,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template",
              relative_urls : false,
              convert_urls : false,
			         theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontsizeselect",
			         theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,code,|,insertdate,inserttime,preview,|,forecolor,backcolor",
			         theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen",
			         theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak",
			         theme_advanced_toolbar_location : "top",
			         theme_advanced_toolbar_align : "left",
			         theme_advanced_statusbar_location : "bottom",
			         theme_advanced_resizing : false,
			         //width: 930,
              height: 800,
              file_browser_callback : 'mceFileBrowser',
			         content_css : PATH_CONTENT_CSS,
			         //remove_trailing_nbsp : false,
			         entity_encoding : "raw"
			     

              // Drop lists for link/image/media/template dialogs
			        //template_external_list_url : "lists/template_list.js",
			         //external_link_list_url : "lists/link_list.js",
			         //external_image_list_url : "lists/image_list.js",
			         //media_external_list_url : "lists/media_list.js",
      
              });
              //settings.container.find('textarea').tinymce().getBody().addClass('body_html_editor');
            break;
          case 'simple':
            settings.container.find('textarea').tinymce({
			
              cleanup : true,
              valid_elements: "b,i,u,a,s,ol,ul,li,sup,sub",
              extended_valid_elements : "module[*],field[*],page[*],template[*],embed[*]",
              inline_styles : false,
              script_url : FLD_JS+'tiny_mce/tiny_mce.js',
              theme : "advanced",
              relative_urls : false,
              convert_urls : false,
			        theme_advanced_buttons1 : "bold,italic,underline,strikethrough,sub,sup,link,unlink,bullist,numlist,blockquote,undo", 
              theme_advanced_buttons2 : "", 
              theme_advanced_buttons3 : "", 

              entity_encoding : "raw",
			        height: 130,
			        language: "cs",
			     
			        content_css : "/templates/output/common/css/screen/common.css"
			     

                });
              break;
        //  case default:
		    }
        
      
      }
      
    function remove()
      {
        $('#' + settings.fieldName + ' .ff').html('');
      }
  
  }
	
function mceFileBrowser (field_name, url, type, win) {

    var flt = field_name=="src" ? ["jpg", "jpeg", "bmp", "gif", "png"] : new Array();
    
    ShowDialogWindow({
          windowID: 'dlg_file', 
          title: 'Průzkumník', 
          width: 800, 
          height: 500, 
          callin: function(w){
          
            fileManager({
            con: w,
            multiple: false,
            Filter: flt
          });
          
          }, 
          callback: function(w){
            win.document.getElementById(field_name).value = modFilePath($(w).find("input[name=selected_file]").attr("value"));
            }
          });
    
    return false;
  }


$(document).ready(function() {
  
  $(".field.f_password").each(function(){
    fieldType_Password({showField: !$(this).hasClass("field_disabled"), containerId: "container_"+$(this).attr("id"),fieldName: $(this).attr("id"), fieldValue: $(this).find(".ff input").attr("value")});
  });
});

function fieldType_Password(settings)
  {
    settings = jQuery.extend({
      
      fieldName: '',
      containerId: '',
      showField: true,
      fieldValue: '',
      
      labelRetypePassword: 'Heslo znovu'
      
    },settings);
    
    initialize();
    
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
          //$('#' + settings.fieldName).toggleClass("field_disabled");
        });
        
        settings.container = $('#' + settings.containerId);
      }
    
    function show()
      {
        settings.container.html('');
        settings.container.append(
          '<input class="input_password" type="password" name="new_'+settings.fieldName + '" id="f_new_'+settings.fieldName+'" value="" />' + 
          '<span>'+settings.labelRetypePassword+':</span><input class="input_password" type="password" name="new_'+settings.fieldName + '_check" id=\"f_new_'+settings.fieldName + '_check" value="" />'
        );
      }
      
    function remove()
      {
        $('#' + settings.fieldName + ' .ff').html('<input type="hidden" name="'+settings.fieldName+'" value="'+settings.fieldValue+'" />');
      }
  
  }



$(document).ready(function() {
  
  $(".field.f_sex").each(function(){
    fieldType_Sex({showField: !$(this).hasClass("field_disabled"), containerId: "container_"+$(this).attr("id"),fieldName: $(this).attr("id"), fieldValue: $(this).find(".ff input").attr("value")});
  });
});

function fieldType_Sex(settings)
  {
    settings = jQuery.extend({
      
      fieldName: '',
      containerId: '',
      showField: true,
      fieldValue: '',
      
      labelMale: 'Muž',
      labelFemale: 'Žena'
      
    },settings);
    
    initialize();
    
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
        });
        
        settings.container = $('#' + settings.containerId);
        //alert(settings.fieldValue);
      }
    
    function show()
      {
        //alert(settings.fieldValue);
        settings.container.html('');
        settings.container.append(
          '<label for="'+settings.fieldName+'_radio">'+settings.labelFemale+'<input class="input_radio" type="radio" name="'+settings.fieldName + '_radio" id="f_'+settings.fieldName+'_0" value="0" '+(settings.fieldValue == 0 ? 'checked="checked"' : '')+' /></label>' + 
          '<label for="'+settings.fieldName+'_radio">'+settings.labelMale+'<input class="input_radio" type="radio" name="'+settings.fieldName + '_radio" id="f_'+settings.fieldName+'_1" value="1" '+(settings.fieldValue == 1 ? 'checked="checked"' : '')+' /></label>' +
          '<input class="input_hidden" type="hidden" name="'+settings.fieldName+'" id="f_'+settings.fieldName+'" value="' + settings.fieldValue + '" />'
        );
        $(settings.container).find("input[type='radio']").click(function(){$("#f_"+settings.fieldName).attr("value", $(this).attr("value"));});
      }
      
    function remove()
      {
        $('#' + settings.fieldName + ' .ff').html('');
      }
  
  }


$(document).ready(function() {
  $(".f_shoplist").each(function(){
    fieldType_ShopList({Obj: $(this), showField: !$(this).hasClass("field_disabled"), fieldName: $(this).attr("id"),containerId: "container_"+$(this).attr("id"),fieldItem: OrderItem});
  });
}); 

//var Structure = new Array();
//var StructureField = new Array();

function fieldType_ShopList(settings)
  {
    settings = jQuery.extend({
      
      Obj: new Object(),
      fieldName: '',
      containerId: '',
      fieldItem: new Array(),
      //fieldId: 0,
      hiddenFields: '',
      showField: true,
      
      labelManager: 'Stránky', 
      labelNoItemsSelected: 'Není vybráno žádné zboží',  
      labelRemoveThisItem: 'Odebrat tuto položku',
      labelRemove: 'Odebrat',
      labelAddItem: 'Přidat zboží',
      labelOpenManager: 'Otevřít průzkumník zboží',
      labelItemLabel: 'Název',
      labelItemAmount: 'Množství'
      
    },settings);
		
		initialize();
		
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
        });
        
        settings.container = $('#' + settings.containerId);
        settings.idList = settings.containerId + '_list';
        settings.idButton = settings.fieldName + '_buttonManager';
        settings.saveOneRow = (settings.fieldType == "structure") ? true : false;
      }
      
    function show()
      {
        settings.container.append('<a class="butt_text bt_shoplistmanager" id="' + settings.idButton + '" title="' + settings.labelOpenManager+ '" href="javascript: void(0);">'+settings.labelAddItem+'</a>');
        settings.container.append('<div class="block_shoplist" id="'+settings.idList+'"></div>');
        $('#'+settings.idButton).click(function(){showManager();});
        showList();
      }
    
    function getDisabledItems()
      {
        var arr = new Array();
        var i = 0;
        
        for (x in settings.fieldItem)
          {
            arr[i] = settings.fieldItem[x]["page_id"];
            i++;
          }
        return arr;
      }
    
    function showManager()
      {
        var disabled = getDisabledItems();
        
        ShowDialogWindow({
          windowID: 'dlg_manager', 
          title: settings.labelManager, 
          width: 800, 
          height: 500, 
          callin: function(win){
          
          shopListManager({
            con: win,
            disabledItem: disabled
          });
          
          }, 
          callback: function(win){
            win.find('.row_item').each(function(){
              
              if($(this).find('input:checkbox').attr("checked"))
                {
                  var record = new Array();
                  record["page_id"] = $(this).find("input:checkbox").attr("value");
                  record["label"] = $(this).find(".td_manager_name").html();
                  record["amount"] = 1;
                  returnItem(record);
                }
              });
              showList(); 
          }
          });
      }
    
    function remove()
      {
        settings.container.html('');
      }
    
    function showList()
      {
        var disabled = getDisabledItems();
        settings.hiddenFields = '';
        $("#" + settings.idList).html('');
        $("#" + settings.idList).append('\n<table cellspacing="0"></table>');
        $("#" + settings.idList + ' table').append('\n<tr><th>'+settings.labelItemLabel+'</th><th>'+settings.labelItemAmount+'</th><th>&nbsp;</th></tr>');
        if(arrayLength(settings.fieldItem))
          { 
            for(x in settings.fieldItem)
              {
                showRow(x);
              }
            //settings.hiddenFields+='<input class="input_hidden" type="hidden" name="' + settings.fieldName + '_order_id" value="' + settings.fieldId + '" />'; 
              
            $("#" + settings.idList).append(settings.hiddenFields);
          }
        else
          {
            $('#' + settings.idList + ' table').append('<tr><td class="td_empty_note"><strong class="empty_note">' + settings.labelNoItemsSelected + '</strong></td></tr>');
          }
      }
    
    function showRow(x)
      {
        id_blockItem = settings.fieldName + '_item_' + x;
        
        $("#" + settings.idList + ' table').append(
          '<tr id="' + id_blockItem + '">' +
          '<td class="td_shoplist_label">' + settings.fieldItem[x]["label"] + '</td>' + 
          '<td class="td_shoplist_amount"><input name="' + settings.fieldName + '_amount['+x+']" type="text" value="' + settings.fieldItem[x]["amount"] + '" /></td>' + 
          '<td class="td_shoplist_toolbar">' +
          '<a class="butt_small bs_remove" title="' + settings.labelRemoveThisItem + '" href="javascript:void(0);">' + settings.labelRemove + '</a>' +
          '</td>' + 
          '</tr>'
        ); 
        
        $('#' + id_blockItem + ' .bs_remove').click(function(){removeItem(x);});
            
        settings.hiddenFields += '<input class="input_hidden" type="hidden" name="' + settings.fieldName + '_page_id['+x+']" value="' + settings.fieldItem[x]["page_id"] + '" />';
      }
      
    function returnItem(record)
      {
        settings.fieldItem[settings.fieldItem.length] = record;
      }
      
    function removeItem(x)
      {
        delete settings.fieldItem[x];
        showList();
      }
    
  }

$(document).ready(function() {
  $(".f_structure").each(function(){
    fieldType_Structure({Obj: $(this), showField: !$(this).hasClass("field_disabled"), fieldName: $(this).attr("id"),fieldType: "structure",containerId: "container_"+$(this).attr("id"),fieldItem: Structure[$(this).attr("id")]});
  });
  $(".f_relations").each(function(){
    fieldType_Structure({Obj: $(this), showField: !$(this).hasClass("field_disabled"), fieldName: $(this).attr("id"),fieldType: "relations",containerId: "container_"+$(this).attr("id"),fieldItem: Structure[$(this).attr("id")]});
  });
}); 

var Structure = new Array();
var StructureField = new Array();

function fieldType_Structure(settings)
  {
    settings = jQuery.extend({
      
      Obj: new Object(),
      fieldName: '',
      fieldType: 'structure',
      containerId: '',
      fieldItem: new Array(),
      hiddenFields: '',
      showField: true,
      saveOneRow: false,
      
      labelManager: 'Stránky', 
      labelNoItemsSelected: 'Nejsou vybrána žádná zařazení',  
      labelRemoveThisItem: 'Odebrat toto zařazení',
      labelRemove: 'Odebrat',
      labelAddItem: 'Přidat zařazení',
      labelEditThisItem: 'Upravit toto zařazení',
      labelOpenManager: 'Otevřít průzkumník stránek'
      
    },settings);
		
		initialize();
		
    if(settings.showField){show();}
    else{remove();}
    
    function initialize()
      {
        $('#' + settings.fieldName + ' label input').unbind("click").click(function(){
          if($(this).attr("checked")){show();}
          else{remove();}
        });
        
        settings.container = $('#' + settings.containerId);
        settings.idList = settings.containerId + '_list';
        settings.idButton = settings.fieldName + '_buttonManager';
        settings.saveOneRow = (settings.fieldType == "structure") ? true : false;
      }
      
    function show()
      {
        settings.container.append('<a class="butt_text bt_structuremanager" id="' + settings.idButton + '" title="' + settings.labelOpenManager+ '" href="javascript: void(0);">'+settings.labelAddItem+'</a>');
        settings.container.append('<div class="block_structurelist" id="'+settings.idList+'"></div>');
        $('#'+settings.idButton).click(function(){showManager();});
        showList();
      }
    
    function getDisabledItems(key)
      {
        var arr = new Array();
        var i = 0;
        
        
        
        for (x in settings.fieldItem)
          {
            if(settings.fieldItem[x]["key"] != key) {arr[i] = settings.fieldItem[x]["key"];}
            i++;
          }
          
        //if(settings.fieldItem.length && settings.fieldItem[0]["id"] != 0){arr[i] = settings.fieldItem[0]["id"];}
        //alert(arr.join(","));
        return arr;
      }
    
    function showManager(x)
      {
        var x = x || ''; 
        var selected = x.length ? settings.fieldItem[x]["key"] : '';
        var disabled = getDisabledItems((x.length ? settings.fieldItem[x]["key"] : ''));
        var disabled_section = new Array();
        for(i in settings.fieldItem)
          {
            if(settings.fieldItem[i]["id"] != 0){disabled_section[disabled_section.length] = settings.fieldItem[i]["id"];}
          }
        //var disabled_section = settings.fieldItem.length && settings.fieldItem[0]["id"] != 0 ? [settings.fieldItem[0]["id"]] : new Array();
        var path = x.length ? settings.fieldItem[x]["path"] : [0,1];
        
        ShowDialogWindow({
          windowID: 'dlg_manager', 
          title: settings.labelManager, 
          width: 800, 
          height: 500, 
          callin: function(win){
          
          pagesManager({
            con: win,
            selectedItem: selected,
            disabledItem: disabled,
            disabledSection: disabled_section,
            multiple: false,
            Path: path,
            type: "structure"
          });
          
          }, 
          callback: function(win){
            win.find('.item').each(function(){
              
              if($(this).find('input:checkbox').attr("checked"))
                {
                  var record = new Array();
                  if(!x.length){record["id"] = 0;}
                  else{record["id"] = settings.fieldItem[x]["id"];}
                  record["key"] = $(this).find("input:checkbox").attr("value");
                  record["path"] = $(this).find("input:checkbox").attr("path").split(",");
                  record["label"] = $(this).find("input:checkbox").attr("label");
                  returnItem(x, record);
                }
              });
              showList(); 
          }
          });
      }
    
    function remove()
      {
        settings.container.html('');
      }
    
    function showList()
      {
        var disabled = getDisabledItems();
        settings.hiddenFields = '';
        $("#" + settings.idList).html('');
        $("#" + settings.idList).append('\n<table cellspacing="0"></table>');
        if(arrayLength(settings.fieldItem))
          { 
            for(x in settings.fieldItem)
              {
                //if(!in_array(settings.fieldItem[x]["key"], disabled))
                //  {
                    showRow(x);
                //  }
                //else
                //  {
                //    showNotice(settings.Obj, 'Nepovolené zařazení stránky "'+settings.fieldItem[x]["label"]+'" bylo vyřazeno');
                //  }
              }
            $("#" + settings.idList).append(settings.hiddenFields);
          }
        else
          {
            $('#' + settings.idList + ' table').append('<tr><td class="td_empty_note"><strong class="empty_note">' + settings.labelNoItemsSelected + '</strong></td></tr>');
          }
      }
    
    function showRow(x)
      {
        id_blockItem = settings.fieldName + '_item_' + x;
        
        $("#" + settings.idList + ' table').append(
          '<tr id="' + id_blockItem + '">' +
          '<td class="td_structure_link"><a href="javascript:void(0);" title="' + settings.labelEditThisItem + '">' + settings.fieldItem[x]["label"] + '</a></td>' + 
          '<td class="td_structure_toolbar">' +
          (
            (settings.saveOneRow && arrayLength(settings.fieldItem)>1) || !settings.saveOneRow ?
             '<a class="butt_small bs_remove" title="' + settings.labelRemoveThisItem + '" href="javascript:void(0);">' + settings.labelRemove + '</a>'
             :
             '&nbsp;'
          ) +
          '</td>' + 
          //'<td class="td_empty_note"><strong class="empty_note">' + settings.labelNoItemsSelected + '</strong></td>' + 
          '</tr>'
        ); 
        
        $('#' + id_blockItem + ' .td_structure_link a').click(function(){showManager(x);});
        $('#' + id_blockItem + ' .bs_remove').click(function(){removeItem(x);});
            
        settings.hiddenFields += 
              '<input class="input_hidden" type="hidden" name="' + settings.fieldName + '_id['+x+']" value="' + settings.fieldItem[x]["id"] + '" />' + 
              '<input class="input_hidden" type="hidden" name="' + settings.fieldName + '_key['+x+']" value="' + settings.fieldItem[x]["key"] + '" />';
      }
      
    function returnItem(x, record)
      {
        settings.fieldItem[(x.length ? x : settings.fieldItem.length)] = record;
      }
      
    function removeItem(x)
      {
        delete settings.fieldItem[x];
        showList();
      }
    
  }

function IsUserNameUnique(field, id, username)
  {
    $.post("/index.php", {'initialize_for_ajax' : 'true', 'file': './scripts/components/system/users/mods/mod_unique_username.php', 'user_username': username, 'user_id': id}, function(data)
    {
      if(data.result == false) {FocusTabField(field);inlineMsg(field,data.alert,2);return false;}
    }, "json");
  }


$(document).ready(function() {
  initFields();
}); 

function initFields()
  {
    $(".field").each(function(){
    var obj = $(this);
    $(this).find("> label input").click(function(){
      obj.toggleClass("field_disabled");
      obj.removeClass("field_ok").removeClass("field_fail");
      obj.find(".ff input, .ff select, .ff textarea").attr("disabled", !$(this).attr("checked"));
      //obj.find(".ff input, .ff select, .ff textarea").attr("value", "");
      });
    });
    highlightFields();
  }

function highlightFields()
  {
    $("input, select, textarea").removeClass("if_highlight").focus(function () {$(this).addClass("if_highlight");}).blur(function () {$(this).removeClass("if_highlight");});
  }

function showNotice(d_object, text)
  {
    if(!d_object.find("block_notice").length){d_object.append('<div class="block_notice"><strong>Upozornění</strong></div>');}
    d_object.find(".block_notice").append('<div class="notice_item">'+text+'</div>');
  }

function setFieldOk(id)
  {
    $('#'+id).removeClass("field_fail").addClass("field_ok");
    return true;
  }

function setFieldFail(id, alert)
  {
    alert = alert || '';
    defaultCaption = 'Format neni spravny!';
    if($(".tabbertab").length){FocusTabField(id);}
    $('#'+id).removeClass("field_ok").addClass("field_fail");
    inlineMsg(id, (alert.length ? alert : defaultCaption), 2);
    return false;
  }
  
function submitForm(form, action)
  {
    var action = action || '';
    if(action.length){$(form).attr("action", action);}
    if(!$(form).find(".field").hasClass("field_fail")){form.submit();}
  }

// START OF MESSAGE SCRIPT //

var MSGTIMER = 20;
var MSGSPEED = 5;
var MSGOFFSET = 3;
var MSGHIDE = 3;

// build out the divs, set attributes and call the fade function //
function inlineMsg(target,string,autohide) {
  var msg;
  var msgcontent;
  if(!document.getElementById('msg')) {
    msg = document.createElement('div');
    msg.id = 'msg';
    msgcontent = document.createElement('div');
    msgcontent.id = 'msgcontent';
    document.body.appendChild(msg);
    msg.appendChild(msgcontent);
    msg.style.filter = 'alpha(opacity=0)';
    msg.style.opacity = 0;
    msg.alpha = 0;
  } else {
    msg = document.getElementById('msg');
    msgcontent = document.getElementById('msgcontent');
  }
  msgcontent.innerHTML = string;
  msg.style.display = 'block';
  var msgheight = msg.offsetHeight;
  var targetdiv = document.getElementById(target);
  targetdiv.focus();
  var targetheight = targetdiv.offsetHeight;
  var targetwidth = targetdiv.offsetWidth;
  var topposition = topPosition(targetdiv) - ((msgheight - targetheight) / 2);
  var leftposition = leftPosition(targetdiv) + targetwidth + MSGOFFSET;
  msg.style.top = topposition + 'px';
  msg.style.left = leftposition + 'px';
  clearInterval(msg.timer);
  msg.timer = setInterval("fadeMsg(1)", MSGTIMER);
  if(!autohide) {
    autohide = MSGHIDE;  
  }
  window.setTimeout("hideMsg()", (autohide * 1000));
}

// hide the form alert //
function hideMsg(msg) {
  var msg = document.getElementById('msg');
  if(!msg.timer) {
    msg.timer = setInterval("fadeMsg(0)", MSGTIMER);
  }
}

// face the message box //
function fadeMsg(flag) {
  if(flag == null) {
    flag = 1;
  }
  var msg = document.getElementById('msg');
  var value;
  if(flag == 1) {
    value = msg.alpha + MSGSPEED;
  } else {
    value = msg.alpha - MSGSPEED;
  }
  msg.alpha = value;
  msg.style.opacity = (value / 100);
  msg.style.filter = 'alpha(opacity=' + value + ')';
  if(value >= 99) {
    clearInterval(msg.timer);
    msg.timer = null;
  } else if(value <= 1) {
    msg.style.display = "none";
    clearInterval(msg.timer);
  }
}

// calculate the position of the element in relation to the left of the browser //
function leftPosition(target) {
  var left = 0;
  if(target.offsetParent) {
    while(1) {
      left += target.offsetLeft;
      if(!target.offsetParent) {
        break;
      }
      target = target.offsetParent;
    }
  } else if(target.x) {
    left += target.x;
  }
  return left;
}

// calculate the position of the element in relation to the top of the browser window //
function topPosition(target) {
  var top = 0;
  if(target.offsetParent) {
    while(1) {
      top += target.offsetTop;
      if(!target.offsetParent) {
        break;
      }
      target = target.offsetParent;
    }
  } else if(target.y) {
    top += target.y;
  }
  return top;
}

// preload the arrow //
if(document.images) {
  arrow = new Image(7,80); 
  arrow.src = "templates/admin/images/msg_arrow.gif"; 
}

function FocusTabField(o_id)
 {
    Pobj = o(o_id);
    if(Pobj)
      {
        if(Pobj.className == "undefined") {Pobj.className = "tbss";}
    
        while(Pobj.className.substr(0, 9) != "tabbertab")
          {
            Pobj = Pobj.parentNode;
            if(Pobj.className == "undefined") {Pobj.className = "tbss";}
          }
        document.getElementById('mytab1').tabber.tabShow(Pobj.id.substring(4));
        Pobj.focus();
      }
    return false;
  }
/*==================================================
  $Id: tabber.js,v 1.9 2006/04/27 20:51:51 pat Exp $
  tabber.js by Patrick Fitzgerald pat@barelyfitz.com

  Documentation can be found at the following URL:
  http://www.barelyfitz.com/projects/tabber/

  License (http://www.opensource.org/licenses/mit-license.php)

  Copyright (c) 2006 Patrick Fitzgerald

  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.
  ==================================================*/

function tabberObj(argsObj)
{
  var arg; /* name of an argument to override */

  /* Element for the main tabber div. If you supply this in argsObj,
     then the init() method will be called.
  */
  this.div = null;

  /* Class of the main tabber div */
  this.classMain = "tabber";

  /* Rename classMain to classMainLive after tabifying
     (so a different style can be applied)
  */
  this.classMainLive = "tabberlive";

  /* Class of each DIV that contains a tab */
  this.classTab = "tabbertab";

  /* Class to indicate which tab should be active on startup */
  this.classTabDefault = "tabbertabdefault";

  /* Class for the navigation UL */
  this.classNav = "tabbernav";

  /* When a tab is to be hidden, instead of setting display='none', we
     set the class of the div to classTabHide. In your screen
     stylesheet you should set classTabHide to display:none.  In your
     print stylesheet you should set display:block to ensure that all
     the information is printed.
  */
  this.classTabHide = "tabbertabhide";

  /* Class to set the navigation LI when the tab is active, so you can
     use a different style on the active tab.
  */
  this.classNavActive = "tabberactive";

  /* Elements that might contain the title for the tab, only used if a
     title is not specified in the TITLE attribute of DIV classTab.
  */
  this.titleElements = ['h2','h3','h4','h5','h6'];

  /* Should we strip out the HTML from the innerHTML of the title elements?
     This should usually be true.
  */
  this.titleElementsStripHTML = true;

  /* If the user specified the tab names using a TITLE attribute on
     the DIV, then the browser will display a tooltip whenever the
     mouse is over the DIV. To prevent this tooltip, we can remove the
     TITLE attribute after getting the tab name.
  */
  this.removeTitle = true;
  
  /* If you want to add an id to each link set this to true */
  this.addLinkId = false;

  /* If addIds==true, then you can set a format for the ids.
     <tabberid> will be replaced with the id of the main tabber div.
     <tabnumberzero> will be replaced with the tab number
       (tab numbers starting at zero)
     <tabnumberone> will be replaced with the tab number
       (tab numbers starting at one)
     <tabtitle> will be replaced by the tab title
       (with all non-alphanumeric characters removed)
   */
  this.linkIdFormat = '<tabberid>nav<tabnumberone>';

  /* You can override the defaults listed above by passing in an object:
     var mytab = new tabber({property:value,property:value});
  */
  for (arg in argsObj) { this[arg] = argsObj[arg]; }

  /* Create regular expressions for the class names; Note: if you
     change the class names after a new object is created you must
     also change these regular expressions.
  */
  this.REclassMain = new RegExp('\\b' + this.classMain + '\\b', 'gi');
  this.REclassMainLive = new RegExp('\\b' + this.classMainLive + '\\b', 'gi');
  this.REclassTab = new RegExp('\\b' + this.classTab + '\\b', 'gi');
  this.REclassTabDefault = new RegExp('\\b' + this.classTabDefault + '\\b', 'gi');
  this.REclassTabHide = new RegExp('\\b' + this.classTabHide + '\\b', 'gi');

  /* Array of objects holding info about each tab */
  this.tabs = new Array();

  /* If the main tabber div was specified, call init() now */
  if (this.div) {

    this.init(this.div);

    /* We don't need the main div anymore, and to prevent a memory leak
       in IE, we must remove the circular reference between the div
       and the tabber object. */
    this.div = null;
  }
}


/*--------------------------------------------------
  Methods for tabberObj
  --------------------------------------------------*/


tabberObj.prototype.init = function(e)
{
  /* Set up the tabber interface.

     e = element (the main containing div)

     Example:
     init(document.getElementById('mytabberdiv'))
   */

  var
  childNodes, /* child nodes of the tabber div */
  i, i2, /* loop indices */
  t, /* object to store info about a single tab */
  defaultTab=0, /* which tab to select by default */
  DOM_ul, /* tabbernav list */
  DOM_li, /* tabbernav list item */
  DOM_a, /* tabbernav link */
  aId, /* A unique id for DOM_a */
  headingElement; /* searching for text to use in the tab */

  /* Verify that the browser supports DOM scripting */
  if (!document.getElementsByTagName) { return false; }

  /* If the main DIV has an ID then save it. */
  if (e.id) {
    this.id = e.id;
  }

  /* Clear the tabs array (but it should normally be empty) */
  this.tabs.length = 0;

  /* Loop through an array of all the child nodes within our tabber element. */
  childNodes = e.childNodes;
  for(i=0; i < childNodes.length; i++) {

    /* Find the nodes where class="tabbertab" */
    if(childNodes[i].className &&
       childNodes[i].className.match(this.REclassTab)) {
      
      /* Create a new object to save info about this tab */
      t = new Object();
      
      /* Save a pointer to the div for this tab */
      t.div = childNodes[i];
      
      /* Add the new object to the array of tabs */
      this.tabs[this.tabs.length] = t;

      /* If the class name contains classTabDefault,
	 then select this tab by default.
      */
      if (childNodes[i].className.match(this.REclassTabDefault)) {
	defaultTab = this.tabs.length-1;
      }
    }
  }

  /* Create a new UL list to hold the tab headings */
  DOM_ul = document.createElement("ul");
  DOM_ul.className = this.classNav;
  
  /* Loop through each tab we found */
  for (i=0; i < this.tabs.length; i++) {

    t = this.tabs[i];

    /* Get the label to use for this tab:
       From the title attribute on the DIV,
       Or from one of the this.titleElements[] elements,
       Or use an automatically generated number.
     */
    t.headingText = t.div.title;

    /* Remove the title attribute to prevent a tooltip from appearing */
    if (this.removeTitle) { t.div.title = ''; }

    if (!t.headingText) {

      /* Title was not defined in the title of the DIV,
	 So try to get the title from an element within the DIV.
	 Go through the list of elements in this.titleElements
	 (typically heading elements ['h2','h3','h4'])
      */
      for (i2=0; i2<this.titleElements.length; i2++) {
	headingElement = t.div.getElementsByTagName(this.titleElements[i2])[0];
	if (headingElement) {
	  t.headingText = headingElement.innerHTML;
	  if (this.titleElementsStripHTML) {
	    t.headingText.replace(/<br>/gi," ");
	    t.headingText = t.headingText.replace(/<[^>]+>/g,"");
	  }
	  break;
	}
      }
    }

    if (!t.headingText) {
      /* Title was not found (or is blank) so automatically generate a
         number for the tab.
      */
      t.headingText = i + 1;
    }

    /* Create a list element for the tab */
    DOM_li = document.createElement("li");

    /* Save a reference to this list item so we can later change it to
       the "active" class */
    t.li = DOM_li;

    /* Create a link to activate the tab */
    DOM_a = document.createElement("a");
    DOM_a.appendChild(document.createTextNode(t.headingText));
    DOM_a.href = "javascript:void(null);";
    DOM_a.title = t.headingText;
    DOM_a.id = "a_tab_"+i;
    DOM_a.onclick = this.navClick;

    /* Add some properties to the link so we can identify which tab
       was clicked. Later the navClick method will need this.
    */
    DOM_a.tabber = this;
    DOM_a.tabberIndex = i;

    /* Do we need to add an id to DOM_a? */
    if (this.addLinkId && this.linkIdFormat) {

      /* Determine the id name */
      aId = this.linkIdFormat;
      aId = aId.replace(/<tabberid>/gi, this.id);
      aId = aId.replace(/<tabnumberzero>/gi, i);
      aId = aId.replace(/<tabnumberone>/gi, i+1);
      aId = aId.replace(/<tabtitle>/gi, t.headingText.replace(/[^a-zA-Z0-9\-]/gi, ''));

      DOM_a.id = aId;
    }

    /* Add the link to the list element */
    DOM_li.appendChild(DOM_a);
    
    /* Add the list element to the list */
    DOM_ul.appendChild(DOM_li);
  }

  /* Add the UL list to the beginning of the tabber div */
  e.insertBefore(DOM_ul, e.firstChild);

  /* Make the tabber div "live" so different CSS can be applied */
  e.className = e.className.replace(this.REclassMain, this.classMainLive);
  e.id = "mytab1"; 
  /* Activate the default tab, and do not call the onclick handler */
  this.tabShow(defaultTab);

  /* If the user specified an onLoad function, call it now. */
  if (typeof this.onLoad == 'function') {
    this.onLoad({tabber:this});
  }

  return this;
};


tabberObj.prototype.navClick = function(event)
{
  //if(ValidateForm())
  //  {
  /* This method should only be called by the onClick event of an <A>
     element, in which case we will determine which tab was clicked by
     examining a property that we previously attached to the <A>
     element.

     Since this was triggered from an onClick event, the variable
     "this" refers to the <A> element that triggered the onClick
     event (and not to the tabberObj).

     When tabberObj was initialized, we added some extra properties
     to the <A> element, for the purpose of retrieving them now. Get
     the tabberObj object, plus the tab number that was clicked.
  */

  var
  rVal, /* Return value from the user onclick function */
  a, /* element that triggered the onclick event */
  self, /* the tabber object */
  tabberIndex, /* index of the tab that triggered the event */
  onClickArgs; /* args to send the onclick function */

  a = this;
  if (!a.tabber) { return false; }

  self = a.tabber;
  tabberIndex = a.tabberIndex;

  /* Remove focus from the link because it looks ugly.
     I don't know if this is a good idea...
  */
  a.blur();

  /* If the user specified an onClick function, call it now.
     If the function returns false then do not continue.
  */
  if (typeof self.onClick == 'function') {

    onClickArgs = {'tabber':self, 'index':tabberIndex, 'event':event};

    /* IE uses a different way to access the event object */
    if (!event) { onClickArgs.event = window.event; }

    rVal = self.onClick(onClickArgs);
    if (rVal === false) { return false; }
  }

  self.tabShow(tabberIndex);
  //}
  return false;
};


tabberObj.prototype.tabHideAll = function()
{
  var i; /* counter */

  /* Hide all tabs and make all navigation links inactive */
  for (i = 0; i < this.tabs.length; i++) {
    this.tabHide(i);
  }
};


tabberObj.prototype.tabHide = function(tabberIndex)
{
  var div;

  if (!this.tabs[tabberIndex]) { return false; }

  /* Hide a single tab and make its navigation link inactive */
  div = this.tabs[tabberIndex].div;

  /* Hide the tab contents by adding classTabHide to the div */
  if (!div.className.match(this.REclassTabHide)) {
    div.className += ' ' + this.classTabHide;
    div.id = "tab_"+tabberIndex;
  }
  this.navClearActive(tabberIndex);

  return this;
};


tabberObj.prototype.tabShow = function(tabberIndex)
{
  /* Show the tabberIndex tab and hide all the other tabs */

  var div;

  if (!this.tabs[tabberIndex]) { return false; }

  /* Hide all the tabs first */
  this.tabHideAll();

  /* Get the div that holds this tab */
  div = this.tabs[tabberIndex].div;

  /* Remove classTabHide from the div */
  div.className = div.className.replace(this.REclassTabHide, '');

  /* Mark this tab navigation link as "active" */
  this.navSetActive(tabberIndex);

  /* If the user specified an onTabDisplay function, call it now. */
  if (typeof this.onTabDisplay == 'function') {
    this.onTabDisplay({'tabber':this, 'index':tabberIndex});
  }

  return this;
};

tabberObj.prototype.navSetActive = function(tabberIndex)
{
  /* Note: this method does *not* enforce the rule
     that only one nav item can be active at a time.
  */

  /* Set classNavActive for the navigation list item */
  this.tabs[tabberIndex].li.className = this.classNavActive;

  return this;
};


tabberObj.prototype.navClearActive = function(tabberIndex)
{
  /* Note: this method does *not* enforce the rule
     that one nav should always be active.
  */

  /* Remove classNavActive from the navigation list item */
  this.tabs[tabberIndex].li.className = '';

  return this;
};


/*==================================================*/


function tabberAutomatic(tabberArgs)
{
  /* This function finds all DIV elements in the document where
     class=tabber.classMain, then converts them to use the tabber
     interface.

     tabberArgs = an object to send to "new tabber()"
  */
  var
    tempObj, /* Temporary tabber object */
    divs, /* Array of all divs on the page */
    i; /* Loop index */

  if (!tabberArgs) { tabberArgs = {}; }

  /* Create a tabber object so we can get the value of classMain */
  tempObj = new tabberObj(tabberArgs);

  /* Find all DIV elements in the document that have class=tabber */

  /* First get an array of all DIV elements and loop through them */
  divs = document.getElementsByTagName("div");
  for (i=0; i < divs.length; i++) {
    
    /* Is this DIV the correct class? */
    if (divs[i].className &&
	divs[i].className.match(tempObj.REclassMain)) {
      
      /* Now tabify the DIV */
      tabberArgs.div = divs[i];
      divs[i].tabber = new tabberObj(tabberArgs);
    }
  }
  
  return this;
}


/*==================================================*/

/*
function tabberAutomaticOnLoad(tabberArgs)
{
  var oldOnLoad;
  if (!tabberArgs) { tabberArgs = {}; }
  
  oldOnLoad = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = function() {
    
      tabberAutomatic(tabberArgs);
    };
  } else {
    window.onload = function() {
    
      oldOnLoad();
      tabberAutomatic(tabberArgs);
    };
  }
}
*/
$(document).ready(function(){

if (typeof tabberOptions == 'undefined') { tabberOptions = {}; }
tabberAutomatic(tabberOptions);

});


/*==================================================*/


/* Run tabberAutomaticOnload() unless the "manualStartup" option was specified */
/*
if (typeof tabberOptions == 'undefined') {

    tabberAutomaticOnLoad();

} else {

  if (!tabberOptions['manualStartup']) {
    tabberAutomaticOnLoad(tabberOptions);
  }

}
*/