/* 
	Oxxigeno JS Calendar Library
	- require commons.js
	- require dates_i18n_js.xhtml to store texts translation/definition
	Version: 1.0. Date: 2/Dec/2008
*/

// css classes names: can be redefined according to specific styles definition

var SELECTED_CLASS_NAME = 'seleccionado';
var FIRST_SELECTED_CLASS_NAME = 'primerseleccionado';
var AVAILABLE_CLASS_NAME = '';
var NOT_AVAILABLE_CLASS_NAME = 'disabled';
var CLOSE_LINK_CLASS_NAME = 'lnk_cerrar';
var PREVIOUS_LINK_CLASS_NAME = 'lnk_anterior';
var NEXT_LINK_CLASS_NAME = 'lnk_siguiente';
var CALENDAR_LEFT_CLASS_NAME = 'calendar';
var CALENDAR_RIGHT_CLASS_NAME = 'calendar ultimo';
var BUTTON_CLASS_NAME = 'btn';

// constants definition

var DAYS_OF_THE_WEEK = 7;

var CMD_PREV_MONTH = -1;
var CMD_NEXT_MONTH = 1;

var SIMPLE_MODE = '1';
var DOUBLE_MODE = '2';

var LEFT_POSITION = 0;
var RIGHT_POSITION = 1;

var TO_CALENDAR_SELECTOR = 'to';
var FROM_CALENDAR_SELECTOR = 'from';

var FIELD_SEPARATOR = '|';

var HIDDEN_SELECTOR_PREFIX = 'hidden' + FIELD_SEPARATOR;
var INFO_SELECTOR_PREFIX = 'info' + FIELD_SEPARATOR;
var NIGHTS_SELECTOR_PREFIX = 'nights';
var LAYER_SELECTOR_PREFIX = 'layer';
var IFRAME_SELECTOR_PREFIX = 'iframe';
var DATE_SELECTION_SELECTOR_PREFIX = 'dateSelectionMode';
var DATE_SHOW_SELECTOR_PREFIX = 'dateShowMode';
var BEGIN_DATE_SELECTOR_PREFIX = 'beginDate';
var END_DATE_SELECTOR_PREFIX = 'endDate';

var COMMON_CONFIGURATION_ID_PREFIX = 'common';

var SELECT_ARRIVAL_DATE_STATE = 0;
var SELECT_DEPARTURE_DATE_STATE = 1;
var READY_DATE_STATE = 2;

var IFRAME_ELEMENT_ID = 'calendar_in_here';

// global values

var openedCalendars = new Object();

// public functions

function smartShowCalendar(calendarId, selector, element) {
	element.blur();
	showCalendar(calendarId, selector);
}

function showCalendar(calendarId, selector) {
	var calendar = new Calendar(calendarId, selector);
	addCalendar(calendar);
	if (calendar.dateSelectionMode == SIMPLE_MODE) {
		calendar.deselectDate(selector);
	}
	calendar.close(); // in case of sparate from/to calendar elements is useful to close both elements
	calendar.drawCalendar();
}

function selectDate(calendarId, selector, date) {
	var calendar = getCalendar(calendarId);
	var jsDate = parseDate(date);
	
	if (calendar.dateSelectionMode == SIMPLE_MODE) { // Simple date selection
		if (selector == FROM_CALENDAR_SELECTOR) calendar.realFromDate = jsDate;
		if (selector == TO_CALENDAR_SELECTOR) calendar.realToDate = jsDate;
		if (selector == FROM_CALENDAR_SELECTOR && (calendar.realToDate == null || calendar.realToDate <= calendar.realFromDate)) { // if user is selecting arrival date, and departure date is unsetted, the pre-set it to "tomorrow"
			calendar.realToDate = copyDate(jsDate, 1);
		} else if (selector == TO_CALENDAR_SELECTOR && calendar.realFromDate == null) { // if user is selecting departure date, and arrival date is unsetted, the pre-set it to "yesterday"
			calendar.realFromDate = copyDate(jsDate, -1);
		}
	} else { // Double date selection
		if (calendar.state == SELECT_ARRIVAL_DATE_STATE) {
			calendar.state = SELECT_DEPARTURE_DATE_STATE;
			calendar.realFromDate = jsDate;
			if (calendar.realToDate != null && calendar.realToDate <= calendar.realFromDate) calendar.realToDate = copyDate(jsDate, 1);
		} else if (calendar.state == SELECT_DEPARTURE_DATE_STATE) {
			calendar.state = READY_DATE_STATE;
			calendar.realToDate = jsDate;
		}
	}
	calendar.updateInfo();
	calendar.highlightDays();
	if (calendar.dateSelectionMode == SIMPLE_MODE || calendar.state == READY_DATE_STATE) 
		closeCalendar(calendarId);
}

function deselectDate(calendarId, selector) {
	var calendar = getCalendar(calendarId);
	calendar.deselectDate(selector);
	calendar.updateInfo();
	calendar.highlightDays();
}

function closeCalendar(calendarId) {
	var calendar = getCalendar(calendarId);
	calendar.close();	
	removeCalendar(calendarId);
}

function reset(calendarId) {
	var calendar = getCalendar(calendarId);
	calendar.realToDate = null;
	calendar.realFromDate = null;
	calendar.updateInfo();
	calendar.close();	
	removeCalendar(calendarId);
}

function move(calendarId, command) {
	var calendar = getCalendar(calendarId);
	// This only works in case of month-type movement commands 
	calendar.move(command);
	calendar.drawCalendar();
}

// PRIVATE FUNCTIONS

// calendar data management functions

function addCalendar(calendar) {
	var calendarId = calendar.calendarId;
	openedCalendars[calendarId] = calendar;
}
function getCalendar(calendarId) {
	return openedCalendars[calendarId];
}
function removeCalendar(calendarId) {
	openedCalendars[calendarId] = null;
}

// assing selection capability to a cell

function makeClickable(element, calendarId, selector, formattedDate) {
	element.onclick = function() {selectDate(calendarId, selector, formattedDate);};
}

function makeNotClickable(element) {
	element.onclick = null;
}

// creates link HTML code

function correctJSFunctionCall(onclickCode, documentReference) {
	return (documentReference == null)?onclickCode:('parent.' + onclickCode);
}

function createLink(txt, onclickCode, cssClassName) {
	var classAttribute = (cssClassName == null)?'':'class="' + cssClassName + '"';
	var onclickAttribute = (onclickCode == null)?'':'onclick="' + onclickCode + '"';
	var closeLink = '<a ' + classAttribute + ' href="javascript:;" ' + onclickAttribute + '>' + txt + '</a>';
	return closeLink;
}

// creates a close element HTML code

function createCloseElement() {
	return '<div class="clear">&nbsp;</div>';
}

// Objects definition

// Calendar object keep calendar configuration and state, gathered from document form inputs
// this object initialization can be fed in case of new initialization/configuration mecanisms are required

function Calendar(id, selector) {
	// all calendar configuration elements, must follow specific naming, according to calendarId
		
	// 1. Calendar basic initialization
	this.calendarId = id; // calendar id [calendar elements id prefix]
	
	this.selector = selector;

	// 2. Calendar values initialization
	// From Date
	this.fromDate = initField(id,FROM_CALENDAR_SELECTOR);
	this.realFromDate = initDateField(id,HIDDEN_SELECTOR_PREFIX + FROM_CALENDAR_SELECTOR);;
	// To Date
	this.toDate = initField(id, TO_CALENDAR_SELECTOR);
	this.realToDate = initDateField(id,HIDDEN_SELECTOR_PREFIX + TO_CALENDAR_SELECTOR);
	// calendar state
	this.state = (this.realFromDate == null)?SELECT_ARRIVAL_DATE_STATE:(this.realToDate == null)?SELECT_DEPARTURE_DATE_STATE:(this.selector == FROM_CALENDAR_SELECTOR)?SELECT_ARRIVAL_DATE_STATE:SELECT_DEPARTURE_DATE_STATE;
	// Nš Nights
	this.nights = initField(id, NIGHTS_SELECTOR_PREFIX);

	// 3. Calendar layer initialization
	// element to show/hide when calendar open/close
	
	this.overLayers = new Object();
	initMultipleField(this.overLayers, id, LAYER_SELECTOR_PREFIX);		
	// element where the calendar is created within
	this.layers = new Object();
	initMultipleField(this.layers, id, LAYER_SELECTOR_PREFIX);		
	// iframe support calendar location
	this.documentReferences = new Object();
	initIframeMultipleField(this.documentReferences, id, IFRAME_SELECTOR_PREFIX);
	for (key in this.documentReferences) {
		var documentReference = this.documentReferences[key];
		if (documentReference != null) this.layers[key] = get(IFRAME_ELEMENT_ID, documentReference);
	}	
	
	// 4. Calendar configuration
	// calendar modes
	var dateSelectionMode = initField(id, DATE_SELECTION_SELECTOR_PREFIX);
	var dateShowMode = initField(id, DATE_SHOW_SELECTOR_PREFIX);
	this.dateSelectionMode = (dateSelectionMode == null || isEmpty(dateSelectionMode.value))?SIMPLE_MODE:dateSelectionMode.value;
	this.dateShowMode = (dateShowMode == null || isEmpty(dateShowMode.value))?DOUBLE_MODE:dateShowMode.value;

	// dates range

	// default 'calendarBeginning' value is today [read-only]
	this.calendarBeginning = initDateField(id, BEGIN_DATE_SELECTOR_PREFIX, getToday());
	// default 'calendarEnd' value is null (no-limit) [read-only]
	this.calendarEnd = initDateField(id, END_DATE_SELECTOR_PREFIX, null);
	
	// 5. Calendar data initialization
	var today = getToday();
	
	this.calendarCurrentDate = (this.calendarBeginning != null && this.calendarBeginning.getTime() > today.getTime())?copyDate(this.calendarBeginning):today;
	
	if (this.selector == TO_CALENDAR_SELECTOR && this.realToDate != null) this.calendarCurrentDate = copyDate(this.realToDate);
	if (this.selector == FROM_CALENDAR_SELECTOR && this.realFromDate != null) this.calendarCurrentDate = copyDate(this.realFromDate);
		
	this.calendarCurrentDate.setDate(1); // current date aplies just to months and years, so using first day of month cause no effect but increase security with date operations.

	this.months = new Array();

	// calendar visual date update functions

	this.deselectDate = function deselectDate(selector) {
		if (selector == FROM_CALENDAR_SELECTOR) {
			this.state = SELECT_ARRIVAL_DATE_STATE;
		} else if (selector == TO_CALENDAR_SELECTOR) {
			this.state = SELECT_DEPARTURE_DATE_STATE;
		}
	}

	this.updateInfo = function updateInfo() {
		this.updateSelectorInfo(FROM_CALENDAR_SELECTOR, this.realFromDate);
		this.updateSelectorInfo(TO_CALENDAR_SELECTOR, this.realToDate);
		if (this.nights == null) return;
		if(this.realFromDate != null && this.realToDate != null) { // number of nights
			var nnights = getNumberOfNights(this.realFromDate, this.realToDate);
			this.nights.innerHTML = '<input class="nights" value="' + (nnights + ' ' + ((nnights == 1)?NIGHT_TEXT:NIGHTS_TEXT)) +'" id="nights" type="text" readonly/>';
		} else this.nights.innerHTML = '';
	}

	this.updateSelectorInfo = function updateSelectorInfo(selector, jsDate) {
		var formElement = get(getCalendarElementId(this.calendarId, selector));
		if (formElement == null) return;
		var formHiddenElement = get(getCalendarElementId(this.calendarId, HIDDEN_SELECTOR_PREFIX + selector))
		var calendarInfoElement = this.smartGet(getCalendarElementId(this.calendarId, INFO_SELECTOR_PREFIX + selector))
		if (jsDate != null) {
			formElement.value = calendarGoodLookingFormat(jsDate);
			formHiddenElement.value = formatDate(jsDate);
			calendarInfoElement.innerHTML = calendarGoodLookingFormat(jsDate);
		} else {
			formElement.value = ALL_DATES;
			formHiddenElement.value = '';
			calendarInfoElement.innerHTML = NO_DATE;
		}
	}

	// calendar drawing management functions

	// draw/re-draw a calendar

	this.drawCalendar = function drawCalendar() {
		var layer = this.layers[this.selector];
		var documentReference = this.documentReferences[this.selector];
		// reset calendar layer
		layer.innerHTML = "";

		// 0. title
		layer.innerHTML+= '<p class="der">' + createLink(CLOSE_LINK_TEXT, correctJSFunctionCall("closeCalendar('" + this.calendarId + "')", documentReference), CLOSE_LINK_CLASS_NAME) + '</p>';
		layer.innerHTML+= createCloseElement();
	
		// 2. month/s
		this.months = new Array();
		
		// 2.1 first month
		var monthDate = copyDate(this.calendarCurrentDate);
		var movementLinks = new Array();
		movementLinks[LEFT_POSITION] = this.monthMovementIsPosible(monthDate, LEFT_POSITION);
		if (this.dateShowMode == SIMPLE_MODE) {
			var nextMonthDate = copyDate(this.calendarCurrentDate, null, 1);
			movementLinks[RIGHT_POSITION] = this.monthMovementIsPosible(nextMonthDate, RIGHT_POSITION);
		}
		
		layer.innerHTML+= this.drawMonth(monthDate, CALENDAR_LEFT_CLASS_NAME, movementLinks);
		
		// 2.2 second month if double show mode is selected
		if (this.dateShowMode == DOUBLE_MODE) {
			layer.innerHTML+= '<br class="hide"/>';
			monthDate = copyDate(this.calendarCurrentDate, null, 1);
			movementLinks = new Array();
			movementLinks[RIGHT_POSITION] = this.monthMovementIsPosible(monthDate, RIGHT_POSITION);
			layer.innerHTML+= this.drawMonth(monthDate, CALENDAR_RIGHT_CLASS_NAME, movementLinks);
		}

		layer.innerHTML+= createCloseElement();

		// 3. info
		var info = '<div class="left">';
		var id = '';
		if (this.fromDate !=null) {
			id = getCalendarElementId(this.calendarId, INFO_SELECTOR_PREFIX + FROM_CALENDAR_SELECTOR);
			info+= '<p class="textsmall"><strong>' + ARRIVAL_DATE_TXT + '</strong><span id="' + id + '">' + showCalendarDateIfExists(this.realFromDate) + '</span>';
			if (this.dateSelectionMode == DOUBLE_MODE)
				info+= createLink(DELETE_LINK_TEXT, correctJSFunctionCall("deselectDate('" + this.calendarId + "', '" + FROM_CALENDAR_SELECTOR + "')", documentReference));
			info+= '</p>';
		}
		
		if (this.toDate !=null) {
			id = getCalendarElementId(this.calendarId, INFO_SELECTOR_PREFIX + TO_CALENDAR_SELECTOR);
			info+= '<p class="textsmall"><strong>' + DEPARTURE_DATE_TXT + '</strong><span id="' + id + '">' + showCalendarDateIfExists(this.realToDate) + '</span>';
			if (this.dateSelectionMode == DOUBLE_MODE)
				info+= createLink(DELETE_LINK_TEXT, correctJSFunctionCall("deselectDate('" + this.calendarId + "', '" + TO_CALENDAR_SELECTOR + "')", documentReference));
			info+= '</p>';
		}
		info += '</div>'
		layer.innerHTML+= info;
		
		// 4. 'Delete' button
		if (selector != '') {
			var deleteButton = '<div class="right"><br />';
			deleteButton += '<input onclick="'+correctJSFunctionCall("reset('" + this.calendarId + "')", documentReference)+'" class="'+BUTTON_CLASS_NAME+'" value="'+DELETE_LINK_TEXT+'" type="button" />';
			deleteButton += '</div>';
			layer.innerHTML+= deleteButton;
			layer.innerHTML+= createCloseElement();
		}
		
	
		// 5. show calendar
		this.overLayers[this.selector].style.display = "block";
	
		// 6. highlight days
		this.highlightDays();
	}

	// draw a month specified by monthDate, according to calendar object configuration, including navigation links specified

	this.drawMonth = function drawMonth(monthDate, calendarClass, movementLinks) {
		var monthToDraw = monthDate.getMonth();
		var monthInnerHTML = "";
		var calendarMonthId = getCalendarElementId(this.calendarId, formatDate(monthDate));
	
		// 0. open
		monthInnerHTML+= '<table id="' + calendarMonthId + '" class="' + calendarClass + '" cellspacing="0" cellpadding="0" border="0">';
		// 1. header: month title
		monthInnerHTML+= '<caption>';
		if (movementLinks[LEFT_POSITION] != null) monthInnerHTML+= movementLinks[LEFT_POSITION];
		monthInnerHTML+= '<strong>' + monthsName[monthToDraw] + ' ' + monthDate.getFullYear() + '</strong>';
		if (movementLinks[RIGHT_POSITION] != null) monthInnerHTML+= movementLinks[RIGHT_POSITION];
		monthInnerHTML+= '</caption>';
		// 2. header: days of the week
		var row = '';
		for (var day = 0; day < daysOfTheWeek.length; day++) {
			row+= '<th class="title">' + daysOfTheWeek[day] + '</th>';
		}
		monthInnerHTML+= '<tr>' + row + '</tr>';
		// 3. content: days of the month
		monthInnerHTML+= this.drawMonthDays(monthDate);
		// 4. close
		monthInnerHTML+= '</table>';

		this.months.push(calendarMonthId);
		return monthInnerHTML;
	}

	// draw months days in a week-organized structure. Generated cells are unstyled.

	this.drawMonthDays = function drawMonthDays(date) {
		var monthDays = '';
		// set first day of the month (begining of month number dates)
		date.setDate(1);
		var monthToDraw = date.getMonth();
		// fill first gap
		var monthDays = '<tr>';
		var dayOfTheWeekIndex = 1;
		for(; dayOfTheWeekIndex < getComfortableDayOfTheWeekIndex(date.getDay()); dayOfTheWeekIndex++) { // no month days
			monthDays+= '<td>&nbsp;</td>';
		}
		if (dayOfTheWeekIndex > DAYS_OF_THE_WEEK) monthDays+= '</tr>';
		while(monthToDraw == date.getMonth()) {
			if (dayOfTheWeekIndex > DAYS_OF_THE_WEEK) {monthDays+= '<tr>'; dayOfTheWeekIndex = 1;}
			monthDays+= '<td>' + createLink(date.getDate())  + '</td>';
			date.setDate((date.getDate() + 1));
			dayOfTheWeekIndex++;
			if (dayOfTheWeekIndex > DAYS_OF_THE_WEEK) monthDays+= '</tr>';
		}
	
		return monthDays;
	}

	// assing css class and capabilities to every day-cell of drawed calendar month/s

	this.highlightDays = function highlightDays() {
		var today = getToday();
		var cssClass = '';
		for (var i = 0; i < this.months.length; i++) { // process each month
			var monthCells = this.getCellsFromCalendarMonth(this.months[i]);
			for (var ii = 0; ii < monthCells.length; ii++) {
				var onClickFunction = null;
				var cellDate = monthCells[ii].date;
				var cellElement = monthCells[ii].element;
				this.setCellClickability(cellDate, cellElement);
			}
		}
	}

	// assing css class and capabilities to day-cell, according to calendar configuration

	this.setCellClickability = function setCellClickability(cellDate, cellElement) {
		var toDateSelection = (this.selector == TO_CALENDAR_SELECTOR || this.state >= SELECT_DEPARTURE_DATE_STATE);
		var lastSelectableDate = copyDate(this.calendarEnd);
		if (lastSelectableDate != null && toDateSelection)
			lastSelectableDate.setDate(lastSelectableDate.getDate() + 1)
		
		var cssClass = NOT_AVAILABLE_CLASS_NAME;
		var formattedDate = formatDate(cellDate);
		makeNotClickable(cellElement);
		if (this.calendarBeginning != null && cellDate < this.calendarBeginning) { // date out of calendar range
			cssClass = NOT_AVAILABLE_CLASS_NAME;
		} else if (this.calendarBeginning != null && (cellDate.getTime() == this.calendarBeginning.getTime()) && toDateSelection) { // first selected day for date to.
			cssClass = NOT_AVAILABLE_CLASS_NAME;	
	 	} else if (this.realFromDate != null && cellDate.getTime() == this.realFromDate.getTime()) { // selected date from
			cssClass = FIRST_SELECTED_CLASS_NAME;
		} else if (this.realToDate != null && cellDate.getTime() == this.realToDate.getTime()) { // selected date to
			cssClass = SELECTED_CLASS_NAME;
			makeClickable(cellElement, this.calendarId, this.selector, formattedDate);
		} else if ((this.realFromDate != null && cellDate.getTime() > this.realFromDate.getTime()) &&
			 (this.realToDate != null && cellDate.getTime() < this.realToDate.getTime()) ) { // date between selected dates
			cssClass = SELECTED_CLASS_NAME;
			makeClickable(cellElement, this.calendarId, this.selector, formattedDate);
		} else if ((toDateSelection) && (this.realFromDate != null && cellDate.getTime() < this.realFromDate.getTime()) ) { // dates previous to selected arrival date
			cssClass = NOT_AVAILABLE_CLASS_NAME;
		} else if (lastSelectableDate == null || cellDate.getTime() < lastSelectableDate.getTime()) { // clickable cell 
			cssClass = AVAILABLE_CLASS_NAME;
			makeClickable(cellElement, this.calendarId, this.selector, formattedDate);
		} else { // days beyond end date limit
			cssClass = NOT_AVAILABLE_CLASS_NAME;
		}
		cellElement.className = cssClass;
	}

	// gathers every calendar cell from a specified calendar month element id

	this.getCellsFromCalendarMonth = function getCellsFromCalendarMonth(id) {
		var calendarMonth = this.smartGet(id);
		var monthDate = parseDate(getSelectorFromId(id));
		var dayCells = new Array();
		var day;
		var cells = calendarMonth.getElementsByTagName('A');
		for (var ii = 0; ii < cells.length; ii++) {
			day = parseInt(cells[ii].innerHTML);
			if (isNaN(day)) continue;
			monthDate.setDate(day);
			dayCells.push(new DayCell(cells[ii], copyDate(monthDate)));
		}
		return dayCells;
	}

	this.monthMovementIsPosible = function monthMovementIsPosible(monthDate, direction) {
		var documentReference = this.documentReferences[this.selector];
		var link = null;
		var isPosible = false;
		var date = copyDate(monthDate);
		date.setDate(1); // for security reasons, month operation begins with first day of the month assignment. 
		if (direction == LEFT_POSITION) {		
			if (this.calendarBeginning == null) isPosible = true;
			else {
				date.setMonth(date.getMonth() - 1); // set previous month
				date.setDate(this.calendarBeginning.getDate()); // same begining day
				isPosible =  (date.getTime() >= this.calendarBeginning.getTime());
			}
			if (isPosible) 
				link = createLink(PREVIOUS_MONTH_TEXT, correctJSFunctionCall("move('" + this.calendarId + "', " + CMD_PREV_MONTH + ")", documentReference), PREVIOUS_LINK_CLASS_NAME);
		} else {
			if (this.calendarEnd == null) isPosible = true;
			else {
				date.setMonth(date.getMonth() + 1); // set next month
				date.setDate(this.calendarEnd.getDate()); // same end day
				isPosible =  (date.getTime() <= this.calendarEnd.getTime());
			}			
			if (isPosible) 
				link = createLink(NEXT_MONTH_TEXT, correctJSFunctionCall("move('" + this.calendarId + "', " + CMD_NEXT_MONTH + ")", documentReference), NEXT_LINK_CLASS_NAME);
		}
		return link;
	}
	
	this.move = function move(command) {
		// this is secure operation because calendarCurrentDate always refers to month/year, day is always first day in month.
		this.calendarCurrentDate.setMonth(this.calendarCurrentDate.getMonth() + command);
	}
	
	this.close = function close() {
		for (key in this.layers) {
			if (this.layers[key] != null) {
				this.layers[key].innerHTML = "";
				this.overLayers[key].style.display = "none";
			}
		}
	}

	this.smartGet = function smartGet(id) {
		return get(id, this.documentReferences[this.selector]);
	}

}

// Utility object to store both date and DOM element reference

function DayCell(element, date) {
	this.element = element;
	this.date = date;	
}

// Utility Functions

function initMultipleField(vector, id, fieldId) {
	vector[FROM_CALENDAR_SELECTOR] = null; 
	vector[TO_CALENDAR_SELECTOR] = null;
	for (key in vector) {
		var value = initField(id, fieldId + FIELD_SEPARATOR + key);
		if (value != null) vector[key] = value;
		else vector[key] = initField(id, fieldId);
	}
}

function initIframeMultipleField(vector, id, fieldId) {
	vector[FROM_CALENDAR_SELECTOR] = null; 
	vector[TO_CALENDAR_SELECTOR] = null;
	for (key in vector) {
	 	var documentReference = frames[id + FIELD_SEPARATOR + IFRAME_SELECTOR_PREFIX + FIELD_SEPARATOR + key];
	 	if (documentReference == null) documentReference = frames[id + FIELD_SEPARATOR + IFRAME_SELECTOR_PREFIX];
	 	vector[key] = documentReference;
	}
}	

function initField(id, fieldId) {
	var htmlField = get(id + "|" + fieldId);
	if (htmlField == null) htmlField = get(COMMON_CONFIGURATION_ID_PREFIX + FIELD_SEPARATOR + fieldId);
	return htmlField;
}

function initDateField(id, fieldId, defaultValue) {
	var htmlField = get(id + "|" + fieldId);
	if (htmlField == null) htmlField = get(COMMON_CONFIGURATION_ID_PREFIX + FIELD_SEPARATOR + fieldId);
	var date = (htmlField == null)?defaultValue:(isEmpty(htmlField.value))?null:parseDate(htmlField.value);
	return date;
}

function getCalendarElementId(calendar, selector) {
	return calendar + FIELD_SEPARATOR + selector;
}

function getSelectorFromId(id) {
	var data = id.split(FIELD_SEPARATOR);
	return data[1];
}

function calendarGoodLookingFormat(date) {
	if (date == null) return "Cualquiera:)";
	return date.getDate() + DATE_SEPARATOR + months[date.getMonth()] + DATE_SEPARATOR + date.getFullYear();
}

function showCalendarDateIfExists(date) {
	return ((date == null)?NO_DATE:calendarGoodLookingFormat(date));
}

