﻿/*
var debug = function(text, append) {
	var t;
	if (!(t = $("testout"))) { return; }
	if (append) {
		t.appendChild(document.createTextNode(text));
	} else {
		t.update(document.createTextNode(text));
	}
}
*/	
if (!BackAgent) { var BackAgent = {}; };
BackAgent.DatePicker = Class.create();
BackAgent.DatePicker.prototype = {
	// constructor
	initialize: function(targets, options) {
		this.setOptions(options);

		this._createPicker();
		this.setValue(new Date());
		this.hide();

		this.targetElements = [];
		this.addTargets(targets);
	},
	// public methods - config
	addTargets: function() {
var s = "ran";
		for (var i = 0; i < arguments.length; i++) {
			var arg = arguments[i];
			if (arg) {
				if (typeof arg !== "string" && arg.length) {
					for (var j = 0; j < arg.length; j++) {
						var elem = $(arg[j]);
						if (elem) {
							this.targetElements.push(elem);
							this._attachTarget(elem);
s += " " + elem.id;
						}
					}
				}
				else {
					var elem = $(arg);
					if (elem) {
						this.targetElements.push(elem);
						this._attachTarget(elem);
s += " " + elem.id;
					}
				}
			}
		}
//alert(s);
	},
	setOptions: function(options) {
		this.options = {
			pickerId:       "",
			pickerClass:    "jsDatePicker",
			behavior:       "manual",		// values: manual, focus
			valueFormat:    "m/d/yyyy",
			fixed: false,
			positionOffset: { x: 0, y: 0 },
			onchange:		null
		};
		Object.extend(this.options, options || {});

		this.setPickerId(this.options.pickerId);
		this.setPickerClass(this.options.pickerClass);
	},
	setPickerId: function(psId) {
		this.options.pickerId = psId;

		var root = this.rootElement;
		if (!root) { return; }
		root.id = psId.toString();
	},
	setPickerClass: function(psClass) {
		this.options.pickerClass = psClass;

		var root = this.rootElement;
		if (!root) { return; }
		root.className = psClass.toString();
	},
	setValue: function(pdDate) {
		var d = new Date(pdDate);
		if (isNaN(d)) { d = new Date(); }
		this.value = d;
		this.setView(d);
	},
	setView: function(pdDate) {
		var d = new Date(pdDate);
		if (isNaN(d)) { return; }

		// save first date of month/year as guide for nav
		var v = new Date(d.getFullYear(), d.getMonth(), 1);
		this._viewDate = v;

		// calculate start date for day and year arrays
		var offset = 0 - v.getDay();
		if (offset == 0) { offset = -7; }
		this._firstDate = new Date(v.getFullYear(), v.getMonth(), 1 + offset);
		this._firstYear = v.getFullYear() - 7;	// hardcode

		this._updatePickDay();
		this._updatePickMonth();
		this._updatePickYear();
	},
	// public methods - behavior
	hide: function() {
		var root = this.rootElement;
		if (!root) { return; }
		root.style.visibility = "hidden";
		this._showing = false;
	},
	show: function() {
		var root = this.rootElement;
		if (!root) { return; }
		var targ = this.currentTarget;
		if (!this._showing) {
			this._clickUpDown(0);
			this._focusTarget();
			this._setPosition();
			if (targ) {
//				var n = targ.getAttribute("data");
				var n = targ.value;
				this.setValue(n);
			}
		}
		root.style.visibility = "visible";
		this._showing = true;
	},
	toggle: function() {
		if (this._showing) {
			this.hide();
		} else {
			this.show();
		}
	},
	showByTarget: function(element) {
		var root = this.rootElement;
		if (!root) { return; }
		element = $(element);
		if (!element) { return; }
		this.currentTarget = element;
		this._showTimed();
	},
	toggleByTarget: function(element) {
		if (this._showing) {
			this.hide();
		} else {
			this.showByTarget(element);
		}
	},
	// private methods - behavior
	_cancelTiming: function() {
		if (this.showTimeout) {
			window.clearTimeout(this.showTimeout);
			this.showTimeout = null;
		}
		if (this.hideTimeout) {
			window.clearTimeout(this.hideTimeout);
			this.hideTimeout = null;
		}
	},
	_hideTimed: function() {
		this._cancelTiming();
		if (this._showing) {
			this.hideTimeout = window.setTimeout(this.hide.bind(this), 200);
		}
	},
	_showTimed: function() {
		this._cancelTiming();
		if (!this._showing) {
			this.showTimeout = window.setTimeout(this.show.bind(this), 50);
		}
	},
	// private methods - helper
	_attachTarget: function(elem) {
		var obs = this.targetObservers;
		if (!obs) {
			obs = this.targetObservers = {
				blur: this._onblurTarget.bindAsEventListener(this),
				click: this._onfocusTarget.bindAsEventListener(this),
				focus: this._onfocusTarget.bindAsEventListener(this),
				keypress: this._onkeypressTarget.bindAsEventListener(this),
				formSubmit: this._onsubmitForm.bindAsEventListener(this)
			};
		}
		elem.setAttribute("autocomplete", "off");
		Event.observe(elem, "blur", obs.blur);
		Event.observe(elem, "click", obs.click);
		Event.observe(elem, "focus", obs.focus);
		Event.observe(elem, "keydown", obs.keypress);
		// need to hack an onsubmit handler to workaround opera's broken key event
		var f = elem.form;
		if (f && window.opera) {
			if (!this.forms) { this.forms = {}; }
			if (!this.forms[f.id]) {
				Event.observe(f, "submit", obs.formSubmit);
				this.forms[f.id] = true;
			}
		}
	},
	_detachTarget: function(elem) {
		var obs = this.targetObservers;
		if (!obs) { return; }
		var targs = $A(this.targetElements).clone();
		for (var i = 0, length = targs.length; i < length; i++) {
			if (targs[i] == elem) {
				targs = targs.without(elem);
				break;
			}
		}
		this.targetElements = targs;
		
		var f = elem.form, found = false;
		if (f && window.opera) {
			for (var i = 0, length = targs.length; i < length; i++) {
				if (targs[i].form && f == targs[i].form) {
					found = true;
					break;
				}
			}
			if (!found) {
				Event.stopObserving(f, "submit", obs.formSubmit);
			}
		}

		Event.stopObserving(elem, "blur", obs.blur);
		Event.stopObserving(elem, "click", obs.click);
		Event.stopObserving(elem, "focus", obs.focus);
		Event.stopObserving(elem, "keydown", obs.keypress);
	},
	_focusTarget: function() {
		var targ = this.currentTarget;
		if (!targ) { return; }
		try {
			targ.focus();
		} catch(ex) {}
	},
	_getTarget: function(e) {
		var target;
		var element = Event.element(e);
		// go up the tree looking for ids, each id found, look for a match in the Targets collection
		do {
			if (element.nodeType == 1 && element.id) {
				target = this.targetElements.detect(function(value) {
					if (value.id == element.id) { return true; }
					else { return false; }
				});
			}
		} while (!(target) && (element = element.parentNode));
		return target;
	},
	_hackSelects: function() {
		var root = this.rootElement;
		if (!root) { return; }
		// insert an iframe, sized to the outer div, underneath the inner content,
		// to cover select-boxes that peek through
		var iframe = this.hackElement;
		if (window.ActiveXObject && !iframe) {
			iframe = document.createElement("iframe");
			iframe.frameBorder = 0;	// setAttribute doesn't take
			iframe.style.position = "absolute";
			iframe.style.left = "0"; iframe.style.top = "0";
			iframe.style.filter = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)";
			root.insertBefore(iframe, root.firstChild);
			this.hackElement = iframe;
		}
		if (iframe) {
			iframe.style.height = "0";
			var dim = Element.getDimensions(root);
			iframe.style.width = dim.width-2 + "px";	// bad hardcode - 2 is for borders
			iframe.style.height = dim.height-2 + "px";
		}
	},
	_setPosition: function() {
		var root, targ;
		root = this.rootElement;
		if (!root) { return; }
		targ = this.currentTarget;
		if (!targ) { return; }
		var coords = Position.cumulativeOffset(targ);
		//var coords = Position.positionedOffset(targ);
		coords[0] = coords[0] + this.options.positionOffset.x;
		coords[1] = coords[1] + this.options.positionOffset.y;
		root.style.left = coords[0] + "px";
		root.style.top = (coords[1] + targ.offsetHeight - 0) + "px";
	},
	_updateTarget: function() {
		var targ = this.currentTarget;
		if (!targ) { return; }
		var d = this.value;
		targ.value = d.toFormatString(this.options.valueFormat);
		if (typeof this.options.onchange == "function") {
			this.options.onchange(this.currentTarget, d);
		} else if (typeof this.currentTarget.onchange == "function") {
			this.currentTarget.onchange();
		}
//		targ.setAttribute("data", d.toGMTString());
	},
	// handlers - target
	_onblurTarget: function(e) {
		this._hideTimed();
	},
	_onfocusTarget: function(e) {
		var targ = this._getTarget(e);
		if (targ != this.currentTarget) {
			this.hide();
		}
		this.currentTarget = targ;
		if (this._closing) {
			this._closing = false;
		} else if (this.options.behavior == 'focus') {
			this._showTimed();
		} else {
			this._cancelTiming();
		}
	},
	_onkeypressTarget: function(e) {
		// note: focus handles all getTarget calls
		var ret = true;
		if (e.keyCode) {
			var code = e.keyCode;
			switch (code) {
				case Event.KEY_RETURN:
					if (this._showing) {
						Event.stop(e);
						this.currentTarget.form._SlyYDatePickCancelSubmit = true;
						if (this._level == 0) {
							this._closing = true;
							this.hide();
							this._updateTarget();
						} else {
							this._clickUpDown(this._level - 1);
						}
						ret = false;
					}
					break;
				case Event.KEY_ESC:
					if (this._showing) {
						this.hide();
						ret = false;
					}
					break;
				case Event.KEY_UP:
				case Event.KEY_DOWN:
					if (!this._showing) {
						this.show();
					} else {
						var diff = (code == Event.KEY_UP) ? -1 : 1;
						if (this._level == 0) {
							var d = this.value;
							var n = new Date(d.getFullYear(), d.getMonth(), d.getDate() + diff);
						} else if (this._level == 1) {
							var d = this._viewDate;
							var n = new Date(d.getFullYear(), d.getMonth() + diff, d.getDate());
						} else if (this._level == 2) {
							var d = this._viewDate;
							var n = new Date(d.getFullYear() + diff, d.getMonth(), d.getDate());
						}
						this.setValue(n);
					}
					Event.stop(e);
					ret = false;
					break;
			}
		}
		return ret;
	},
	_onsubmitForm: function(e) {
		var f = Event.findElement(e, "form");
		if (f && f._SlyYDatePickCancelSubmit) {
			f._SlyYDatePickCancelSubmit = false;
			Event.stop(e);
			return false;
		}
		return true;
	},
	// handlers - picker
	_onclickPicker: function(e) {
		this._focusTarget();
	},
	_clickUpDown: function(pnIndex) {
		var root, tables;
		root = this.rootElement;
		if (!root) { return; }
		tables = root.getElementsByTagName("table");
		for (var i = 0; i < tables.length; i++) {
			if (i == pnIndex) {
				tables[i].style.display = "block";
			} else {
				tables[i].style.display = "none";
			}
		}
		this._level = pnIndex;
		this._hackSelects();
	},
	_clickDayNav: function(pnDir) {
		var v = this._viewDate;
		var n = new Date(v.getFullYear(), v.getMonth() + pnDir, v.getDate());
		this.setView(n);
	},
	_clickDayItem: function(pnIndex) {
		var f = this._firstDate;
		if (pnIndex < (6 * 7)) {
			var n = new Date(f.getFullYear(), f.getMonth(), f.getDate() + pnIndex);
		} else {
			var n = new Date();
		}
		this.setValue(n);
		this._closing = true;
		this.hide();
		this._updateTarget();
	},
	_clickMonthNav: function(pnDir) {
		var v = this._viewDate;
		var n = new Date(v.getFullYear() + pnDir, v.getMonth(), v.getDate());
		this.setView(n);
	},
	_clickMonthItem: function(pnIndex) {
		var v = this._viewDate;
		if (pnIndex < (4 * 3)) {
			var n = new Date(v.getFullYear(), pnIndex, v.getDate());
		} else {
			var t = new Date();
			var n = new Date(t.getFullYear(), t.getMonth(), v.getDate());
		}
		this.setView(n);
		this._clickUpDown(0);
	},
	_clickYearNav: function(pnDir) {
		var v = this._viewDate;
		var n = new Date(v.getFullYear() + (pnDir * 10), v.getMonth(), v.getDate());
		this.setView(n);
	},
	_clickYearItem: function(pnIndex) {
		var v = this._viewDate;
		var y = this._firstYear;
		if (pnIndex < (5 * 3)) {
			var n = new Date(y + pnIndex, v.getMonth(), v.getDate());
		} else {
			var t = new Date();
			var n = new Date(t.getFullYear(), v.getMonth(), v.getDate());
		}
		this.setView(n);
		this._clickUpDown(1);
	},
	// private methods - generate picker elements
	_createPicker: function() {
		var body, root, table;
		// get body
		body = document.getElementsByTagName("body");
		if (!body.length) { return; }
		body = body[0];

		// create picker div
		root = document.createElement("div");
		if (this.options.pickerId) {
			root.id = this.options.pickerId.toString();
		}
		if (this.options.pickerClass) {
			root.className = this.options.pickerClass.toString();
		}
		root.onclick = this._onclickPicker.bindAsEventListener(this);

		// create day table
		table = root.appendChild(this._createPickDay());
		table.style.position = "relative";
		table.style.display = "block";
		// create month table
		table = root.appendChild(this._createPickMonth());
		table.style.position = "relative";
		table.style.display = "none";
		// create year table
		table = root.appendChild(this._createPickYear());
		table.style.position = "relative";
		table.style.display = "none";

		// set base styles
		root.style.display = "block";
//		root.style.visibility = "hidden";
		if (this.options.fixed) { root.style.position = "fixed"; }
		else { root.style.position = "absolute"; }
		root.style.left = "0";
		root.style.top = "0";

		// place picker in document & save ref
		body.appendChild(root);
		this.rootElement = root;
		this._showing = false;
	},
	_createPickDay: function() {
		var table, thead, tfoot, tbody, row, cell, cellVal;
		// create table of days in month
		table = document.createElement("table");
		table.setAttribute("border", "0");
		table.setAttribute("cellSpacing", "0");
		table.setAttribute("cellPadding", "0");
		table.className = "pickDay";

		// thead
		thead = table.appendChild(document.createElement("thead"));
		// - title and nav
		row = thead.appendChild(document.createElement("tr"));
		row.className = "first";
		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("\u00ab"));
		cell.className = "first";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickDayNav.bind(this, -1);

		cell = row.appendChild(document.createElement("td"));
		cell.setAttribute("colSpan", "5");
		cell.appendChild(document.createTextNode("Mmm YYYY"));
		cell.style.cursor = "pointer";
		cell.onclick = this._clickUpDown.bind(this, 1);

		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("\u00bb"));
		cell.className = "last";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickDayNav.bind(this, 1);

		// - day names
		row = thead.appendChild(document.createElement("tr"));
		row.className = "last";
		for (var j = 0; j < 7; j++) {
			cellVal = Date.prototype._DAYNAMES[j].substr(0, 2);
			cell = row.appendChild(document.createElement("td"));
			cell.appendChild(document.createTextNode(cellVal.toString()));
			if (j == 0) { cell.className = "first"; }
			if (j == 6) { cell.className = "last"; }
		}

		// tfoot
		tfoot = table.appendChild(document.createElement("tfoot"));
		row = tfoot.appendChild(document.createElement("tr"));
		row.className = "first";
		cell = row.appendChild(document.createElement("td"));
		cell.setAttribute("colSpan", "7");
		cell.appendChild(document.createTextNode("Today: Mmm d, YYYY"));
		cell.className = "first last";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickDayItem.bind(this, (6 * 7));

		// tbody
		tbody = table.appendChild(document.createElement("tbody"));
		for (var i = 0; i < 6; i++) {	// 6 rows (weeks)
			row = tbody.appendChild(document.createElement("tr"));
			if (i == 0) { row.className = "first"; }
			if (i == 5) { row.className = "last"; }
			for (var j = 0; j < 7; j++) {	// 7 columns (days)
				cellVal = (i * 7) + j + 1;
				cell = row.appendChild(document.createElement("td"));
				cell.appendChild(document.createTextNode(cellVal.toString()));
				if (j == 0) { cell.className = "first"; }
				if (j == 6) { cell.className = "last"; }
				cell.style.cursor = "pointer";
				cell.onclick = this._clickDayItem.bind(this, (i * 7) + j);
			}
		}
		return table;
	},
	_createPickMonth: function() {
		var table, thead, tfoot, tbody, row, cell, cellVal;
		// create table of months in year
		table = document.createElement("table");
		table.setAttribute("border", "0");
		table.setAttribute("cellSpacing", "0");
		table.setAttribute("cellPadding", "0");
		table.className = "pickMonth";

		// thead
		thead = table.appendChild(document.createElement("thead"));
		// - title and nav
		row = thead.appendChild(document.createElement("tr"));
		row.className = "first";
		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("\u00ab"));
		cell.className = "first";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickMonthNav.bind(this, -1);

		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("YYYY"));
		cell.style.cursor = "pointer";
		cell.onclick = this._clickUpDown.bind(this, 2);

		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("\u00bb"));
		cell.className = "last";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickMonthNav.bind(this, 1);

		// tfoot
		tfoot = table.appendChild(document.createElement("tfoot"));
		row = tfoot.appendChild(document.createElement("tr"));
		row.className = "first";
		cell = row.appendChild(document.createElement("td"));
		cell.setAttribute("colSpan", "3");
		cell.appendChild(document.createTextNode("This month: Mmm"));
		cell.className = "first last";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickMonthItem.bind(this, (4 * 3));

		// tbody
		tbody = table.appendChild(document.createElement("tbody"));
		for (var i = 0; i < 4; i++) {	// 4 rows (quarters)
			row = tbody.appendChild(document.createElement("tr"));
			if (i == 0) { row.className = "first"; }
			if (i == 3) { row.className = "last"; }
			for (var j = 0; j < 3; j++) {	// 3 columns
				cellVal = Date.prototype._MONTHNAMES[(i * 3) + j].substr(0, 3);
				cell = row.appendChild(document.createElement("td"));
				cell.appendChild(document.createTextNode(cellVal.toString()));
				if (j == 0) { cell.className = "first"; }
				if (j == 2) { cell.className = "last"; }
				cell.style.cursor = "pointer";
				cell.onclick = this._clickMonthItem.bind(this, (i * 3) + j);
			}
		}
		return table;
	},
	_createPickYear: function() {
		var table, thead, tfoot, tbody, row, cell, cellVal;
		// create table of years
		table = document.createElement("table");
		table.setAttribute("border", "0");
		table.setAttribute("cellSpacing", "0");
		table.setAttribute("cellPadding", "0");
		table.className = "pickYear";

		// thead
		thead = table.appendChild(document.createElement("thead"));
		// - title and nav
		row = thead.appendChild(document.createElement("tr"));
		row.className = "first";
		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("\u00ab"));
		cell.className = "first";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickYearNav.bind(this, -1);

		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("\u00a0"));

		cell = row.appendChild(document.createElement("td"));
		cell.appendChild(document.createTextNode("\u00bb"));
		cell.className = "last";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickYearNav.bind(this, 1);

		// tfoot
		tfoot = table.appendChild(document.createElement("tfoot"));
		row = tfoot.appendChild(document.createElement("tr"));
		row.className = "first";
		cell = row.appendChild(document.createElement("td"));
		cell.setAttribute("colSpan", "3");
		cell.appendChild(document.createTextNode("This year: YYYY"));
		cell.className = "first last";
		cell.style.cursor = "pointer";
		cell.onclick = this._clickYearItem.bind(this, (5 * 3));

		// tbody
		tbody = table.appendChild(document.createElement("tbody"));
		for (var i = 0; i < 5; i++) {	// 5 rows
			row = tbody.appendChild(document.createElement("tr"));
			if (i == 0) { row.className = "first"; }
			if (i == 4) { row.className = "last"; }
			for (var j = 0; j < 3; j++) {		// 3 columns
				cellVal = 1000 + (i * 3) + j + 1;
				cell = row.appendChild(document.createElement("td"));
				cell.appendChild(document.createTextNode(cellVal.toString()));
				if (j == 0) { cell.className = "first"; }
				if (j == 2) { cell.className = "last"; }
				cell.style.cursor = "pointer";
				cell.onclick = this._clickYearItem.bind(this, (i * 3) + j);
			}
		}
		return table;
	},
	_updatePickDay: function() {
		var root, table, thead, tfoot, tbody, cells, cellVal;
		var root = this.rootElement;
		if (!root) { return; }
		var t, d, v, f, c;
		t = new Date();
		d = this.value;
		v = this._viewDate;
		table = root.getElementsByTagName("table")[0];
		thead = table.getElementsByTagName("thead")[0];
		tfoot = table.getElementsByTagName("tfoot")[0];
		tbody = table.getElementsByTagName("tbody")[0];
		// thead
		cells = thead.getElementsByTagName("td");
		cellVal = v.getMonthName().substr(0, 3) + " " + v.getFullYear();
		cells[1].innerHTML = cellVal;
		// tfoot
		cells = tfoot.getElementsByTagName("td");
		cellVal = "Today: " + t.getMonthName().substr(0, 3) + " " + t.getDate() + ", " + t.getFullYear();
		cells[0].innerHTML = cellVal;
		// tbody
		cells = tbody.getElementsByTagName("td");
		f = new Date(this._firstDate);
		for (var i = 0; i < cells.length; i++) {
			c = new Date(f.getFullYear(), f.getMonth(), f.getDate() + i);
			cellVal = c.getDate();
			cells[i].innerHTML = cellVal;
			var cn = cells[i].className;
			cn = cn.replace(/(\boutside\b)|(\bweekend\b)|(\btoday\b)|(\bselected\b)|(\btodaySelected\b)/g, "");
			if (c.getMonth() !== v.getMonth()) { cn += " outside"; }
			if (c.getDay() == 0 || c.getDay() == 6) { cn += " weekend"; }
			if (c.getFullYear() == t.getFullYear() && c.getMonth() == t.getMonth() && c.getDate() == t.getDate()) { cn += " today"; }
			if (c.getFullYear() == d.getFullYear() && c.getMonth() == d.getMonth() && c.getDate() == d.getDate()) { cn += " selected"; }
			cn = cn.replace(/\btoday selected\b/, " todaySelected");
			cells[i].className = cn;
		}
	},
	_updatePickMonth: function() {
		var root, table, thead, tfoot, tbody, cells, cellVal;
		var root = this.rootElement;
		if (!root) { return; }
		var t, d, v, c;
		t = new Date();
		d = this.value;
		v = this._viewDate;
		table = root.getElementsByTagName("table")[1];
		thead = table.getElementsByTagName("thead")[0];
		tfoot = table.getElementsByTagName("tfoot")[0];
		tbody = table.getElementsByTagName("tbody")[0];
		// thead
		cells = thead.getElementsByTagName("td");
		cellVal = v.getFullYear();
		cells[1].innerHTML = cellVal;
		// tfoot
		cells = tfoot.getElementsByTagName("td");
		cellVal = "This month: " + t.getMonthName().substr(0, 3) + " " + t.getFullYear();
		cells[0].innerHTML = cellVal;
		// tbody - nothing
		cells = tbody.getElementsByTagName("td");
		for (var i = 0; i < cells.length; i++) {
			var cn = cells[i].className;
			cn = cn.replace(/(\boutside\b)|(\bweekend\b)|(\btoday\b)|(\bselected\b)|(\btodaySelected\b)/g, "");
			if (v.getFullYear() == t.getFullYear() && i == t.getMonth()) { cn += " today"; }
			if (d.getFullYear() == v.getFullYear() && i == d.getMonth()) { cn += " selected"; }
			cn = cn.replace(/\btoday selected\b/, " todaySelected");
			cells[i].className = cn;
		}
	},
	_updatePickYear: function() {
		var root, table, thead, tfoot, tbody, cells, cellVal;
		var root = this.rootElement;
		if (!root) { return; }
		var t, d, v, c;
		t = new Date();
		d = this.value;
		v = this._viewDate;
		table = root.getElementsByTagName("table")[2];
		thead = table.getElementsByTagName("thead")[0];
		tfoot = table.getElementsByTagName("tfoot")[0];
		tbody = table.getElementsByTagName("tbody")[0];
		// thead - nothing
		// tfoot
		cells = tfoot.getElementsByTagName("td");
		cellVal = "This year: " + t.getFullYear();
		cells[0].innerHTML = cellVal;
		// tbody
		cells = tbody.getElementsByTagName("td");
		var y = this._firstYear;
		for (var i = 0; i < cells.length; i++) {
			cellVal = y + i;
			cells[i].innerHTML = cellVal;
			var cn = cells[i].className;
			cn = cn.replace(/(\boutside\b)|(\bweekend\b)|(\btoday\b)|(\bselected\b)|(\btodaySelected\b)/g, "");
			if (cellVal == t.getFullYear()) { cn += " today"; }
			if (cellVal == d.getFullYear()) { cn += " selected"; }
			cn = cn.replace(/\btoday selected\b/, " todaySelected");
			cells[i].className = cn;
		}
	}
};

