



/** a simple class for handling conversion between date field triples and a date object */

function DateField(dayField, monthField, yearField) {

    this.day    = dayField;

    this.month  = monthField;

    this.year   = yearField;

}

DateField.prototype.getDate = function() {

    var day     = this.day.value;

    var month   = this.month.value - 1; // this.month: 1-12->date:0-11

    var year    = this.year.value;

    return new Date(year, month, day);

}

DateField.prototype.setDate = function(date) {

    this.day.value      = date.getDate();

    this.month.value    = date.getMonth()+1;

    this.year.value     = date.getFullYear();

}





/** a small utility for creating tables */

function EHTable() {

    this.table          = document.createElement("table");

    //this.table.border   = "1";

    this.tbody          = document.createElement("tbody");

    this.table.appendChild(this.tbody);

}





/** append a table row, either use the argument or create a fresh one */

EHTable.prototype.appendTr = function(/* optional:*/ tr) {

    if(! tr) {

        tr  = document.createElement("tr");

    }

    this.tbody.appendChild(tr);

    this.tr = tr;

}



/** append a table cell, either use the argument or create a fresh one */

EHTable.prototype.appendTd = function(/* optional:*/ td) {

    if(! td) {

        td = document.createElement("td");

    }

    this.tr.appendChild(td);

    this.td = td;

}



/** convenience: append a child node to the most recent td */

EHTable.prototype.appendChild = function(node) {

    this.td.appendChild(node);

}



/** convenience: append a text child node to the most recent td */

EHTable.prototype.appendText = function(text) {

    var textNode    = document.createTextNode(text);

    this.appendChild(textNode);

}



/**

 *  A class for displaying a calender with multiple months

 */

function EHCalendar(container,

						  numberOfMonths, lang,

						  arr_day, arr_month, arr_year,

						  dep_day, dep_month, dep_year) {









	this.numberOfMonths         =  numberOfMonths;

	this.lang                   =  lang? lang : "es";



    this.arrival                = new DateField(arr_day, arr_month, arr_year);

    this.departure              = new DateField(dep_day, dep_month, dep_year);

    this.displayedDate         = this.stripDateToDay(new Date);



    this.mode                   = this.MODE_ARRIVAL;

	

	// div-layer containing the calendar tables

	this.container				=  container;

    this.render();

}



EHCalendar.prototype.MODE_ARRIVAL   = 0;    // select arrival date

EHCalendar.prototype.MODE_DEPARTURE = 1;    // select departure date





/** this is called whenever the calendar should update */

EHCalendar.prototype.update = function(event) {

    this.adjustDisplay();

    this.render();

}



/** make sure that the arrival is visible */

EHCalendar.prototype.adjustDisplay = function() {

    var arrival     = this.arrival.getDate();

    var firstDate   = this.stripDateToMonth(this.displayedDate);

    // the lastDate is after the dates displayed

    var lastDate   = this.addMonths(firstDate, this.numberOfMonths);

    if(arrival < firstDate || arrival >= lastDate) {

        // scroll to arrival date

        this.displayedDate  = this.arrival.getDate();

    }

}







/** clear the container */

EHCalendar.prototype.clear = function() {

    while(this.container.hasChildNodes()) {

        this.container.removeChild(this.container.firstChild);

    }

}





/** create month name row */

EHCalendar.prototype.monthNameTd = function(date) {

    var td  = document.createElement("td");

    td.colSpan  = "7";

    td.align    = "center";

    td.className= "calMonth";



    // create text:

    var month       = date.getMonth();

    var year        = date.getFullYear();

    var monthNames  = this.localize("MonthNames");

    var monthName   = monthNames[month];

    var title       = monthName + " " + year;

    var titleNode   = document.createTextNode(title);



    // put into text span (for formatting)

    var titleSpan   = document.createElement("span");

    titleSpan.className = "calMonth";

    titleSpan.appendChild(titleNode);

    td.appendChild(titleSpan);



    return td;

}





/** create a table for a single months */

EHCalendar.prototype.monthTable = function(date) {

    var month       = date.getMonth();

    var year        = date.getFullYear();



    var table       = new EHTable();

    table.table.className  = "tableDay";

    table.appendTr();

    table.appendTd(this.monthNameTd(date));



    // create day name row

    table.appendTr(this.create_dayname_row());



    var todaysDate          = this.stripDateToDay(new Date());

    var arrivalDate         = this.arrival.getDate();

    var departureDate       = this.departure.getDate();

    var firstWeekdayOfMonth = (date.getDay() + 6) % 7;    // 0 = monday

    var localizedModeText   = this.localizedModeText(this.mode);

    for (var week = 0; week < 6; week++) {

        table.appendTr();

        for (var weekday = 0; weekday < 7; weekday++) {

            var cellNumber  = 7 * week + weekday;

            var day         = cellNumber -  firstWeekdayOfMonth + 1;

            var tdClass     = "";

            var text        = String.fromCharCode(160); // nbsp;

            var onclick;

            var arg;

            var title;

			var infoCelda = new Array();

            if(day < 1) {

                // this cell is before the start of the month

                tdClass     = "calEmpty";

            } else {

                var date    = new Date(year, month, day);

                if(date.getMonth() != month) {

                    // this cell is after the end of the month

                    tdClass     = "calEmpty";

                } else {

                    // cell is within the month

                    text    = date.getDate();

                    if (date.valueOf() < todaysDate.valueOf()) {

                        // it's a date in the past

                        tdClass     = "calDaysPast";

                    } else {

						if (checkFullDates(date)) {

							tdClass = "calFullDate";

							title = "Hotel al completo"

						}	else {

							// a clickable date

							onclick = "selectDate";  // a function call

							arg     = date;

							infoCelda = this.tdClass(date, arrivalDate, departureDate);

							title   = (infoCelda[1]==''?'Marcar como '+localizedModeText:infoCelda[1]);

							tdClass = infoCelda[0];

						}

                    }

                }

            }

            var dayCell = this.createCell(text, tdClass, onclick, arg);

            if(title) {

                dayCell.title   = title;

            }

            table.appendTd(dayCell);

            table.td.align      = "right";

        } // for(weekday)

    } // for(week)

    return table.table;

}



EHCalendar.prototype.localizedModeText = function(mode) {

    var	keys    = new Array("Arrival Date", "Departure Date");

    var key     = keys[mode];

    return this.localize(key);

}



/** render (display) the calendar */

EHCalendar.prototype.render = function() {

    /*

    this.clear();

    this.container.appendChild(this.headline());

    return;

     */



    this.headline();

	

    var table               = new EHTable();

    table.table.className   = "tableMain";

    table.appendTr();

   	table.appendTd();



    	

	var className       = new Array("calStatePu", "calStateRe");

   	table.td.colSpan    =  this.numberOfMonths+2;

    table.td.align      = "center";

	table.td.className  = className[this.mode];

	

	

	//table.appendChild(this.headline())

		

    table.appendTr();

	table.appendTd(this.createNaviTd(0));

		

    var displayedDate = this.displayedDate;



    var month   = displayedDate.getMonth();

    var year    = displayedDate.getFullYear();

	

	for (var monthCount = 0; monthCount < this.numberOfMonths; monthCount++) {

        var firstDay    = new Date(year, month, 1);

        var monthTable  = this.monthTable(firstDay);

        table.appendTd();

		

        table.appendChild(monthTable);



        // advance to next month:

        month++;

        if(month > 11) {

            month   = 0;

            year++;

        }

    } // for(monthCount)



    table.appendTd(this.createNaviTd(1));

    

	// put calendar into container

    this.clear();

	this.container.appendChild(table.table);

}



/** return the css class for this date */

EHCalendar.prototype.tdClass = function(date, arrivalDate, departureDate) {

    var tdClass;

	var title = '';

	var infoCelda = new Array();

    // determine class for td

    if (date.valueOf() == arrivalDate.valueOf()) {

        tdClass	= "calPuDate";

		title = "Día de entrada";

    } else if (date.valueOf() == departureDate.valueOf()) {

        tdClass	= "calReDate";

		title = "Día de salida";

    } else if (arrivalDate.valueOf() <  date.valueOf()

               && date.valueOf() < departureDate.valueOf()) {

        tdClass	= "calDurDate";

	}  else if (checkTOferta(date)) {

		tdClass = "calTOferta";

		title = "Oferta especial";

	} else if (checkTAlta(date)) {

		tdClass = "calTAlta";

		title = "Temporada alta";

	} else if (checkTMedia(date)) {

		tdClass = "calTMedia";

		title = "Temporada media"

    } else if (date.getDay() == 0) {    // sunday

        tdClass	= "calSunday";

    } else {

        tdClass	= "calNorm";

    }

	infoCelda[0] = tdClass;

	infoCelda[1] = title;

    return infoCelda;

}



function toMySQLDate(date)

{

	var dia = date.getDate(); 

	if (dia < 10) dia = '0' + dia;

    var mes = date.getMonth()+1;

	if (mes < 10) mes = '0' + mes;

    var ano = date.getFullYear();

	return ano+'-'+mes+'-'+dia;

}



function checkFullDates (date)

{

	var full = false;

	var fecha = toMySQLDate(date);

	

	for(var x=0; x < hotel_lleno.length && !full;x++)

		if (hotel_lleno[x]==fecha)

			full=true;

	return full;

}



function checkTOferta (date)

{

	var esTOferta = false;

	var fecha = toMySQLDate(date);

	

	if ((fecha>=toferta[0] && fecha<=toferta[1]) || (toferta.length>2 && fecha>=toferta[2] && fecha<=toferta[3]))

		esTOferta=true;

	

	return esTOferta;

}



function checkTAlta (date)

{

	var esTAlta = false;

	var fecha = toMySQLDate(date);

	for(x = 0; x < talta.length; x=x+2) {
		if (fecha>=talta[x] && fecha<=talta[x+1])
			esTAlta=true;
	}

	return esTAlta;

}



function checkTMedia (date)

{

	var esTMedia = false;

	var fecha = toMySQLDate(date);

	

	if ((fecha>=tmedia[0] && fecha<=tmedia[1]) || (tmedia.length>2 && fecha>=tmedia[2] && fecha<=tmedia[3]))

		esTMedia=true;

	

	return esTMedia;

}





/** strip time info from date, i.e. make it midnight */

EHCalendar.prototype.stripDateToDay = function(date) {

    var  year   = date.getFullYear();

    var month   = date.getMonth();

    var day     = date.getDate();

    var stripped    = new Date(year, month, day);

    return stripped;

}



/** strip time info from date, i.e. make it midnight */

EHCalendar.prototype.stripDateToMonth = function(date) {

    var  year   = date.getFullYear();

    var month   = date.getMonth();

    var stripped    = new Date(year, month, 1);

    return stripped;

}





/** create the headline */

EHCalendar.prototype.headline = function() {

	var nbsp                    = String.fromCharCode(160);

	var td                      = document.createElement("td");

	var className				= new Array("calStatePu", "calStateRe");

    var tableEntrada                   = new EHTable();

    var tableSalida                   = new EHTable();

    tableEntrada.appendTr();

    tableSalida.appendTr();



	this.txtEntrada = document.getElementById("txtEntrada");

	this.txtSalida = document.getElementById("txtSalida");

	this.txtEntrada.innerText='';

	this.txtSalida.innerText='';

	

	// 0 = Arrival, 1 = Departure

	for(mode=this.MODE_ARRIVAL; mode<=this.MODE_DEPARTURE; mode++) {

        var	text		= this.localizedModeText(mode);

		button			=  document.createElement("input");

		button.type     = "radio";

		button.name     = "calendar_state";

		button.id       = "calendar_state";

		button.value    = "calendar_state_"+mode;

		var span;

		if(mode == this.mode) {

			// build the element for currently selected state

			span            = document.createElement("span");

			button.checked  = true;

			button.defaultChecked  = true;  // IE compatibility

		} else {

			// build the element for other other state

            button.checked  = false;

			span		= document.createElement("a");

            span.href   = "#"+this.mode;

            this.setDelegate(span, "onclick", this,  "switchMode", mode);

            this.setDelegate(button, "onclick", this,  "switchMode", mode);

		}

		var table = (mode==0?this.txtEntrada:this.txtSalida);

        //table.appendTd();

		span.className      = className[mode];

		span.appendChild(button);

		span.appendChild(document.createTextNode(text));

		table.appendChild(span);



		if(mode == this.MODE_ARRIVAL) {

            //table.appendTd();   // empty cell

            var spaces  = nbsp+nbsp+nbsp+nbsp+nbsp+nbsp;

           // table.appendText(spaces);

		}

	}



	//return table.table;*/

}



/** switch calendar to the given mode (select arrival/departure */

EHCalendar.prototype.switchMode = function(newMode) {

    this.mode   = newMode;

    this.render();

}



function switchMode (newMode) {

	

	EHCalendar.prototype.mode   = newMode;

	EHCalendar.prototype.render();

}



/** create a table cell and return it */

EHCalendar.prototype.createCell = function (txt, className, onclick, arg) {

	var txt         =  document.createTextNode(txt);

	var td          =  document.createElement("td");

    td.className    =  className;

	if (onclick) {

		var a           = document.createElement("a");

        a.href      = "#SelectDate";

		a.className     = className;

        this.setDelegate(a, "onclick", this, onclick, arg);

		a.appendChild(txt);

		td.appendChild(a);

	} else {

		td.appendChild(txt);		

	}

	return td;

}





/** set an event handler */

EHCalendar.prototype.setDelegate = function(element, eventName, delegate, methodName, argument) {

    element._delegate   = delegate;

    element._method     = methodName;

    element._argument   = argument;

    element[eventName]  = EHCalendar.prototype.forwarder;

}



/** forward an event */

EHCalendar.prototype.forwarder = function(event) {

    event       = event ? event : window.event;

    var target  = event.target ? event.target : event.srcElement;

    while(! target._delegate && target.parentNode) {

        // bubble up (<a onclick><img></a> returns the img as target)

        target      = target.parentNode;

    }

    if(target._delegate) {

        var delegate    = target._delegate;

        var method      = target._method;

        var argument    = target._argument;

        delegate[method](argument);

    }

}





/** create a row of daynames */

EHCalendar.prototype.create_dayname_row = function(arr, style) {

    var dayNames        = this.localize("DayNames");

    var tr              = document.createElement("tr");

	for (var day in dayNames) {		

		td      =  document.createElement("td");

		text    =  document.createTextNode(dayNames[day]);

		td.className =  "calDayName";

		td.appendChild(text);

		tr.appendChild(td);

	}

	return tr;

}





/** create a td for navigation (i.e. the << or >> links at the sides of the calender) */

EHCalendar.prototype.createNaviTd = function(direction) {

    var src;

    var alt;

    var title;

    var method;

		

    if(direction == 0) {

        src     = "arrow_left.gif";

        alt     = "<";

		title   = this.localize("Display previous month");

        method  = "displayPreviousMonth";

    } else {

        src     = "arrow_right.gif";

        alt     = ">";

        title   = this.localize("Display next month");

        method  = "displayNextMonth";

    }

    src = "img/"+src;

    var td      = document.createElement("td");

    var a       = document.createElement("a");

    var img     = document.createElement("img");

    a.href      = "#"+title;

    this.setDelegate(a, "onclick", this, method, 0);

    img.src     = src;

    img.alt     = alt;

    img.title   = title;

	img.className = "arrowCalendar";

    img.border  = "0";

    td.appendChild(a);

    a.appendChild(img);

	

    return td;

}





/** switch to next month */

EHCalendar.prototype.displayNextMonth = function() {

    this.displayedDate = this.addMonths(this.displayedDate, 1);

    this.render();

}



/** switch to previous month */

EHCalendar.prototype.displayPreviousMonth = function(id) {

    this.displayedDate = this.addMonths(this.displayedDate, -1);

    this.render();

}







/** select this date, called via the event handler */

EHCalendar.prototype.selectDate = function(date) {

    // validate date:

	hideReservar();

    if(this.mode == this.MODE_ARRIVAL) {

        this.arrival.setDate(date);

        if(date >= this.departure.getDate()) {

            this.departure.setDate(this.addDays(date, 1));

        }

    } else {    // MODE_DEPARTURE

        var today       = this.stripDateToDay(new Date());

        var tomorrow    = this.addDays(today, 1);

        if(date < tomorrow) {

            date    = tomorrow;

        }



        this.departure.setDate(date);

        if(date <= this.arrival.getDate()) {

            this.arrival.setDate(this.addDays(date, -1));

        }

				

    }

    

	// automatically switch to departure mode

	// when the first date is clicked

	if(this.mode == this.MODE_ARRIVAL) {

		// arrival

		if(! this.beenHere) {

			this.mode = this.MODE_DEPARTURE;

			this.beenHere	= 1;

		}

	}

	this.render();



    var event       = new Object();

    event.type      = "change";

    event.target    = this;

    if(this.onchange) {

        this.onchange(event);

    }

}



EHCalendar.prototype.addDays = function(date, addDays) {

    var msDate  = date.valueOf();

    var msAdd   = addDays * 24 *60 *60 * 1000;

    var msNew   = msDate + msAdd;

    var newDate = new Date(msNew);

    return newDate;

}



EHCalendar.prototype.addMonths = function(date, addMonths) {

    var year    = date.getFullYear();

    var month   = date.getMonth();

    var day     = date.getDate();

    month       += addMonths;

    // some browsers don't handle overflow gracefully:

    while(month > 11) {

        month   -= 11;

        year++;

    }

    while(month < 0) {

        month   += 11;

        year--;

    }

    var newDate = new Date(year, month, day);

    return newDate;

}





EHCalendar.prototype.getLanguage = function() {

    /*var language;

    if(navigator) {

        language    = navigator.language;

        if(language) {

            language    = language.substring(0,2).toLowerCase();

            if(! this.translations[language]) {

                language    = "en";

            }

        } else {

            language    = "en";

        }

    }

    return this.lang;

	*/

	return "es";

}



EHCalendar.prototype.localize = function(text) {

    var lang    = this.getLanguage();

	var tr      = this.translations[lang][text];

    if(! tr) {

        // assume that at least an english translation exists

        tr  = this.translations.en[text];

    }

    if(! tr) {

        // when everything fails, return the original text

        tr  = text;

    }

    return tr;

}





EHCalendar.prototype.initTranslations = function() {

    var tr  = new Object();



    tr.de    = new Object();

    tr.en    = new Object();

    tr.fr    = new Object();

    tr.nl    = new Object();

    tr.es    = new Object();

    tr.tr    = new Object();

    tr.pl    = new Object();

    tr.it    = new Object();





    tr.en["Display previous month"] = "Display previous month";

	tr.es["Display previous month"] = "Mes anterior";

    tr.de["Display previous month"] = "Vorhergehenden Monat anzeigen";



    tr.en["Display next month"]     = "Display next month";

	tr.es["Display next month"]     = "Mes siguiente";

    tr.de["Display next month"]     = "Folgenden Monat anzeigen";





    tr.de["Arrival Date"]           = "Anreise";

    tr.en["Arrival Date"]           = "Arrival Date";

    tr.fr["Arrival Date"]           = "Arrivée";

    tr.nl["Arrival Date"]           = "Aankomst";

    tr.es["Arrival Date"]           = "Fecha de entrada";

    tr.tr["Arrival Date"]           = "Otele giris";

    tr.pl["Arrival Date"]           = "Przyjazd";

    tr.it["Arrival Date"]           = "Arrivo";





    tr.de["Departure Date"]           = "Abreise";

    tr.en["Departure Date"]           = "Departure Date";

    tr.fr["Departure Date"]           = "Départ";

    tr.nl["Departure Date"]           = "Vertrek";

    tr.es["Departure Date"]           = "Fecha de salida";

    tr.tr["Departure Date"]           = "Otelden cikis";

    tr.pl["Departure Date"]           = "Wyjazd";

    tr.it["Departure Date"]           = "Partenza";







    tr.de["Close"]     =  "Bitte hier den Kalender schliessen";

    tr.de["DayNames"] =  new Array("Mo","Di","Mi","Do","Fr","Sa","So");

    tr.de["MonthNames"] =  new Array("Januar","Februar","März","April","Mai","Juni",

                                     "Juli","August","September","Oktober","November","Dezember");



    tr.de["Close"]     =  "close the calendar";

    tr.en["DayNames"] =  new Array("Mo", "Tu", "We", "Th", "Fr", "Sa", "Su");

    tr.en["MonthNames"] =  new Array("January", "February", "March", "April", "May", "June",

                                     "July", "August", "September", "October", "November", "December");



    tr.fr["Close"]     =  "fermer le calendrier";

    tr.fr["DayNames"] =  new Array("Lu", "Ma", "Me", "Je", "Ve", "Sa", "Di");

    tr.fr["MonthNames"] =  new Array("Janvier", "Février", "Mars", "Avril", "Mai", "Juin",

                                     "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre");



    tr.nl["Close"]     =  "kalender sluiten";

    tr.nl["DayNames"] =  new Array("Ma", "Di", "Wo", "Do", "Vr", "Za", "Zo");

    tr.nl["MonthNames"] =  new Array("Januari", "Februari", "Maart", "April", "Mei", "Juni",

                                     "Juli", "Augustus", "September", "Oktober", "November", "December");



    tr.es["Close"]     =  "Cierre";

    tr.es["DayNames"] =  new Array("Lu", "Ma", "Mi", "Ju", "Vi", "Sá", "Do");

    tr.es["MonthNames"] =  new Array("Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",

                                     "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre");



    tr.tr["Close"]     =  "Cierre";

    tr.tr["DayNames"] =  new Array("Pa", "Sa", "Ça", "Pe", "Cu", "Cu", "Pa");

    tr.tr["MonthNames"] =  new Array("Ocak ayy", "Pubat", "Mart", "Nisan", "Mayys", "Haziran",

                                     "Temmuz", "Aoustos", "Eylül", "Ekim", "Kasym", "Aralyk");



    tr.pl["Close"]     =  "Zamykac";

    tr.pl["DayNames"] =  new Array("Po", "Wt", "Sr", "Cz", "Pt", "So", "Ni");

    tr.pl["MonthNames"] =  new Array("Styczen", "Luty", "Kwiecien", "Maj", "Mayys", "Czerwiec",

                                     "Lipiec", "Sierpien ", "Wrzesien", "Pazdziernik", "Listopad ", "Grudzien");



    tr.it["Close"]     =  "Fine";

    tr.it["DayNames"] =  new Array("Lu","Ma","Me","Gi","Ve","Sa","Do");

    tr.it["MonthNames"] =  new Array("Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno",

                                     "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre");

    return tr;

}





EHCalendar.prototype.translations       = EHCalendar.prototype.initTranslations();






