var calendar_select = function () {
	var _pub = {
		year: null,
		month: null,
		day: null,
		input: null,
		reset: null,

		update_date: function() {
			_pub.input.innerHTML = sprintf("%02d.%02d.%04d", parseInt(_pub.day.options[_pub.day.selectedIndex].value), parseInt(_pub.month.options[_pub.month.selectedIndex].value), parseInt(_pub.year.options[_pub.year.selectedIndex].value));
		},

		do_reset: function() {
			if (_pub.reset){
				_pub.input.innerHTML = '';
				_pub.year.value = '';
				_pub.month.value = '';
				_pub.day.value = '';
			}
		},

		updateSelect: function (cal) {
			var date = cal.date;
			_pub.year.value = date.getFullYear();
			_pub.month.value = date.getMonth()+1;
			_pub.day.value =  date.getDate();
		}
	}

	return _pub;
}

var myCalendar = function (){

	var _pub = {
		startDate: null,
		endDate: null,
		cal1: null,
		cal2: null,
		cal1_select: null,
		cal2_select: null,

		allowed_dates: {
			beforeNow: true,
			sdateEqual: true
		},

		startFromInput: function (input_id, button_id) {
			var date = null;
			
			var input = document.getElementById(input_id);
			var patt=/^\d{2}\.\d{2}\.\d{4}$/;
			if (patt.test(input.value)){
				var a = input.value.split(/\./);
				date = new Date (a[2], a[1] - 1, a[0], 0, 0, 0);
			}
			_pub.startCommon(input_id, button_id, null, date);
		
		},

		startFromInput_wTime: function (input_id, button_id) {
			var date = null;
			
			var input = document.getElementById(input_id);
			var patt=/^(\d{2})\.(\d{2})\.(\d{4}) (\d{2})\:(\d{2})$/;
			if (patt.test(input.value)){
				var a = patt.exec(input.value);
				date = new Date (a[3], a[2] - 1, a[1], a[4], a[5], 0);
			}
			_pub.startCommon_wTime(input_id, button_id, null, date);
		
		},

		startFromSelect: function (input_id, button_id, year, month, day, reset_id) {
			var date = null;

			var year_value = year.options[year.selectedIndex].value;
			var month_value = month.options[month.selectedIndex].value;
			var day_value = day.options[day.selectedIndex].value;
			if (year_value > 0 && month_value > 0 && day_value > 0){
				date = new Date (year_value, month_value - 1, day_value, 0, 0, 0);
			}
			
			
			var cal = new calendar_select();
			cal.day = day;
			cal.month = month;
			cal.year = year;
			cal.input = document.getElementById(input_id);
			if (reset_id) {
				cal.reset = document.getElementById(reset_id);
				Zapatec.Utils.addEvent(cal.reset, 'click', cal.do_reset);
			}
			cal.update_date();
			
			Zapatec.Utils.addEvent(day, 'change', cal.update_date);
			Zapatec.Utils.addEvent(month, 'change', cal.update_date);
			Zapatec.Utils.addEvent(year, 'change', cal.update_date);

			if (_pub.cal1_select){
				_pub.cal2_select = cal;
			} else {
				_pub.cal1_select = cal;
			}


			_pub.startCommon(null, button_id, input_id, date);
		
		},

		startCommon: function (input_id, button_id, display_id, date){
			if (!_pub.cal1){
				_pub.startDate = date;
				_pub.cal1 = _pub.createÑal(input_id, button_id, display_id, _pub.dateInRange1, _pub.filterDates1, date);
			} else {
				_pub.endDate = date;
				_pub.cal2 = _pub.createÑal(input_id, button_id, display_id, _pub.dateInRange2, _pub.filterDates2, date);
			}
		},


		createÑal: function (input_id, button_id, display_id, __dateStatusFunc, __onUpdate, __date){
			var params = {
				firstDay          : 1,
				weekNumbers       : false,
				showOthers        : true,
				inputField        : input_id,
				displayArea		  : display_id,
				button            : button_id,
				ifFormat          : "%d.%m.%Y",
				daFormat          : "%d.%m.%Y",
				numberMonths          : 2,
				step : 1,
				align             : "bR",
				noHelp : true,
				electric       :  false,
				dateStatusFunc :  __dateStatusFunc, //the function to call
				onUpdate       :  __onUpdate,
				date : __date
			};
			var a = new Zapatec.Calendar.setup(params);
			return a;
		},


		startCommon_wTime: function (input_id, button_id, display_id, date){
			if (!_pub.cal1){
				_pub.startDate = date;
				_pub.cal1 = _pub.createÑal_wTime(input_id, button_id, display_id, _pub.dateInRange1, _pub.filterDates1, date);
			} else {
				_pub.endDate = date;
				_pub.cal2 = _pub.createÑal_wTime(input_id, button_id, display_id, _pub.dateInRange2, _pub.filterDates2, date);
			}
		},

		createÑal_wTime: function (input_id, button_id, display_id, __dateStatusFunc, __onUpdate, __date){
			var params = {
				singleClick: false,
				showsTime: true,
				firstDay          : 1,
				weekNumbers       : false,
				showOthers        : true,
				inputField        : input_id,
				displayArea		  : display_id,
				button            : button_id,
				ifFormat          : "%d.%m.%Y %H:%M",
				daFormat          : "%d.%m.%Y %H:%M",
				numberMonths          : 2,
				step : 1,
				align             : "bR",
				noHelp : true,
				electric       :  false,
				dateStatusFunc :  __dateStatusFunc, //the function to call
				onUpdate       :  __onUpdate,
				date : __date
			};
			var a = new Zapatec.Calendar.setup(params);
			return a;
		},




		/*
		* Given two dates (in seconds) find out if date1 is bigger, date2 is bigger or
		 * they're the same, taking only the dates, not the time into account.
		 * In other words, different times on the same date returns equal.
		 * returns -1 for date1 bigger, 1 for date2 is bigger 0 for equal
		 */

		compareDatesOnly: function (date1, date2) {
			var year1 = date1.getYear();
			var year2 = date2.getYear();
			var month1 = date1.getMonth();
			var month2 = date2.getMonth();
			var day1 = date1.getDate();
			var day2 = date2.getDate();

			if (year1 > year2) {
				return -1;
			}
			if (year2 > year1) {
				return 1;
			}

			//years are equal
			if (month1 > month2) {
				return -1;
			}
			if (month2 > month1) {
				return 1;
			}

			//years and months are equal
			if (day1 > day2) {
				return -1;
			}
			if (day2 > day1) {
				return 1;
			}

			//days are equal
			return 0;


			/* Can't do this because of timezone issues
			var days1 = Math.floor(date1.getTime()/Date.DAY);
			var days2 = Math.floor(date2.getTime()/Date.DAY);
			return (days1 - days2);
			*/
		},

		filterDates1: function (cal) {
			_pub.startDate = cal.date;
			/* If they haven't chosen an 
			end date before we'll set it to the same date as the start date This
			way if the user scrolls in the start date 5 months forward, they don't
			need to do it again for the end date.
			*/

			if (_pub.cal2 && _pub.endDate == null) { 
				_pub.cal2 = _pub.createÑal(date2_input_id, date2_button_id, _pub.dateInRange2,  _pub.filterDates2, cal.date);
			}
			if (_pub.cal1_select) _pub.cal1_select.updateSelect(cal);
		},

		filterDates2: function (cal) {
			_pub.endDate = cal.date;
			if (_pub.cal2_select) _pub.cal2_select.updateSelect(cal);
		},

		/*
		* Both functions disable and hilight dates.
		*/

		/* 
		* Can't choose days after the
		* end date if it is choosen, hilights start and end dates with one style and dates between them with another
		*/
		dateInRange1: function (date) {

			if (_pub.endDate != null) {

				// Disable dates after end date
				var compareEnd = _pub.compareDatesOnly(date, _pub.endDate);
				if  (compareEnd < 0) {
					//return (true);
				}

				// Åñëè íå áëîêèðîâàòü òàêæå íà÷àëüíóþ äàòó, òî áëîêèðóåì åå
				//if (_pub.allowed_dates.sdateEqual == false && compareEnd == 0) return true;


				// Hilight end date with "edges" style
				if  (compareEnd == 0) {
					{return "edges";}
				}


				// Hilight inner dates with "between" style
				if (_pub.startDate != null){
					var compareStart = _pub.compareDatesOnly(date, _pub.startDate);
					if  (compareStart < 0) {
						return "between";
					}
				} 
			}

			//disable days prior to today if allowed

			if (_pub.allowed_dates.beforeNow == false){
				var today = new Date();
				var compareToday = _pub.compareDatesOnly(date, today);
				if (compareToday > 0) {
					return(true);
				}
			}

			//all other days are enabled
			return false;
			//alert(ret + " " + today + ":" + date + ":" + compareToday + ":" + days1 + ":" + days2);
			return(ret);
		},

		/* 
		* Can't choose days before the
		* start date if it is choosen, hilights start and end dates with one style and dates between them with another
		*/

		dateInRange2: function (date) {
			if (_pub.startDate != null) {
				// Disable dates before start date
				var compareDays = _pub.compareDatesOnly(_pub.startDate, date);
				if  (compareDays < 0) {
					return (true);
				}

				if (_pub.allowed_dates.sdateEqual == false && compareDays == 0) return (true);


				// Hilight end date with "edges" style
				if  (compareDays == 0 && _pub.allowed_dates.sdateEqual == true) {
					{return "edges";}
				}

				// Hilight inner dates with "between" style
				if ((_pub.endDate != null) && (date > _pub.startDate) && (date < _pub.endDate)) {
					// Åñëè íå áëîêèðîâàòü òàêæå íà÷àëüíóþ äàòó, òî áëîêèðóåì åå
					return "between";
				}
			} 

			if (_pub.allowed_dates.beforeNow == false){
				var now = new Date();
				if (_pub.compareDatesOnly(now, date) < 0) {
					return (true);
				}
			}

			//all other days are enabled
			return false;
		}

	}

	return _pub;
}