// Title: Tigra Calendar
// URL: http://www.softcomplex.com/products/tigra_calendar/
// Version: 3.4 (European date format)
// Date: 07/12/2007
// Note: Permission given to use this script in ANY kind of applications if
//    header lines are left unchanged.
// Note: Script consists of two files: calendar?.js and calendar.html

// if two digit year input dates after this year considered 20 century.
var NUM_CENTYEAR = 30;

var calendars = new Hash();
var RE_NUM = /^\-?\d+$/;
var dateTimeFormat = new Template('#{date}/#{month}/#{year}');

function calendar(obj_target, iframe, maxDaysForBooking) {

	// assigning methods
	this.gen_date = gen_date;
	this.gen_tsmp = gen_tsmp;
	this.prs_date = prs_date;
	this.prs_tsmp = prs_tsmp;
	this.popup    = popup;
	this.hideIt = hideIt;
	this.dependOn = dependOn;
	this.currentDate = currentDate;
	this.showCalendar = showCalendar;
	
	this.iframe = iframe;
	this.setDate = setDate;
	this.shouldShow = shouldShow;
	this.minDate = resetTime(new Date());
	this.maxDate = setMaxDate(new Date(), maxDaysForBooking);
	this.handleClose = handleClose;
	
	this.target = obj_target;
	
	// register in global collections
	this.id = obj_target.id;
	calendars.set(this.id,this);
}

function setMaxDate(date, maxDaysForBooking){
	date.setDate(date.getDate() + maxDaysForBooking);    
    return date;
}

function dependOn(dependentOn, isOutward, maxDaysForBooking){
	this.dependentOn = dependentOn;
	var date = resetTime(dependentOn?dependentOn.currentDate():new Date());
	var today = resetTime(new Date());
	if(date<today) date = today;
	if(dependentOn && $(dependentOn.id).up('fieldset').visible() && !$(dependentOn.id).disabled && AreNotEqual(date,today)){
			if(isOutward) 
				this.maxDate = date;
			else 
				this.minDate = date;
	} else if(AreNotEqual(this.minDate,today)) 
		this.minDate = date;
	  else 
		this.maxDate = setMaxDate(new Date(),maxDaysForBooking);
}

function AreNotEqual(date, today){
    if(date.getDate() != today.getDate()) return true;
    if(date.getMonth() != today.getMonth()) return true;
    return date.getYear() != today.getYear();
}

function currentDate(){
	var parsedTime = this.prs_tsmp(this.target.value);
	var date = parsedTime?parsedTime:new Date();
	return date;
}

function popup (str_datetime) {
	var currDate;
	if(!str_datetime) str_datetime = this.target.value;

	if(str_datetime) currDate = resetTime(this.prs_tsmp(str_datetime));
	
	this.dt_current = currDate?currDate:resetTime(new Date());

	if (!this.poppedUp) { 
		this.dt_selected = currDate;
		if (this.minDate) {
			if (this.dt_selected){
				if(this.dt_selected<this.minDate){
					if(this.dt_current>this.minDate) this.dt_current = this.minDate;
				} else {
					this.dt_current = this.dt_selected;
				}
			}
			if(this.minDate>=this.dt_current){
				this.dt_selected = this.minDate;
				this.dt_current = this.dt_selected;
			}
		}
	}
	
	this.showCalendar();
}

function showCalendar(){
	if (!this.dt_current) return;
	this.iframe.src= 'calendar.html?id=' + this.id + (this.dt_selected?'&s=' + this.dt_selected.valueOf():'') + '&c=' + this.dt_current.valueOf()+'&r='+Math.random();
	$(this.target).addClassName('focussed');
	$(this.iframe).addClassName('visible');
	this.poppedUp = true;
}

// timestamp generating function
function gen_tsmp (dt_datetime) {
	return(this.gen_date(dt_datetime) + ' ' + this.gen_time(dt_datetime));
}

// date generating function
function gen_date (dt_datetime) {
	return (
		(dt_datetime.getDate() < 10 ? '0' : '') + dt_datetime.getDate() + "-"
		+ (dt_datetime.getMonth() < 9 ? '0' : '') + (dt_datetime.getMonth() + 1) + "-"
		+ dt_datetime.getFullYear()
	);
}

// timestamp parsing function
function prs_tsmp (str_datetime) {
	// if no parameter specified return current timestamp
	if (!str_datetime)
		return (new Date());
		
	// if positive integer treat as milliseconds from epoch
	if (RE_NUM.exec(str_datetime))
		return new Date(str_datetime);
	return this.prs_date(str_datetime);
}

// date parsing function
function prs_date (str_date) {

	var arr_date = str_date.split('/');

	if (arr_date.length != 3) return null;
	if (!arr_date[0]) return null;
	if (!RE_NUM.exec(arr_date[0])) return null;
	if (!arr_date[1]) return null;
	if (!RE_NUM.exec(arr_date[1])) null;
	if (!arr_date[2]) return null;
	if (!RE_NUM.exec(arr_date[2])) return null;

	var dt_date = new Date();
	dt_date.setDate(1);

	if (arr_date[1] < 1 || arr_date[1] > 12) return null;
	dt_date.setMonth(arr_date[1]-1);
	 
	if (arr_date[2] < 100) arr_date[2] = Number(arr_date[2]) + (arr_date[2] < NUM_CENTYEAR ? 2000 : 1900);
	dt_date.setFullYear(arr_date[2]);

	var dt_numdays = new Date(arr_date[2], arr_date[1], 0);
	dt_date.setDate(arr_date[0]);
	if (dt_date.getMonth() != (arr_date[1]-1)) return null;

	return (dt_date);
}

function formatDate(date){
	var yearPart = padDatePart(date.getFullYear()%100);
	var datePart = padDatePart(date.getDate());
	var monthPart = padDatePart(date.getMonth()+1);
	return dateTimeFormat.evaluate({date:datePart,month:monthPart,year:yearPart});
}

function padDatePart(part){
	return part < 10?'0'+part:part;;
}

function shouldShow(date) {
	date = resetTime(date);
	return date >= this.minDate && date <= this.maxDate;
}

function resetTime(date){
	if(!date) return null;
	date.setHours(0);
	date.setMinutes(0);
	date.setSeconds(0);
	date.setMilliseconds(0);
	return date;
}

function hideIt(){
	this.poppedUp = false;
	$(this.iframe).hide();
	$(this.iframe).removeClassName('visible');
	$(this.target).removeClassName('focussed');
}

function hideCalendars(calendarToPop){
 calendars.values().each(function(calendar){
		calendar.hideIt();
	});
}

function setDate(date){
	this.dt_current = this.dt_selected = resetTime(date);
	this.target.setValue(formatDate(date));
	$(this.target).focus();
	this.hideIt();
}

function handleClose(){
	hideCalendars();
}

var calendar;
var clickOnBody;
function calendarPopup(calendarToPopId, dependentOnId, isOutward, maxDaysForBooking){
	var calendarToPop = calendars.get(calendarToPopId.id);
	var iframeObj = calendarToPop.iframe.frameElement?$(calendarToPop.iframe.frameElement.id):$(calendarToPop.iframe.name);
	var isPoppedUp = calendarToPop.poppedUp;
	hideCalendars(calendarToPop);
	if (isPoppedUp) {return;}	
	showCalendarFrame(calendarToPop, iframeObj);
	var dependentOn = dependentOnId?calendars.get(dependentOnId.id):null;
	calendarToPop.dependOn(dependentOn, isOutward, maxDaysForBooking);
	calendar = calendarToPop;
	calendar.popup();
}

function showCalendarFrame(calendarToPop, iframeObj) {
	var offsets = calendarToPop.target.cumulativeOffset();
	var left = offsets.left + calendarToPop.target.getWidth()+10;
	var top = offsets.top;
	iframeObj.setStyle({left:left+'px',top:top+'px'});
	iframeObj.show();
}

function addHintToTextField(textField) {
	onBlur(null,textField);
	Event.observe(textField, 'blur', onBlur);
	Event.observe(textField, 'change', function (){
		if (!textField.value || textField.value+'' == '') {
			textField.addClassName('textFieldBlur');
			textField.value = textField.title;
		} else if (textField.value == textField.title) {
			textField.removeClassName('textFieldBlur');
			textField.value = '';
		} else {
			textField.removeClassName('textFieldBlur');
		}
	});
	Event.observe(textField, 'focus', function(e){
		textField.removeClassName('textFieldBlur');
		if (textField.value == textField.title) {
			textField.value = '';
		}
	});
}

function onBlur(event,textField){
	textField = event?event.target:textField;
	if (!textField.value || textField.value+'' == '') {
		textField.addClassName('textFieldBlur');
		textField.value = textField.title;
	}
}

function getIframe(iframeId){
	if ($(iframeId)) return window.frames[iframeId];
	return createIframe(iframeId);
}

function createIframe (iframeName) {
	var div = new Element('div');
	div.addClassName('calendarDiv');
	document.body.appendChild(div);
	
	var onloadEvent = document.frames?'onload="adjustDimensions(\''+iframeName+'\')"':'';
	div.update('<iframe frameborder="0" style="border:0" scrolling="no" class="calIFrame" src="DummyIframe.html" id="'+iframeName+'" name="'+iframeName+'" '+onloadEvent+' style="z-index:1024"></iframe>');
	return div.firstChild;
}

function adjustDimensions(id) {
	var children = $A(this.frames(id).document.body.childNodes);
	if (!children.any()) return;
	width = children[0].clientWidth + 5;	
	height = children[0].clientHeight + 5;
	$(id).setStyle({
		height: height+'px',
		width: width+'px'
	});
	
	
}


function getCalendar(obj_target, iframeObj, maxDaysForBooking) {
	var cal = calendars.get(obj_target.id);
	return cal?cal:new calendar(obj_target, iframeObj, maxDaysForBooking);
}

function RegisterCalendarToTextField(obj_target, iframeId, dependentOn, isOutward, maxDaysForBooking){
	maxDaysForBooking = maxDaysForBooking? maxDaysForBooking: 999;
	RegisterCalendar(obj_target, obj_target, iframeId, dependentOn, isOutward, maxDaysForBooking);
	obj_target.title='dd/mm/yy';
	addTextFieldListeners(obj_target);
	addHintToTextField(obj_target);
}

function addTextFieldListeners(textField) {
	Event.observe(textField, 'keydown', function(e){
	    if(e.keyCode==9) hideCalendars();
	});
	if(!clickOnBody){
		Event.observe(document,'mouseup',function(){hideCalendars();});
		clickOnBody = true;
	}
}

function RegisterCalendar(click_target, obj_target, iframeId, dependentOn, isOutward, maxDaysForBooking){
	var iframeObj = getIframe(iframeId+obj_target.id);
	var cal = getCalendar(obj_target, iframeObj, maxDaysForBooking);
	Event.observe(click_target,'mouseup', function(e){ 
		if(click_target.disabled) return;
		e.stop();
		calendarPopup(obj_target, dependentOn,isOutward, maxDaysForBooking);
	});
	/*Event.observe(dependOn,'onBlur',function(e) {
		alert($(dependOn.id).value);
	});*/
	obj_target.setAttribute('autocomplete','off');
}


