Object.extend(
	Array.prototype,
	{
		push: function(element) {
			this[this.length] = element;
		}
	}
);

Object.extend(
	Date.prototype,
	{
		toAnsi: function() {
			var month = this.getMonth() + 1;
			var date = this.getDate();
			return this.getFullYear() + '-' + (month < 10 ? '0' : '') + month + '-' + (date < 10 ? '0' : '') + date;
		}
	}
);

function DateToAnsi(_date) {
	var month = _date.getMonth() + 1;
	var date = _date.getDate();
	return _date.getFullYear() + '-' + (month < 10 ? '0' : '') + month + '-' + (date < 10 ? '0' : '') + date;
};

function $DOM(A){
	var aL = A.length, node, child, ref={}, bRef=false;
	if(aL>=1){
		node = cE(A[0]);
		if(aL>=2){
			for(var arg in A[1]){
				if(arg.indexOf('on')==0){
					node[arg] = A[1][arg];
				}else if(arg=='ref'){
					ref[A[1][arg]] = node;
					ref['DOM']     = node;
					bRef           = true;
				}else{
					if(arg=='style'){
						node.style.cssText   = A[1][arg];
					} else if(arg.toLowerCase()=='classname'){
						node.style.className = A[1][arg];
					} else {
						node.setAttribute(arg, A[1][arg]);
					}
				}
			}
		}
		for(var i=2; i<aL; i++){
			if(typeof(A[i])=='string'){
				node.appendChild(document.createTextNode(A[i]));
			} else {
				child = $DOM(A[i]);
				if(child.DOM){
					bRef = true;
					for(n in child){
						if (n == 'DOM') {
							node.appendChild(child[n]);
						} else {
							ref[n] = child[n];
						}
					}
					ref['DOM'] = node;
				} else {
					node.appendChild(child);
				}
			}
		}
		return bRef ? ref : node;
	}
	return null;
}

function cE() {
	var A = arguments;

	if(!cE.cache[A[0]]) cE.cache[A[0]]=document.createElement(A[0]);
	return cE.cache[A[0]].cloneNode(false);
}

cE.cache = {};

var PanelHandler = Class.create();
PanelHandler.prototype = {
	panel: function() { return this._panel; },
	input: function() { return this._input; },
	initialize: function(_input_id) {
		this._input		= $(_input_id);
		this._panel_id	= _input_id.replace('[', '_').replace(']', '_') + '_panel';
		this._panel		= $(this._panel_id);
		Event.observe(this._input, 'dblclick', this.Show.bind(this), false);
		this._input.setAttribute('autocomplete', 'off');
		this.createPanel();
	},
	createPanel: function() {
		if (!this._panel) {
			this._panel = $DOM(['DIV', {id: this._panel_id, 'class': 'datepicker'}]);
			document.body.appendChild(this._panel);
		}
		this._panel.hide();
		this._panel.style.position = 'absolute';
		this.writePanel();
	},
	writePanel: function() { },
	Show: function (e) {
		var pos					= Position.positionedOffset(this._input);
		this._panel.style.left	= pos[0] + 'px';
		this._panel.style.top	= pos[1] + parseInt(this._input.offsetHeight) + 'px';
		this.writePanel();
		this._panel.show();
		this._input.blur();
//		this._panel.clicked		= true;
	},
//	TryHide: function(e) {
//		if (this._panel.clicked) {
//			return;
//		}
//		this.Hide(e);
//	},
	Hide: function(e) {
		this._panel.hide();
	},
	KeyPress: function(e) {
		window.alert('KeyPress');
		if (this._panel.clicked) {
			switch(e.keyCode) {
				case Event.KEY_TAB:
				case Event.KEY_RETURN:
					break;
				case Event.KEY_ESC:
					this.Hide(e);
					break;
			}
		}
	}
};

function DatePicker(_input_id) {
	var panel_handler = new PanelHandler(_input_id);
	var START_OF_WEEK = 1;
	var months = 'January,February,March,April,May,June,July,August,September,October,November,December'.split(',');
	var days = 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'.split(',');
	panel_handler.writePanel = writePanel;

	function changeCalendar(offset) {
		var d1 = getDateFromInput();
		var d2;
		if (offset % 12 == 0) {
			d2 = new Date(d1.getFullYear() + offset / 12, d1.getMonth(), d1.getDate());
		} else if (d1.getMonth() == 0 && offset == -1) {
			d2 = new Date(d1.getFullYear() - 1, 11, d1.getDate());
		} else {
			d2 = new Date(d1.getFullYear(), d1.getMonth() + offset, d1.getDate());
		}

		if (d1.getDate() != d2.getDate()) {
			d2 = new Date(d2.getFullYear(), d2.getMonth(), 0);
		}

		setDate(d2);
		panel_handler.writePanel();
	}

	function setDate(date) {
		panel_handler._input.value = panel_handler._input.value.replace(DateToAnsi(getDateFromInput()), DateToAnsi(date));
//		panel_handler._input.value = panel_handler._input.value.replace(getDateFromInput().toAnsi(), date.toAnsi());
	}

	function selectDate(e) {
		panel_handler.Hide(e);
		var date = getDateFromInput();
		setDate(new Date(date.getFullYear(), date.getMonth(), Number(Event.element(e).title)));
//		writePanel();
	}

	function selectStartOfWeek(e) {
		START_OF_WEEK = Number(Event.element(e).title) + START_OF_WEEK % 7;
		panel_handler.writePanel();
	}

	function dayToWeekday(day) {
		return (day + 7 - START_OF_WEEK) % 7;
	}

	function writePanel() {
		var date				= getDateFromInput();
	    var firstWeekday		= new Date(date.getFullYear(), date.getMonth(), 1).getDay();
	    var lastDateOfMonth		= new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
	    var day					= 1; // current day of month

	    var o = ['TABLE', {},
	    	['THEAD', {},
	    		['TR', {},
	    			['TH', {colspan: 2, onclick: function() { changeCalendar(-12); }}, '<<'],
	    			['TH', {colspan: 3}, date.getFullYear() + ''],
	    			['TH', {colspan: 2, onclick: function() { changeCalendar(12); }}, '>>']
	    		],
	    		['TR', {},
	    			['TH', {onclick: function() { changeCalendar(-1); }}, '<'],
	    			['TH', {colspan: 5}, months[date.getMonth()]],
	    			['TH', {onclick: function() { changeCalendar(1); }}, '>']
	    		],
	    		['TR', {}]	// Day labels
	    	]
	    ];
		for (var i = 0; i < days.length; i++) {
			o.last().last().push(['TH', {title: i, onclick: selectStartOfWeek}, days[(i + START_OF_WEEK) % 7]]);
		}
		o.push(['TBODY', {}]);
		var date_now = new Date();
		for (rows = 1; rows < 7 && (day <= lastDateOfMonth); rows++) {
			o.last().push(['TR', {}]);
			for (var day_num = 0; day_num < days.length; day_num++) {
				var translated_day = (day_num + START_OF_WEEK) % 7;
				if ((translated_day >= firstWeekday || day > 1) && (day <= lastDateOfMonth)) {
					var current_date	= new Date(date.getFullYear(), date.getMonth(), day);
					var args			= {onclick: selectDate, title: day};
					if (date.getDate() == day) {
						args['class'] = 'current-date';
					} else if (current_date.getFullYear() == date_now.getFullYear()) {
						if (current_date.getMonth() == date_now.getMonth()) {
							if (current_date.getDate() == date_now.getDate()) {
								args['class'] = 'today';
							} else if (current_date.getDate() - dayToWeekday(current_date.getDay()) == date_now.getDate() - dayToWeekday(date_now.getDay())) {
								args['class'] = 'this-week';
							} else {
								args['class'] = 'this-month';
							}
						} else {
							args['class'] = 'this-year';
						}
					}
					o.last().last().push(['TD', args, day + '']);
					day++;
				} else {
					o.last().last().push(['TD', {}, String.fromCharCode(160)]);
				}
			}
		}
		o.push(['TFOOT', {}, ['TR', {}, ['TD', {colspan: 7, onclick: panel_handler.Hide.bind(panel_handler), 'class': 'close'}, 'Close']]]);

		while (panel_handler._panel.hasChildNodes()) {
			panel_handler._panel.removeChild(panel_handler._panel.lastChild);
		}
		panel_handler._panel.appendChild($DOM(o));
	}

	function getDateFromInput() {
		var date = panel_handler._input.value;
		if (date == '') { return new Date(); }
		date = date.split(' ');
		if (date.length == 0) { return new Date(); }
		date = date[0].split('-');
		if (date.length < 3) { return new Date(); }
		return new Date(date[0], Number(date[1]) - 1, date[2]);
	}
}

function Autocomplete(_input_id) {
	var panel_handler = new PanelHandler(_input_id);
	var lis = panel_handler._panel.getElementsBySelector('li');
	for (var i  = 0; i < lis.length; i++) {
		Event.observe(lis[i], 'click', select, false);
	}

	function select(e) {
		panel_handler._input.value = Event.element(e).title;
		panel_handler.Hide(e);
	}
}

function NormalSubmit(_form) {
	_form.target = '';
}

function PrintSubmit(_form) {
	_form.target = 'print_window';
}

//function ToggleAssign(_from, _to)
//{
//	var input_from	= document.getElementById(_from);
//	var input_to	= document.getElementById(_to);
//
//	for(var i = 0; i < input_from.length; i++)
//	{
//		if(input_from.options[i].selected == true)
//		{
//			input_to.options[input_to.length] = new Option(
//				input_from.options[i].text,
//				input_from.options[i].value
//			);
//			input_from.options[i] = null;
//			i--;
//		}
//	}
//
//	OptionsSort(input_from.options);
//	OptionsSort(input_to.options);
//}
//
//function OptionsSort(_options) {
//	var text;
//	var value;
//	for(var i = 0; i < _options.length - 1; i++)
//	{
//		for(var j = i + 1; j < _options.length; j++)
//		{
//			if(_options[i].text > _options[j].text)
//			{
//				text				= _options[i].text;
//				value				= _options[i].value;
//				_options[i].text	= _options[j].text;
//				_options[i].value	= _options[j].value;
//				_options[j].text	= text;
//				_options[j].value	= value;
//			}
//		}
//	}
//}
//
//function SelectAll(_element) {
//	var input = document.getElementById(_element);
//
//	for (var i = 0; i < input.length; i++) {
//		input.options[i].selected = true;
//	}
//}
//
//function AddEvent(_element, _event, _function) {
//	var input = document.getElementById(_element);
//
//	if (input.addEventListener) {
//		input.addEventListener(_event, _function, false);
//	} else if(input.attachEvent) {
//		input.attachEvent("on" + _event, _function);
//	}
//}
//
//function MarkUp(_element, _bg_color) {
//	document.getElementById(_element).style.backgroundColor = _bg_color;
//}

//(
//	function AutocompleterNamespace() {
//		var Autocompleter = null;
//
//		function AutocompleterCreate() {
//			if (Autocompleter) return;
//		}
//
//		function AutocompleterAttach(input) {
//			AutocompleterCreate();
//		}
//
//		window.AutocompleterAttach = AutocompleterAttach;
//	}
//)();
