
/* CALENDAR FUNCTIONS */
/* Requires Commons.js */

OxxCalendar.prototype.setCalendarTexts = setCalendarTexts;
OxxCalendar.prototype.initDates = initDates;
OxxCalendar.prototype.load = load;
OxxCalendar.prototype.loadCalendarCaption = loadCalendarCaption;
OxxCalendar.prototype.loadCalendarData = loadCalendarData;
OxxCalendar.prototype.resetCalendarDates = resetCalendarDates;
OxxCalendar.prototype.loadText = loadText;
OxxCalendar.prototype.getCalendar = getCalendar;
OxxCalendar.prototype.nextMonth = nextMonth;
OxxCalendar.prototype.previousMonth = previousMonth;
OxxCalendar.prototype.reset = reset;
OxxCalendar.prototype.loadWizardTexts = loadWizardTexts;
OxxCalendar.prototype.selectDateMouseOver = selectDateMouseOver;
OxxCalendar.prototype.selectDate = selectDate;
OxxCalendar.prototype.getRowColumnData = getRowColumnData;

function OxxCalendar(nInstanceName, nCalendarLeftID, nCalendarRigthID, nIdTextFini, nIdTextFout, paramDateFini, paramDateFout, twoMonths, twoDates) {
	// Set instance Name
	this.instanceName = nInstanceName;

	// Set calendar DIVS ID's
	this.calendarLeftID = nCalendarLeftID;
	this.calendarRigthID = nCalendarRigthID;

	// Set calendar F.Ini and F.out TEXTs ID's
	this.idTextFini = nIdTextFini;
	this.idTextFout = nIdTextFout;

	var nDateFini = null;
	if (!isEmpty(paramDateFini)) {
        nDateFini = createDateFromCode(paramDateFini);
	}
	var nDateFout = null;
	if (!isEmpty(paramDateFout)) {
		nDateFout = createDateFromCode(paramDateFout);
	}

	this.twoMonths = twoMonths;
	this.twoDates = twoDates;

	// Check valid dates
	if (!isEmpty(nDateFini) && !isEmpty(nDateFout) && compareDates(nDateFini, nDateFout) == 1) {
		var _tmp = nDateFini;
		nDateFini = nDateFout;
		if (this.twoMonths == '1')
			nDateFout = _tmp;
	}

	this.today = new Date();
	this.dateFini = nDateFini;
	this.leftCalendarDate = isEmpty(nDateFini) ? this.today : nDateFini;
	if (this.twoDates == '1') {
		if (!isEmpty(nDateFini) && compareDates(nDateFini, this.today) == -1) nDateFini = null;
		if (isEmpty(nDateFini) && !isEmpty(nDateFout)) nDateFout = null;
		this.dateFout = nDateFout;
	} else {
		if (!isEmpty(nDateFini) && compareDates(nDateFini, this.today) == -1) nDateFini = null;
	}
	if (this.twoMonths == '1') {
		this.rigthCalendarDate = new Date(this.leftCalendarDate.getFullYear(), this.leftCalendarDate.getMonth() + 1, 1);
	}
}

function setCalendarTexts(nMONTH_NAMES, nTXT_SELECT_FINI, nTXT_SELECT_FOUT, nTXT_DATE_FINI, nTXT_DATE_FOUT, nTXT_INVALID_DATES) {
	this.MONTH_NAMES = nMONTH_NAMES;
	this.TXT_SELECT_FINI = nTXT_SELECT_FINI;
	this.TXT_SELECT_FOUT = nTXT_SELECT_FOUT;
	this.TXT_DATE_FINI = nTXT_DATE_FINI;
	this.TXT_DATE_FOUT = nTXT_DATE_FOUT;
	this.TXT_INVALID_DATES = nTXT_INVALID_DATES;
}

function initDates(paramDateFini, paramDateFout) {
	this.dateFini = createDateFromCode(paramDateFini);
	if (this.twoDates == '1') {
		this.dateFout = createDateFromCode(paramDateFout);
	}
}

function load(loadCalendarDataBool, loadWizardTextsBool) {
	if (loadCalendarDataBool) {
		this.loadCalendarCaption(this.getCalendar("left"), this.leftCalendarDate);
		if (this.twoMonths == '1') {
			this.loadCalendarCaption(this.getCalendar("right"), this.rigthCalendarDate);
			this.loadCalendarData(this.getCalendar("right"), this.rigthCalendarDate, loadCalendarDataBool);
		}
	}
	this.loadCalendarData(this.getCalendar("left"), this.leftCalendarDate, loadCalendarDataBool);
	if (loadWizardTextsBool) this.loadWizardTexts();
}

function getCalendar(side) {
	return (side == "left") ? (document.getElementById(this.calendarLeftID)) : (document.getElementById(this.calendarRigthID));
}

function loadCalendarCaption(table, date) {
	var _caption = table.getElementsByTagName("caption")[0];
	_caption.innerHTML = this.MONTH_NAMES[date.getMonth()] + " " + date.getFullYear();
}

function loadWizardTexts() {
	if (this.twoDates == '1') {
		this.loadText(this.dateFini, document.getElementById(this.idTextFini), this.TXT_DATE_FINI, this.TXT_SELECT_FINI);
		this.loadText(this.dateFout, document.getElementById(this.idTextFout), isEmpty(this.dateFini) ? "&nbsp;" : this.TXT_DATE_FOUT, isEmpty(this.dateFini) ? "&nbsp;" :this.TXT_SELECT_FOUT);
	}
}

function loadText(date, element, txtDate, txtSelect) {
	if (isEmpty(date)) {
		element.innerHTML = "<strong>" + txtSelect + "</strong>";
	} else {
		element.innerHTML = "<strong>" + txtDate + ":</strong> " + date.getDate() + "/" + this.MONTH_NAMES[date.getMonth()] + "/" + date.getFullYear();
	}
}

function loadCalendarData(table, date, loadCalendarDates) {
	var _firstWeekDay = getFirstWeekDayInMonth(date);
	var _monthDays = getMonthDays(date);

	var _count = 0;
	var _rows = table.getElementsByTagName("tbody")[0].childNodes;
	for (i = 0; i < _rows.length; i++) {
		var _columns = _rows[i].childNodes;
		for (j = 0; j < _columns.length; j++) {
			var _rowColumn = _columns[j];
			var _className = "";
			// Valor por defecto vacio
			var _date = null;
			var _innerHTML = null;

			if ((_count != 0 || j >= _firstWeekDay) && _count < _monthDays) {
				_count++;
				_date = new Date(date.getFullYear(), date.getMonth(), _count);
				var _isLinkable = true;
				if (this.twoDates == '1') {
					if (compareDates(_date, this.today) === -1) {
						_className = "yesterday";
						_isLinkable = false;
					} else if (compareDates(_date, this.today) === 0) {
						_className = "today";
					}
				} else {
					if (compareDates(_date, this.today) === 0) {
						_className = "today";
					}
				}
				if (isDateInRange(_date, this.dateFini, this.dateFout)) {
					_className = isEmpty(_className) ? "selected" : _className + " selected";
				}
				_innerHTML = this.getRowColumnData(_date, _isLinkable);
			} else {
				_className = "empty";
			}
			if (loadCalendarDates) {
				fillRowColumn(_rowColumn, _date, _className, _innerHTML);
			} else {
				_rowColumn.className = _className;
			}
		}
	}
}

function resetCalendarDates() {
	var table = this.getCalendar("left");
	var _count = 0;

	var _rows = table.getElementsByTagName("tbody")[0].childNodes;
	for (i = 0; i < _rows.length; i++) {
		var _columns = _rows[i].childNodes;
		for (j = 0; j < _columns.length; j++) {
			var _rowColumn = _columns[j];
			var _className = "empty";
			_rowColumn.className = _className;
		}
	}

	if (this.twoMonths == '1') {
		table = this.getCalendar("right");
		_count = 0;

		var _rows = table.getElementsByTagName("tbody")[0].childNodes;
		for (i = 0; i < _rows.length; i++) {
			var _columns = _rows[i].childNodes;
			for (j = 0; j < _columns.length; j++) {
				var _rowColumn = _columns[j];
				var _className = "empty";
				_rowColumn.className = _className;
			}
		}
	}
}

function fillRowColumn(rowColumn, date, className, innerHTML) {
	// TODO: Pendiente decidir como eliminar atributos (removeAttribute)
	rowColumn.id = isEmpty(date) ? "" : createCodeFromDate(date);
	rowColumn.className = className;
	rowColumn.innerHTML = isEmpty(innerHTML) ? "&nbsp;" : innerHTML;
}

function getRowColumnData(date, isLinkable) {
	if (this.twoDates == '1') {
		if (isLinkable) {
			return "<a href=\"javascript:;\" onclick=\"" + this.instanceName + ".selectDate('" + createCodeFromDate(date) + "');this.blur()\" onmouseover=\"javascript: " + this.instanceName + ".selectDateMouseOver('" + createCodeFromDate(date) + "')\">" + date.getDate() + "</a>";
		} else {
			return "<a>" + date.getDate() + "</a>";
		}
	} else {
		return "<a href=\"javascript:;\" onclick=\"" + this.instanceName + ".selectDate('" + createCodeFromDate(date) + "');this.blur();agree();\">" + date.getDate() + "</a>";
	}
}


function selectDate(dateCode) {
	var _dateCodeArray = dateCode.split("-");
	var _date = new Date(_dateCodeArray[2], _dateCodeArray[1], _dateCodeArray[0]);
	if (this.twoDates == '1') {
		if (isEmpty(this.dateFini)) {
			this.dateFini = _date;
		} else if (isEmpty(this.dateFout)) {
			switch (compareDates(this.dateFini, _date)) {
				case -1:
					this.dateFout = _date;
					break;
				case 0:
					break;
				case 1:
					this.dateFout = this.dateFini;
					this.dateFini = _date;
			}
		} else {
			this.dateFini = _date;
			this.dateFout = null;
		}
	} else {
		this.dateFini = _date;
	}

	this.load(false, true);
}

function selectDateMouseOver(dateCode) {
	if (!isEmpty(this.dateFini) && isEmpty(this.dateFout)) {
		var _dateCodeArray = dateCode.split("-");
		var _date = new Date(_dateCodeArray[2], _dateCodeArray[1], _dateCodeArray[0]);

		var _oldDateFini = this.dateFini;
		switch (compareDates(this.dateFini, _date)) {
			case -1:
				this.dateFout = _date;
				break;
			case 0:
				break;
			case 1:
				this.dateFout = this.dateFini;
				this.dateFini = _date;
		}
		this.loadCalendarData(this.getCalendar("left"), this.leftCalendarDate, false);
		this.loadCalendarData(this.getCalendar("right"), this.rigthCalendarDate, false);
		this.dateFini = _oldDateFini;
		this.dateFout = null;
	}
}

function nextMonth() {
	if (this.twoMonths == '1') {
		this.leftCalendarDate = this.rigthCalendarDate;
		this.rigthCalendarDate = new Date(this.leftCalendarDate.getFullYear(), this.leftCalendarDate.getMonth() + 1, 1);
	} else {
		this.leftCalendarDate = new Date(this.leftCalendarDate.getFullYear(), this.leftCalendarDate.getMonth() + 1, 1);
	}
	this.load(true, false);
}

function previousMonth() {
	if (this.twoMonths == '1') {
		this.rigthCalendarDate = this.leftCalendarDate;
		this.leftCalendarDate = new Date(this.rigthCalendarDate.getFullYear(), this.rigthCalendarDate.getMonth() - 1, 1);
	} else {
		this.leftCalendarDate = new Date(this.leftCalendarDate.getFullYear(), this.leftCalendarDate.getMonth() - 1, 1);
	}
	this.load(true, false);
}

function reset() {
	this.dateFini = null;
	this.dateFout = null;
	this.load(true, true);
}

// DATE GENERAL FUNCTIONS

function getFirstWeekDayInMonth(date) {
	var _date = new Date(date.getFullYear(), date.getMonth(), 1);
	var _firstWeekDay = _date.getDay();
	return _firstWeekDay == 0 ? 6 : _firstWeekDay - 1;
}

function getMonthDays(date) {
	var _date = new Date(date.getFullYear(), date.getMonth() + 1, 0);
	return _date.getDate();
}


function compareDates(date1, date2) {
	if (date1.getFullYear() > date2.getFullYear()) return 1;
	else if (date1.getFullYear() < date2.getFullYear()) return -1;
	else if (date1.getMonth() > date2.getMonth()) return 1;
	else if (date1.getMonth() < date2.getMonth()) return -1;
	else if (date1.getDate() > date2.getDate()) return 1;
	else if (date1.getDate() < date2.getDate()) return -1;
	else return 0;
}

function getMostRecentDate(date1, date2) {
	if (isEmpty(date1)) return date2;
	if (isEmpty(date2)) return date1;
	return compareDates(date1, date2) == 1 ? date1 : date2;
}

function isDateInRange(date, dateIn, dateOut) {
	if (isEmpty(dateIn)) return false;
	if (isEmpty(dateOut)) return compareDates(date, dateIn) === 0;
	return compareDates(date, dateIn) !== -1 && compareDates(date, dateOut) !== 1;
}


function createDateFromCode(str) {
	var _dateArray = str.split("-");
	if (isArray(_dateArray) && _dateArray.length == 3 && isInteger(_dateArray[2]) && _dateArray[2].length == 4 && isInteger(_dateArray[1]) && _dateArray[1].length <= 2 && isInteger(_dateArray[0]) && _dateArray[0].length <= 2) {
		return new Date(_dateArray[2], _dateArray[1], _dateArray[0]);
	} else {
		return null;
	}
}

function createCodeFromDate(date) {
	return date.getDate() + "-" + date.getMonth() + "-" + date.getFullYear();
}

function createVisualFormattedDate(date, shortDateNamesArray) {
	return date.getDate() + "-" + shortDateNamesArray[parseInt(date.getMonth())] + "-" + date.getFullYear();
}

function createVisualFormattedDayOfTheWeek(date, shortDaysNamesArray) {
	return shortDaysNamesArray[date.getDay() == 0 ? 6 : (date.getDay() - 1)];
}