/* Muestra una ventana modal con el contenido de element */
/*
function popup(element)
{
	Control.Modal.open(element,{
		overlayOpacity: 0.5,
		className: 'modal',
		constrainToViewport: true,
		iframe: false,
		iframeshim: false,
		fade: true
	});

	return false;
}
*/

/* Recarga la página cambiando el idioma */
function setLanguage(lang)
{
	/* Si estamos en un formulario cambiamos el action y lo enviamos. Si no, se envía el href normal */
	if (lang && ($('bookingForm') || $('searchForm')))
	{
		var action = window.location.href.replace(/https?:\/\/[\w\.\-]+(\/[a-z]{2})?\/(.*)/, "/" + lang + "/$2");
		var form = $('bookingForm') || $('searchForm');

		form.writeAttribute({action:action}).submit();

		/* Anular la acción del enlace */
		return false;
	}
	else
	{
		return true;
	}
}

/* Carga diferida del SDK de Facebook */
function loadFacebookSDK()
{
	/* Cargar el SDK */
	if ($('fb-root') && !$('script_fb_connect'))
	{
		/* Acciones al cargar el SDK */
		window.fbAsyncInit = function()
		{
			if (typeof document.fb_app_id !== 'undefined')
			{
				FB.init({
					appId: document.fb_app_id,
					status: true,
					cookie: true,
					xfbml: false,
					channelUrl: '//' + document.location.hostname + '/tools/facebook/channel.html'
				});
			}

			document.fire('fb:loaded');
		};

		var locale = document.locale || 'en_GB';

		$$('head')[0].insert(new Element('script', {type: 'text/javascript', id:'script_fb_connect', async: true, src: '//connect.facebook.net/' + locale + '/all.js'}));
	}
}

/* Navegar hacia un paso anterior */
function gotoStep(step)
{
	if ($('bookingForm'))
	{
		$('bookingForm').writeAttribute({action: $('bookingForm').readAttribute('action').replace(/step-\d/, 'step-'+step)});
		$('bookingForm').submit();
	}
}

/* Despliega el desglose de una reserva */
function showBreakdown(link, position)
{
	if ($('breakdown_' + position))
	{
		var breakdown = $('breakdown_' + position);

		var icolink = link.up('table.room').down('a.expand');
		icolink.addClassName('open');

		new Effect.toggle(breakdown, 'blind',
		{
			duration:0.4,
			afterFinish:function() {
				if (breakdown.visible()) icolink.addClassName('open');
				else icolink.removeClassName('open');
			},
			afterUpdate:summaryScroll
		});
	}
	return false;
}

/* Element.update con efecto */
Element.addMethods({
	updateEffect:function(element, text, options)
	{
		var duration = 0.4;

		var options = $H({
			from:0.3, pulses:1, duration:duration,
			afterFinish:function(){element.setOpacity(1)}
		}).merge(options).toObject();
		if (text) Element.update.delay(options.duration / 4, $(element), text);
		new Effect.Pulsate(element, options);
	}
});

Element.addMethods('INPUT',
{
	getCaretPosition:function(element)
	{
		var caretPos = 0;

		//IE
		if (document.selection)
		{
			element.focus ();

			var selection = document.selection.createRange();
			selection.moveStart('character', -element.value.length);
			caretPos = selection.text.length;
		}
		//Firefox
		else if (element.selectionStart || element.selectionStart == '0')
		{
			caretPos = element.selectionStart;
		}

		return (caretPos);
	},

	setCaretPosition:function(element, caretPos)
	{
		//IE
		if (document.selection)
		{
			element.focus();

			var selection = document.selection.createRange();
			selection.move('character', -element.value.length);
			selection.move('character', caretPos);
			selection.select();
		}
		//Firefox
		else if (element.selectionStart || element.selectionStart == '0') {
			element.selectionStart = caretPos;
			element.selectionEnd = caretPos;
			element.focus();
		}
		else
		{
			element.caretPosition = caretPos;
		}
	}

});

/* Filtra la entrada de datos en un INPUT de un formulario */
function filterInput(event)
{
	/*
	http://www.webonweboff.com/tips/js/event_key_codes.aspx
	*/
	if (event && (event.keyCode == 38 || event.keyCode >= 40))
	{
		switch (event.element().id || event.element().name)
		{
			case 'arrival':
			case 'departure':
				var caretPos = event.element().value.substring(0, event.element().getCaretPosition()).formatDate().length;
				var newDate = event.element().value.formatDate();

				/* Incremento de la fecha con las flechas del cursor, según la posición dentro del input */
				if (newDate.isDate() && event.type == 'keydown' && (event.keyCode == 38 || event.keyCode == 40))
				{
					/* Sumar o restar? */
					var diff = (event.keyCode == 38 ? +1 : (event.keyCode == 40 ? -1 : 0));

					/* Miramos si el cursor está posicionado en el día o el mes */
					var parts_after = newDate.slice(caretPos).split('/').length;

					if (parts_after == 3)
					{
						newDate = newDate.toDate().addDays(diff).toStrDate();
					}
					else if (parts_after == 2)
					{
						newDate = newDate.toDate().addMonths(diff).toStrDate();
					}
				}

				event.element().setValue(newDate);
				event.element().setCaretPosition(caretPos);
				break;

			case 'nights':
				var caretPos = event.element().value.substring(0, event.element().getCaretPosition()).formatNumeric(2).length;
				var newValue = event.element().value.formatNumeric(2);

				/* Incremento del valor con las flechas del cursor */
				var diff = (event.keyCode == 38 ? +1 : (event.keyCode == 40 ? -1 : 0));
				if (event.type == 'keydown' && diff)
				{
					newValue = parseInt(newValue) + diff;
				}

				event.element().setValue(newValue);
				event.element().setCaretPosition(caretPos);
				break;

			case 'phone':
				var caretPos = event.element().value.substring(0, event.element().getCaretPosition()).formatPhone().length;
				event.element().setValue(event.element().value.formatPhone());
				event.element().setCaretPosition(caretPos);
				break;

			case 'cc_number':
				var caretPos = event.element().value.substring(0, event.element().getCaretPosition()).formatCC().length;
				event.element().setValue(event.element().value.formatCC());
				event.element().setCaretPosition(caretPos);
				break;

			case 'cc_cvv':
				var caretPos = event.element().value.substring(0, event.element().getCaretPosition()).formatNumeric(4).length;
				event.element().setValue(event.element().value.formatNumeric(4));
				event.element().setCaretPosition(caretPos);
				break;

			case 'passport':
				var caretPos = event.element().value.substring(0, event.element().getCaretPosition()).formatAlphanumeric(10).length;
				event.element().setValue(event.element().value.formatAlphanumeric(10));
				event.element().setCaretPosition(caretPos);
				break;

			case 'email':
			case 'emailr':
				if (event.ctrlKey && event.keyCode == 67) event.stop();
				break;
		}
	}
}

function migas(step)
{
	createCookie('history-'+step, 1);

	if ($('link-history-1'))
	{
		$('link-history-1').addClassName('link');
		$('link-history-1').onclick = function() { history.go(parseInt(1 - step)); return false; };
	}

	if ($('link-history-2') && (readCookie('history-2') || step >= 2))
	{
		$('link-history-2').addClassName('link');
		$('link-history-2').onclick = function() { history.go(parseInt(2 - step)); return false; };
	}
	if (step == 1) eraseCookie('history-2');

	if ($('link-history-3') && (readCookie('history-3') || step >= 3))
	{
		$('link-history-3').addClassName('link');
		$('link-history-3').onclick = function() { history.go(parseInt(3 - step)); return false; };
	}
	if (step == 2) eraseCookie('history-3');
}

/* COOKIES */

function createCookie(name, value, path, days)
{
	if (name)
	{
		var cookie = [name+"="+value];

		if (days)
		{
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			cookie.push("expires="+date.toGMTString());
		}

		cookie.push("path=" + (path || '/'));

		document.cookie = cookie.join(';');

		return cookie.join(';');
	}
	else
	{
		return null;
	}
}

function readCookie(name)
{
	if (name)
	{
		var nameEQ = name + "=";
		var a_cookie = document.cookie.split(';');

		for (var i=0; i < a_cookie.length; i++)
		{
			var c = a_cookie[i];

			while (c.charAt(0) == ' ')
			{
				c = c.substring(1, c.length);
			}

			if (c.indexOf(nameEQ) == 0)
			{
				return c.substring(nameEQ.length, c.length);
			}
		}
	}

	return null;
}

function eraseCookie(name)
{
	createCookie(name, null, null, -1);
}

/* STRING */

String.prototype.trim = function(char)
{
	if (char == undefined) char = '\\s';
	return this.replace(new RegExp('^'+char+'*(.*?)'+char+'*$'), '$1');
}

String.prototype.pad = function(len, chr, right)
{
	var string = "" + this;

	if (!chr) chr = ' ';

	while (string.length < len)
	{
		if (right)
		{
			string = string + chr;
		}
		else
		{
			string = chr + string;
		}
    }

	return string;
}

String.prototype.isAlpha = function()
{
	return /^[a-zA-Z]+$/.test(this);
}

String.prototype.isAlphaNum = function()
{
	return !/\W/.test(this);
}

String.prototype.isFloat = function()
{
	return /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/.test(this);
}

String.prototype.isEmail = function()
{
	/* http://en.wikipedia.org/wiki/E-mail_address */
	return /^[-+!#$%&*=?{}|~\w]+(\.[-+!#$%&*=?{}|~\w]+)*@([-\w]+\.)+[a-z]{2,6}$/i.test(this);
}

String.prototype.isDate = function()
{
	return /^\d{1,2}\/\d{1,2}\/\d{4}$/.test(this);
}

String.prototype.isDateTime = function()
{
	// Comprueba una fecha con hora opcional y segundos opcionales
	return /^(\d{1,2}\/\d{1,2}\/\d{4})?\s?(\d{2}:\d{2}(:\d{2})?)?$/.test(this);
}

String.prototype.isTime = function()
{
	return /^\d{1,2}:\d{2}$/.test(this);
}

String.prototype.isUrl = function()
{
	return /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(this);
}

String.prototype.isNumeric = function()
{
	return (!isNaN(this) && !/^\s+$/.test(this));
}

String.prototype.isCreditCard = function(cardType)
{
	var cardNumber = this.replace(/[^\d]/g, "");
	var isValid = false;

	switch (cardType)
	{
		case "mastercard" :

			isValid = /^5[1-5][0-9]{14}$/.test(cardNumber);
			break;

		case "visa" :

			isValid = /^4[0-9]{12}(?:[0-9]{3})?$/.test(cardNumber);
			break;

		case "amex" :

			isValid = /^3[47][0-9]{13}$/.test(cardNumber);
			break;

		case "diners" :

			isValid = /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/.test(cardNumber);
			break;

		case "discover" :

			isValid = /^6(?:011|5[0-9]{2})[0-9]{12}$/.test(cardNumber);
			break;

		case "jcb" :

			isValid = /^(?:2131|1800|35\d{3})\d{11}$/.test(cardNumber);
			break;
	}

	if (isValid)
	{
		var numberProduct;
		var numberProductDigitIndex;
		var checkSumTotal = 0;

		for (var digitCounter = cardNumber.length - 1; digitCounter >= 0; digitCounter--)
		{
			checkSumTotal += parseInt(cardNumber.charAt(digitCounter));
			digitCounter--;
			numberProduct = String((cardNumber.charAt(digitCounter) * 2));

			for (var productDigitCounter = 0; productDigitCounter < numberProduct.length; productDigitCounter++)
			{
				checkSumTotal += parseInt(numberProduct.charAt(productDigitCounter));
			}
		}

		isValid = (checkSumTotal % 10 == 0);
	}

	return isValid;
}

String.prototype.formatDate = function()
{
	var date = this.replace(/[^\d\/]/g, '').replace(/\/+/g, '/').split('/');

	result = [];

	if (date.length > 0)
	{
		result[0] = date[0].substr(0, 2);
		if (result[0] > 31) result[0] = result[0].substr(0, 1);
	}
	if (date.length > 1)
	{
		result[1] = date[1].substr(0, 2);
		if (result[1] > 12) result[1] = result[1].substr(0, 1);
	}
	if (date.length > 2)
	{
		result[2] = date[2].substr(0, 4).replace(/\d{2}(.*)/, '20$1');
	}

	return result.join('/');
}

String.prototype.formatNumeric = function(limit)
{
	return this.replace(/[^\d]/g, '').substr(0, limit || 9999);
}

String.prototype.formatAlphanumeric = function(limit)
{
	return this.replace(/[^0-9a-z]/ig, '').substr(0, limit || 9999);
}

String.prototype.formatCC = function()
{
	return this.replace(/[^\d]/g, '').substr(0,16).replace(/(\d{4})/g, '$1 ');
}

String.prototype.formatPhone = function()
{
	return this.substr(0,1).replace(/[^\d\s+]/g, '') + this.substr(1).replace(/[^\d\s]/g, '').replace(/\s+/g, ' ');
}

String.prototype.toDate = function()
{
	if (this == '')
	{
		return new Date(0);
	}
	else if(!this.isDate())
	{
		return null;
	}
	else
	{
		var date_s = this.split("/");
		var new_date = [date_s[1],date_s[0],date_s[2]];

		// Formato mm/dd/yyyy
		var dDate = new Date(new_date.join("/"));

		return dDate;
	}
}

String.prototype.toDateTime = function()
{
	if(!this.isDateTime())
	{
		return null;
	}

	var newdate = /(?:(\d{1,2})\/(\d{1,2})\/(\d{4}))?\s?(?:(\d{2}):(\d{2})(?::(\d{2}))?)?/.exec(this);

	for(var i=1; i < newdate.length; i++)
	{
		if (typeof newdate[i] != "string")
		{
			newdate[i] = "0";
		}
	}

	var returndate = new Date(newdate[3], newdate[2], newdate[1], newdate[4], newdate[5], newdate[6]);

	return returndate;
}

String.prototype.getDaysBetween = function(date2)
{
	if (this.isDate() && date2.isDate())
	{
		return this.toDate().getDaysBetween(date2.toDate());
	}
	else
	{
		return null;
	}
}

String.prototype.addDays = function(n)
{
	return this.isDate() ? this.toDate().addDays(n).toStrDate() : null;
}

String.prototype.addMonths = function(n)
{
	return this.isDate() ? this.toDate().addMonths(n).toStrDate() : null;
}

String.prototype.addYears = function(n)
{
	return this.isDate() ? this.toDate().addYears(n).toStrDate() : null;
}

String.prototype.inArray = function(array)
{
	var needle = this;

	if (array != undefined && array.length)
	{
		return array.find(function(element){return element == needle;});
	}
	else
	{
		return false;
	}
}

/* DATE */

Date.prototype.isDate = function ()
{
	return true;
}
Date.prototype.toDate = function ()
{
	return this;
}

Date.prototype.copy = function ()
{
	return new Date(this.getTime());
}

Date.prototype.getDaysBetween = function(date2)
{
	var msPERDAY = 1000 * 60 * 60 * 24;

	/* Aquí redondeamos para sortear el problema de cambio de horario de verano */
	return Math.round((date2.getTime() - this.getTime()) / msPERDAY);
}

Date.prototype.addDays = function(n)
{
	var date = this.copy();
	date.setDate(this.getDate() + parseInt(n, 10));
	return date;
}

Date.prototype.addMonths = function(n)
{
	var date = this.copy();
	date.setMonth(this.getMonth() + parseInt(n, 10));
	return date;
}

Date.prototype.addYears = function(n)
{
	var date = this.copy();
	date.setYear(this.getFullYear() + parseInt(n, 10));
	return date;
}

Date.prototype.toStrDate = function()
{
	var day = parseInt(this.getDate(), 10);
	var month = parseInt(this.getMonth(), 10) + 1;

	return day.toString().pad(2, "0") + "/" + month.toString().pad(2, "0") + "/" + this.getFullYear();
}

/* Array */

Array.prototype.spliceValue = function(value)
{
	var done;

	for(var i = 0; i < this.length; i++)
	{
		if (this[i] == value)
		{
			this.splice(i,1);
			var done = true;
			i -= 1;
		}
	}

	return done ? value : null;
}

/*
Agregado a Scriptaculous
http://scriptaculous.jakewendt.com/effects.html
*/
Effect.SlideLeftIn = function(element) {
/*
	SlideLeftIn need to have the content of the element wrapped in a container element with fixed width!
*/
	element = $(element).cleanWhitespace();
	if ( ! element.effectOn ) {
		element.effectOn = true;
		var elementDimensions = element.getDimensions();
		return new Effect.Parallel ( [
			new Effect.Move(element,
				Object.extend({
					x: -(elementDimensions.width),
					sync: true,
					mode: 'relative',
					beforeStartInternal: function(effect) {
						if(window.opera) effect.element.setStyle({left: ''});
						effect.element.setStyle({left: elementDimensions.width + 'px' });
						effect.element.show();
					}
				}, arguments[1] || {})
			),
			new Effect.Scale(element, 100,
				Object.extend({ scaleContent: false,
					/* why does the use of sync: true make this flicker? */
					scaleY: false,
					scaleFrom: window.opera ? 0 : 1
				}, arguments[1] || {})
			)
			], Object.extend({
				beforeSetup: function(effect){
					effect.effects[0].element.parentNode.makeClipping();
					effect.effects[0].element.makeClipping();
				},
				afterFinishInternal: function(effect){
					effect.effects[0].element.parentNode.undoClipping();
					effect.effects[0].element.undoClipping();
				},
				afterFinish: function(effect){
//					delete(effect.effects[0].element.effectOn);
					effect.effects[0].element.effectOn = false;
				}
			}, arguments[1] || {})
		);
	}
}

/*
 * Aborta una petición Ajax
 * http://blog.bubbleideas.com/?p=443
 */
Ajax.Request.prototype.abort = function()
{
	if (!this._complete)
	{
		this.transport.onreadystatechange = null; //prevent state change callbacks from being issues
		this.transport.abort(); //abort the XHR
		Ajax.activeRequestCount--; //updates the request counter
	}
};
