﻿//Control calendario javascript:
//<Valores por defecto>
//(en caso no se haya inicializado la localización en las páginas):
var cal_defaultDateFormat = "dd/mm/yyyy";
var cal_defaultTitle = "Calendario";
var cal_defaultWeekDaysAbbrNames = new Array('Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sáb', 'Dom')
var cal_defaultWeekDaysNames = new Array('Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sábado', 'Domingo')
var cal_defaultMonthAbbrNames = new Array('Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic');

var calendars = Array();
var cal_monthAbbrNames = null;
var cal_weekDaysAbbrNames = null;
var cal_weekDaysNames = null;
var cal_openCal;
var cal_stuffInitzed = false;
var cal_title = "";

var cal_calCount = 0;

//</Valores por defecto>

function initCalendarStuff()
{
   cal_monthAbbrNames = (typeof(monthAbbrNames) != "undefined") ? monthAbbrNames : cal_defaultMonthAbbrNames;
	cal_title = (typeof(calendarTitle) != "undefined") ? calendarTitle : cal_defaultTitle;
	cal_weekDaysAbbrNames = (typeof(weekDaysAbbrNames) != "undefined") ? weekDaysAbbrNames : cal_defaultWeekDaysAbbrNames;
	cal_weekDaysNames = (typeof(weekDaysNames) != "undefined") ? weekDaysNames : cal_defaultWeekDaysNames;
	
	cal_stuffInitzed = true;
}

function getCalendar(fieldId)
{
	var formElement = cal_getObj(fieldId);
	return ensureCalendarObject(formElement);
}

function displayCalendarFor(fieldId)
{
	if(!cal_stuffInitzed)
		initCalendarStuff();

	var formElement = cal_getObj(fieldId);
	displayCalendar(formElement);
}

//Si no está creado ya el objeto asociado al elemento formElemen se crea
//y se añade a la colección de calendarios de la página
function ensureCalendarObject(formElement)
{
	if (!formElement.id)
	{
		formElement.id = cal_calCount++;
	}

	var cal = calendars[formElement.id];

	if (typeof(cal) == 'undefined')
	{
		cal = new calendarObject();
		cal.setElement(formElement);
		calendars[formElement.id] = cal;
	}
	
	return cal;
}

function displayCalendar(formElement)
{
	var cal = ensureCalendarObject(formElement);
   
	if (cal.shown)
		cal.hide();
	else
		cal.show();
}

function display3FieldCalendar(me, de, ye)
{
	if (!me.id)
		me.id = cal_calCount++;

	if (!de.id)
		de.id = cal_calCount++;

	if (!ye.id)
		ye.id = cal_calCount++;

	var id = me.id + '-' + de.id + '-' + ye.id;

	var cal = calendars[id];

	if (typeof(cal) == 'undefined')
	{
		cal = new calendarObject();
		cal.setElements(me, de, ye);
		calendars[id] = cal;
	}

	if (cal.shown)
		cal.hide();
	else
		cal.show();
}

//--Class Stuff--------------------------------------------------
function calendarObject()
{
	// Define Methods
	this.setElement = cal_setElement;
	this.setElements = cal_setElements;
	this.parseDate = cal_parseDate;
	this.generateHTML = cal_generateHTML;
	this.show = cal_show;
	this.hide = cal_hide;
	this.moveMonth = cal_moveMonth;
	this.setDate = cal_setDate;
	this.formatDate = cal_formatDate;
	this.setDateFields = cal_setDateFields;
	this.parseDateFields = cal_parseDateFields;
	
	//Gestor del evento "Fecha seleccionada"
	this.onDateSelected = null;

	this.shown = false;
}

function cal_setElement(formElement)
{
	this.element = formElement;
	if(this.element.dateFormat)
		this.format = this.element.dateFormat;
	else
		this.format = cal_defaultDateFormat;
	this.value = this.element.value;
	this.id = this.element.id;
	this.mode = 1;
}

function cal_setElements(monthElement, dayElement, yearElement)
{
	this.mElement = monthElement;
	this.dElement = dayElement;
	this.yElement = yearElement;
	this.id = this.mElement.id + '-' + this.dElement.id + '-' + this.yElement.id;
	this.element = this.mElement;

	if (cal_absoluteOffsetLeft(this.dElement) < cal_absoluteOffsetLeft(this.element))
		this.element = this.dElement;

	if (cal_absoluteOffsetLeft(this.yElement) < cal_absoluteOffsetLeft(this.element))
		this.element = this.yElement;

	if (cal_absoluteOffsetTop(this.mElement) > cal_absoluteOffsetTop(this.element))
		this.element = this.mElement;

	if (cal_absoluteOffsetTop(this.dElement) > cal_absoluteOffsetTop(this.element))
		this.element = this.dElement;

	if (cal_absoluteOffsetTop(this.yElement) > cal_absoluteOffsetTop(this.element))
		this.element = this.yElement;

	this.mode = 2;
}

//Parsea el campo de texto para inicializar el calendario:
function cal_parseDate()
{
	if (this.element.value)
	{
		this.date = new Date();
		var out = '';
		var token = '';
		var lastCh, ch;
		var start = 0;

		lastCh = this.format.substring(0, 1);

		for (i = 0; i < this.format.length; i++)
		{
			ch = this.format.substring(i, i+1);
			if (ch == lastCh)
				token += ch;
			else
			{
				cal_parseToken(this.date, token, this.element.value, start);
				start += token.length;
				token = ch;
			}
			lastCh = ch;
		}

		cal_parseToken(this.date, token, this.element.value, start);
	}
	else
		this.date = new Date();

	if ('' + this.date.getMonth() == 'NaN')
		this.date = new Date();
}

function cal_parseDateFields()
{
	this.date = new Date();
	if (this.mElement.value)
		this.date.setMonth(cal_getFieldValue(this.mElement) - 1);

	if (this.dElement.value)
		this.date.setDate(cal_getFieldValue(this.dElement));

	if (this.yElement.value)
		this.date.setFullYear(cal_getFieldValue(this.yElement));

	if ('' + this.date.getMonth() == 'NaN')
		this.date = new Date();
}

function cal_setDate(d, m, y)
{
	this.date.setYear(y);
	this.date.setMonth(m);
	this.date.setDate(d);

	if (this.mode == 1)
		this.element.value = this.formatDate();
	else
		this.setDateFields();
		
	this.hide();

	//Si desde fuera se ha definido un gestor de evento, este es el momento de llamarlo
	if(this.onDateSelected != null)
		this.onDateSelected();
}

function cal_setDateFields()
{
	cal_setFieldValue(this.mElement, cal_zeroPad(this.date.getMonth() + 1));
	cal_setFieldValue(this.dElement, cal_zeroPad(this.date.getDate()));
	cal_setFieldValue(this.yElement, this.date.getFullYear());
}

function cal_formatDate()
{
	var out = '';
	var token = '';
	var lastCh, ch;
	lastCh = this.format.substring(0, 1);

	for (i = 0; i < this.format.length; i++)
	{
		ch = this.format.substring(i, i+1);

		if (ch == lastCh)
			token += ch;
		else
		{
			out += cal_formatToken(this.date, token);
			token = ch;
		}

		lastCh = ch;
	}

	out += cal_formatToken(this.date, token);
	return out;
}

function cal_show()
{
	if (typeof(cal_openCal) != 'undefined')
		cal_openCal.hide();

	if (this.mode == 1)
	{
		this.parseDate();
	}
	else
	{
		this.parseDateFields();
	}

	this.showDate = new Date(this.date.getTime());

	if (typeof(this.div) == 'undefined')
	{
		this.div = document.createElement('DIV');
		this.div.style.position = 'absolute';
		this.div.style.display = 'none';
		this.div.className = 'cal_main';
	    //En caso de browsers <> IE, es necesario que los valores pasados a .left y .top sean cadenas
	    //que especifiquen también la unidad de medida
		this.div.style.left = cal_absoluteOffsetLeft(this.element) + "px";
		this.div.style.top = (cal_absoluteOffsetTop(this.element) + this.element.offsetHeight + 1) + "px";
		document.body.appendChild(this.div);
	}
	
	this.div.innerHTML = this.generateHTML();
	this.div.style.display = 'block';
	this.shown = true;
	cal_openCal = this;
}

function cal_generateHTML()
{
	var html = '';
	html += '<table>';
	html += '	<tr>';
	html += '		<td class="cal_head" colspan="6">' + cal_title + '</td>';
	html += '		<td class="cal_button" onMouseover="this.className = \'cal_buttonHover\';" onMouseout="this.className=\'cal_button\';" onClick="getCalendar(\'' + this.id + '\').hide();">X</td>';
	html += '	</tr>';
	html += '	<tr>';
	html += '		<td class="cal_button" onMouseover="this.className = \'cal_buttonHover\';" onMouseout="this.className=\'cal_button\';" onClick="getCalendar(\'' + this.id + '\').moveMonth(-12);"><<</td>';
	html += '		<td class="cal_button" onMouseover="this.className = \'cal_buttonHover\';" onMouseout="this.className=\'cal_button\';" onClick="getCalendar(\'' + this.id + '\').moveMonth(-1);"><</td>';
	html += '		<td colspan="3" class="cal_wk">' + cal_monthAbbrNames[this.showDate.getMonth()] + ' ' + cal_getYear(this.showDate) + '</td>';
	html += '		<td class="cal_button" onMouseover="this.className = \'cal_buttonHover\';" onMouseout="this.className=\'cal_button\';" onClick="getCalendar(\'' + this.id + '\').moveMonth(1);">></b></td>';
	html += '		<td class="cal_button" onMouseover="this.className = \'cal_buttonHover\';" onMouseout="this.className=\'cal_button\';" onClick="getCalendar(\'' + this.id + '\').moveMonth(12);">>></td>';
	html += '	</tr>';

	html += '	<tr>';
	for(var day=0;day<cal_weekDaysAbbrNames.length;day++)
	{
		var className = (day < 5) ? "cal_wk" : "cal_wknd";
		html += '		<td width="14%" class="' + className + '" title="' + cal_weekDaysNames[day] + '">' + cal_weekDaysAbbrNames[day] + '</td>';
	}
	html += '	</tr>';

	html += '	<tr>';

	var dow = 0;
	var i, style;
	var totald = cal_monthLength(this.showDate);

	for (i = 0; i < cal_firstDOW(this.showDate); i++)
	{
		dow++;
		html += '		<td class="cal_wk2">&nbsp;</td>';
	}

	for (i = 1; i <= totald; i++)
	{
		if (dow == 0)
			html += '	<tr>';

		if (this.showDate.getMonth() == this.date.getMonth() && this.showDate.getYear() == this.date.getYear() && this.date.getDate() == i)
			html += '		<td class="cal_date" onMouseover="this.className = \'cal_dateHover\';" onMouseout="this.className=\'cal_date\';" onClick="getCalendar(\'' + this.id + '\').setDate(' + i + ', ' + this.showDate.getMonth() + ', ' + this.showDate.getFullYear() + ');" ' + style + '><strong>' + i + '</strong></td>';
		else
			html += '		<td class="cal_date" onMouseover="this.className = \'cal_dateHover\';" onMouseout="this.className=\'cal_date\';" onClick="getCalendar(\'' + this.id + '\').setDate(' + i + ', ' + this.showDate.getMonth() + ', ' + this.showDate.getFullYear() + ');" ' + style + '>' + i + '</td>';

		dow++;
		if (dow == 7)
		{
			html += '	</tr>';
			dow = 0;
		}
	}

	if (dow != 0)
		for (i = dow; i < 7; i++)
			html += '		<td class="cal_wk2">&nbsp;</td>';

	html +='	</tr>';
	html += '</table>';

	return html;
}

function cal_hide()
{
	if (this.div != false)
		this.div.style.display = 'none';

	this.shown = false;
	cal_openCal = undefined;
}

function cal_moveMonth(amount)
{
	var m = this.showDate.getMonth();
	var y = cal_getYear(this.showDate);
	if (amount == 1)
	{
		if (m == 11)
		{
			this.showDate.setMonth(0);
			this.showDate.setYear(y + 1);
		}
		else
		{
			this.showDate.setMonth(m + 1);
	  }
	}
	else if (amount == -1)
	{
		if (m == 0)
		{
			this.showDate.setMonth(11);
			this.showDate.setYear(y - 1);
		}
		else
		{
			this.showDate.setMonth(m - 1);
	  }
	}
	else if (amount == 12)
	{
		this.showDate.setYear(y + 1);
   }
	else if (amount == -12)
   {
		this.showDate.setYear(y - 1);
   }

	this.div.innerHTML = this.generateHTML();
}

//--Utils-------------------------------------------------------------
function cal_absoluteOffsetTop(obj)
{
	var top = obj.offsetTop;
	var parent = obj.offsetParent;

	while (parent != document.body && parent != null)
	{
		top += parent.offsetTop;
		parent = parent.offsetParent;
	}

	return top;
}

function cal_absoluteOffsetLeft(obj)
{
	var left = obj.offsetLeft;
	var parent = obj.offsetParent;

	while (parent != document.body && parent != null)
	{
		left += parent.offsetLeft;
		parent = parent.offsetParent;
	}

	return left;
}

function cal_firstDOW(date)
{
	var dow = date.getDay();
	var day = date.getDate();

	if (day % 7 == 0)
	{
		return dow;
   }

	return (7 + dow - (day % 7)) % 7;
}

function cal_getYear(date)
{
	var y = date.getYear();

	if (y > 1900)
	{
		return y;
   }
   
	return 1900 + y;
}

function cal_monthLength(date)
{
	var month = date.getMonth();
	var totald = 30;
	if (month == 0
		|| month == 2
		|| month == 4
		|| month == 6
		|| month == 7
		|| month == 9
		|| month == 11) totald = 31;

	if (month == 1)
	{
		var year = date.getYear();
		if (year % 4 == 0 && (year % 400 == 0 || year % 100 != 0))
			totald = 29;
		else
			totald = 28;
	}
	return totald;
}

function cal_formatToken(date, token)
{
	var command = token.substring(0, 1);
	if (command == 'y' || command == 'Y')
	{
		if (token.length == 2)
			return cal_zeroPad(date.getFullYear() % 100);

		if (token.length == 4)
			return date.getFullYear();
	}

	if (command == 'd' || command == 'D')
	{
		if (token.length == 2)
			return cal_zeroPad(date.getDate());
	}

	if (command == 'm' || command == 'M')
	{
		if (token.length == 2)
			return cal_zeroPad(date.getMonth() + 1);

		if (token.length == 3)
			return cal_monthAbbrNames[date.getMonth()];
	}

	return token;
}

function cal_parseToken(date, token, value, start)
{
	var command = token.substring(0, 1);
	var v;
	if (command == 'y' || command == 'Y')
	{
		if (token.length == 2)
		{
			v = value.substring(start, start + 2);
			if (v < 70)
				date.setFullYear(2000 + parseInt(v));
			else
				date.setFullYear(1900 + parseInt(v));
		}

		if (token.length == 4)
		{
			v = value.substring(start, start + 4);
			date.setFullYear(v);
		}
	}

	if (command == 'd' || command == 'D')
	{
		if (token.length == 2)
		{
			v = value.substring(start, start + 2);
			date.setDate(v);
		}
	}

	if (command == 'm' || command == 'M')
	{
		if (token.length == 2)
		{
			v = value.substring(start, start + 2);
			date.setMonth(v - 1);
		}

		if (token.length == 3)
		{
			v = value.substring(start, start + 3);
			var i;
			for (i = 0; i < cal_monthAbbrNames.length; i++)
			{
				if (cal_monthAbbrNames[i].toUpperCase() == v.toUpperCase())
					date.setMonth(i);
			}
		}
	}
}

function cal_zeroPad(num)
{
	if (num < 10)
		return '0' + num;

	return num;
}

function cal_getObj(id)
{
   return document.getElementById(id);
}

function cal_setFieldValue(field, value)
{
	if (field.type.substring(0,6) == 'select')
	{
		var i;
		for (i = 0; i < field.options.length; i++)
		{
			if (cal_equals(field.options[i].value, value))
				field.selectedIndex = i;
		}
	}
	else
		field.value = value;
}

function cal_getFieldValue(field)
{
	if (field.type.substring(0,6) == 'select')
		return field.options[field.selectedIndex].value;
	else
		return field.value;
}

function cal_equals(val1, val2)
{
	if (val1 == val2)
		return true;

	if (1 * val1 == 1 * val2)
		return true;

	return false;
}
