/**
 * Vadingo global namespace structure
 *
 * @package    vadingo
 * @author     Luis Merino <mail@luismerino.name>
 */
var Vadingo = {
	
	version: '',
	
	build: '',
	
	imagesUrl: URI.base.valueOf() + 'assets/images/',
	
	scriptsUrl: URI.base.valueOf() + 'assets/js/',
	
	stylesUrl: URI.base.valueOf() + 'assets/css/',
	
	languages: {
		'de': {
			'description': 'Deutsch', 'cascade': ['en'],
			'Currency': {'decimal': ',', 'thousands': '.', 'symbol': unescape('%u20ac')},
			'Date': {'calendar_format': 'd/m/Y'}
		},
		'en': {
			'description': 'English', 'cascade': ['en-US'],
			'Currency': {'decimal': '.', 'thousands': ',', 'symbol': unescape('%u20ac')},
			'Date': {'calendar_format': 'd/m/Y'}
		},
		'es': {
			'description': 'Español', 'cascade': ['en'],
			'Currency': {'decimal': ',', 'thousands': '.', 'symbol': unescape('%u20ac')},
			'Date': {'calendar_format': 'd/m/Y'}
		}
	}
	
};

(function(global, $){
// We add all the functions which do some kind of initialization on the Site.
Vadingo.methods = {

	initCufon: function(context){
		if (!('Cufon' in window)) throw new Error("The Class 'Cufon' does not exists or has not been included.");
		var header, context = (!$chk(context)) ? '' : context;
		Cufon.replace(context+' .cufon, '+context+' h2, '+context+' legend', {hover: true});
		Cufon.replace(context+' .frontend-button-big', {hover: true});
		
		if ($E('h2') && $E('h2').hasClass('homepage')) {
			Cufon.replace('h2', {
				textShadow: '2px 2px rgba(0,0,0,0.5)'
			});
		}
	},
	
	initBrowserSupportCheck: function(){
		with(Browser.Engine){
			if (name == 'trident') {
				if (version <= 4) {
					document.location.href = URI.base.valueOf() + 'unsupported-browser';
				}
			}
		}
	},
	
	initPreloader: function(){
		if (!('Preloader' in window)) throw new Error("The Class 'Preloader' does not exists or has not been included.");
		
		new Preloader(Vadingo.imagesUrl + 'ajax-loader.gif');
	},
	
	initZenbox: function(){
		if (!('Zenbox' in window)) throw new Error("The Class 'Zenbox' does not exists or has not been included.");
		
		new Zenbox();
	},
	
	// initBgImage: function(){
	// 	var myImages = ['paris.jpg', 'rome.jpg', 'vienna.jpg', 'london.jpg', 'barcelona.jpg', 'moscow.jpg', 'chewing-the-sun-3.jpg'];
	// 	// Preload images in homepage to cache them for later randomization!
	// 	new PreloaderQueue(myImages.map(function(src){ return Vadingo.imagesUrl + src; }));
	// 	// Set a random background image
	// 	Element(document.body).setStyle('background', 'url('+Vadingo.imagesUrl+myImages.getRandom()+') no-repeat top center');
	// },
	
	initThawte: function(){
		if (!('Thawte' in window)) throw new Error("The Class 'Thawte' does not exists or has not been included.");
		
		new Thawte();
	},

/*	// CAUSING TROUBLE IN IE8 - NOW GETS CALLED IN MASTER TMPL
	initAddThisButton: function(){
		new Asset.javascript('http://s7.addthis.com/js/250/addthis_widget.js#username=xa-4c36f0bc3224e038');
	},
*/

	initTabPane: function(){
		new TabPane('tabs');
	},
	
	initRegionsMap: function(){
		var regions = null, clsname = 'unfold';
		
		if (regions = document.id('regions-map-wrapper')) {
			document.id('location').addEvents({
				'focus': function(){
					regions.addClass(clsname);
				},
				'blur': function(){
					regions.removeClass(clsname);
				},
				'change': function(){
					this.blur();
				}
			}).addEvent('click:relay(option)', function(){
				document.id('location').blur();
			});
		}
	},
	
	initIndexBudget: function(){
		//document.id('intro').hide();
		//document.id(document.body).addClass('sun');
		
		var budgetEl = document.id('budget').setProperty('autocomplete', 'off');
		var clsname = 'error-input';
		var digits = new RegExp(/^([0-9])+$/);
		
		budgetEl.addEvent('keyup', trackDigits);
		
		function trackDigits(){
			if (digits.test(budgetEl.get('value'))) {
				budgetEl.removeClass(clsname);
			} else {
				budgetEl.addClass(clsname);
			}
		};
		
		document.id('search-form').addEvent('submit', function(event){
			if (!digits.test(budgetEl.get('value'))) {
				event.stop();
				budgetEl.addClass(clsname);
				budgetEl.focus();
			}
		});
	},
	
	initTips: function(){
		if (!('Tips' in window)) throw new Error("The Class 'Tips' does not exists or has not been included.");
		// Avoid instantiation of Class when there're no tips in the HTML
		var selectors = '.vadingo-tip, .timeline-widget .actions button';
		if (!$$(selectors).length) return false;
		
		var vadingo_tips = new Tips($$(selectors), {
			'className': 'vadingo-tooltip',
			'text': null,
			'fixed': true,
			'offset': {x: 0, y: 42},
			'showDelay': 0,
			'onShow': function(tip, element){
				if (!Browser.Engine.trident) {
					this.tip.setStyles({'display': 'block', 'opacity': 0}).get('tween', {property: 'opacity', duration: 200, transition: 'linear'}).start(0, 1);
				} else {
					this.tip.setStyle('display', 'block');
				}
				this.options.offset.x = -(this.tip.offsetWidth/2 - element.offsetWidth/2);
			}
		});
	},

	initHelpTips: function(){
		if (!('Tips' in window)) throw new Error("The Class 'Tips' does not exists or has not been included.");
		// Avoid instantiation of Class when there're no tips in the HTML
		var selectors = '.help-tip';
		if (!$$(selectors).length) return false;
		
		var deals_tips = new Tips($$(selectors), {
			'className': 'help-tooltip',
			'fixed': false,
			'offset': {x: 0, y: (Browser.Platform.mac) ? 23 : 28},
			'showDelay': 300,
			'onShow': function(){
				this.tip.setStyle('display', 'block');
				this.options.offset.x = -(this.tip.offsetWidth/2);
			}
		});
	},

	initListingDragAndDrop: function(){
		if (!('ListingDragAndDrop' in window)) throw new Error("The Class 'ListingDragAndDrop' does not exists or has not been included.");
		
		var items = $$('#search-results li > a, #search-results-similar li > a');
		if (!items.length) return false;
		
		//this.tm = Controller.getInstance().translation;
		ListingDragAndDrop.init(items, $E('.dropzone'));
	},
	
	initVideo: function() {
		var video = document.getElementsByTagName("video")[0];
		
		if(video) {

			video.addEventListener('ended', function () {
				this.play();
			});
			
		}
	},
	
	initAcc: function(){
		if ($$('.acc-toggler')) {
			var myAccordion = new Fx.Accordion($$('.acc-toggler'), $$('.acc-element'), {
			display: -1
			});
		}
	},
	
	initSwfObject: function() {
		var s1 = new SWFObject('/assets/movies/player.swf','player','468','378','9');
		s1.addParam('allowfullscreen','false');
		s1.addParam('allowscriptaccess','always');
		s1.addParam('wmode', 'transparent');
		s1.addVariable('autoRewind','false');
		s1.addVariable('type','video');
		s1.addVariable("autoplay","true");
		s1.addVariable("autostart","true");
		s1.addVariable('file','/assets/movies/teaser_'+lang+'.m4v');
		s1.addVariable('controlbar','none');
		//s1.addVariable('skin','/assets/movies/comet.swf');
		s1.addVariable('stretching','uniform');
		s1.addVariable('image','/assets/images/movie.jpg');

	},
	
	initTeaserVideo: function() {

		var lang = document.id('logo').get('class');
		var s1 = new SWFObject('/assets/movies/player.swf','player','468','264','9', 'ffffff');
		s1.addParam('allowfullscreen','false');
		s1.addParam('allowscriptaccess','always');
		s1.addParam('wmode', 'transparent');
		s1.addVariable('autoRewind','false');
		s1.addVariable('type','video');
		s1.addVariable("autoplay","false");
		s1.addVariable("autostart","false");
		s1.addVariable('file','/assets/movies/teaser_'+lang+'.m4v');
		s1.addVariable('controlbar','none');
		//s1.addVariable('skin','/assets/movies/comet.swf');
		s1.addVariable('image','/assets/images/movie.jpg');
		s1.addVariable('stretching','uniform');
		s1.write('teaser-vadingo-video');
	},

	initPromoVideo: function() {

		var lang = $('logo').get('class');
				var s1 = new SWFObject('/assets/movies/player.swf','player','460','254','9', 'ffffff');
				s1.addParam('allowfullscreen','false');
				s1.addParam('allowscriptaccess','always');
				s1.addParam('wmode', 'transparent');
				s1.addVariable('autoRewind','false');
				s1.addVariable('type','video');
				s1.addVariable("autoplay","false");
				s1.addVariable("autostart","false");
				s1.addVariable('file','/assets/movies/how-it-works_'+lang+'.m4v');
				s1.addVariable('controlbar','none');
				//s1.addVariable('skin','/assets/movies/comet.swf');
				s1.addVariable('image','/assets/images/how-it-works.jpg');
				s1.addVariable('stretching','uniform');
				s1.write('how-it-works-video');
	},
	
	initDetailViewSlider: function(){
 		
		var slide = document.id('slider');
		
		var IMAGE_WIDTH = 600;

		if (slide) {
			mySlide = function(slide) {

				var inner = document.id('slider-inner'),
				knob = document.id('slider-knob'), 
				control = document.id('slider-control');
				var slider = null;
				var count = $$('.item').length;
				//var posStart = $('main-content').getPosition();
				var posStart = document.id('main-content').getPosition();
				var offset = posStart.x + 180;
				inner.setStyle('padding-left', offset);
				
				slide.getElement('div.wrapper').setStyle('width', document.getSize().x); 
				//alert(document.getSize().x);
				inner.setStyle('width', count*IMAGE_WIDTH+'px');
				slide.getElement('div.wrapper').setStyle('margin-left', -(slide.getPosition().x +1));

				var fx = new Fx.Tween(inner, {
					property: 'left',
					link: 'cancel',
					duration: 500,
					transition: Fx.Transitions.Sine.easeOut
				});

				function update() {
					var left = 0;
					
					var maskLeftWidth = document.id('main-content').getCoordinates().left+180;
					var maskLeftWidth = document.id('main-content').getCoordinates().left+180;

					var maskRightWidth = document.id('header').getCoordinates().right-maskLeftWidth-IMAGE_WIDTH;
					var maskTop = 40; //document.id('slider-inner').getCoordinates().top;
					           
					document.id('mask-left').setStyles({
						width: maskLeftWidth+'px',
						top : maskTop+'px',
						height: document.id('slider-inner').offsetHeight,
						position: 'absolute',
						left: -((window.getScrollSize().x-960)/2)+'px'
					});

					document.id('mask-right').setStyles({
						width: maskRightWidth+'px',
						top : maskTop+'px',
						height: document.id('slider-inner').offsetHeight,
						position: 'absolute',
						right: -((window.getScrollSize().x-960)/2)+'px'
						
					});

					if (false && slider) {
						control.removeEvents();
						knob.removeEvents();
						slider.removeEvents();
						inner.setStyle('margin-left', offset);
						slider = null;
				}

				var last = inner.getLast();
				if (!last) {
					return document.id('slider-knob') ? document.id('slider-knob').dispose() : null;
				}
				var max = last.offsetWidth * ((inner.getChildren().length)-1);
				
				document.id('slider-knob').setStyle('width', '30px'); //tweaking th knob!
				
				slider = new Slider(control, knob, {
					snap: true,
					range: [0, max],
					steps: inner.getChildren().length-1,
					wheel: true,
					snap: false,
					onChange: function(set){
						//window.status = set;
						fx.start(-set);
						
					}
				});

				slider.drag.options.preventDefault = true;
				} // END MYSLIDE()
				window.addEvent('resize', update).addEvent('load', update);
		};  // END SLIDE

		mySlide(slide);
		}
	},
	
	initFeedback: function(){
		//
	},
	
	initDatePicker: function(){
		if (!('Calendar' in window)) throw new Error("The Class 'Calendar' does not exists or has not been included.");
		// This is one of the worse forms of instantiation classes in all Date Pickers classes.
		// Not to mention the mediocre code, but it works and its the only that has all the methods Vadingo needs...
		// TODO: Complete a class for Date Pickers.
		new Calendar({arrive: MooTools.lang.get('Date', 'calendar_format'), depart: MooTools.lang.get('Date', 'calendar_format')},
					{
						days: MooTools.lang.get('Date', 'days'),
						months: MooTools.lang.get('Date', 'months'),
						pad: 1,
						classes: ['dashboard'],
						direction: 1,
						offset: 1,
						tweak: { x: -100, y: -25 }
					}
				);
		
		// return;
		// 		
		// 		$$('.datepicker').each(function(dp){
		// 			new DatePicker(dp);
		// 		});
		// 		
		// 		return;
		// 		
		// 		var instances = $$('.date-picker').map(function(pick){
		// 			return new DatePicker(pick, {
		// 				'onRender': function(){
		// 					document.addEvent('esc', this.hide.bind(this));
		// 					// TODO: add close button event too.
		// 				},
		// 				'onPick': function(){
		// 					this.fireEvent('onChange');
		// 					this.accept(DatePeerVisitor);
		// 				},
		// 				'onChange': function(){
		// 					var d = new Date(this.year, this.month - 1, this.day);
		// 					pick.set('value', d.format('%x'));
		// 				}
		// 			});
		// 		});
		// 		
		// 		var DatePeerVisitor = {
		// 			getOrder: function(element){
		// 				var match = new RegExp(/\border\:(\d+)\b/).exec(element.className);
		// 				return Number(match[1]);
		// 			},
		// 			visit: function(instance){
		// 				var d = new Date(instance.year, instance.month - 1, instance.day);
		// 				var ordered = [];
		// 				Array.each(instances, function(object){
		// 					ordered[this.getOrder(object.trigger)] = object;
		// 				}, this);
		// 				ordered = ordered.clean();
		// 				var from = ordered.indexOf(instance);
		// 				var i, index;
		// 				for (var i = from; i < ordered.length; i++) {
		// 					index = i + 1;
		// 					d2 = (ordered[index]) ? new Date(ordered[index].year, ordered[index].month - 1, ordered[index].day) : d;
		// 					if (d > d2) {
		// 						ordered[index].pick(ordered[index].container.getElements('a.datepicker-day')[d.get('date') * (i - order)]);
		// 					}
		// 				}
		// 				for (i = from; i > -1; i--) {
		// 					index = i - 1;
		// 					d2 = (ordered[index]) ? new Date(ordered[index].year, ordered[index].month - 1, ordered[index].day) : d;
		// 					if (d < d2) {
		// 						ordered[index].pick(ordered[index].container.getElements('a.datepicker-day')[d.get('date') - from + index]);
		// 					}
		// 				}
		// 			}
		// 		};
	},
	
	// initOfferDatePicker: function(){
	// 		if (!('Calendar' in window)) throw new Error("The Class 'Calendar' does not exists or has not been included.");
	// 		
	// 		var NUM_OFFERS = 2;
	// 		var FLEXIBLE_DAYS = 7;
	// 		var flexible = null;
	// 		
	// 		if ($E('input[name=flexible]') && !!$E('input[name=flexible]').get('value')) flexible = FLEXIBLE_DAYS;
	// 		
	// 		// REPEAT CALENDAR TWICE FOR OFFERS 1 AND 2
	// 		NUM_OFFERS.times(function(i){
	// 			i++;
	// 			var start = Date.parse(document.id('offers['+i+'][arrival]').get('value'));
	// 			var end = Date.parse(document.id('offers['+i+'][departure]').get('value'));
	// 			var pad = start.diff(end);
	// 		
	// 			if (nil(flexible)) {
	// 				start.decrement('day', flexible+1);
	// 				end.increment('day', flexible+1);
	// 			}
	// 		
	// 			var permittedMonths = [];
	// 			var limitedMonths = [1,2,3,4,5,6,7,8,9,10,11,12].filter(function(m){
	// 				return (m < (start.get('month')+1) || m > (end.get('month')+1)) ? true : !(permittedMonths.push(m));
	// 			});
	// 		
	// 			if (permittedMonths.length > 1) {
	// 				blockedDatesArray = [
	// 					('0-'+start.get('date')+' '+permittedMonths[0]+' '+start.get('year')),
	// 					(end.get('date')+'-'+end.getLastDayOfMonth()+' '+permittedMonths[1]+' '+end.get('year'))
	// 				];
	// 			} else {
	// 				blockedDatesArray = [
	// 					('0-'+start.get('date')+' '+permittedMonths[0]+' '+start.get('year')),
	// 					(end.get('date')+'-'+end.getLastDayOfMonth()+' '+permittedMonths[0]+' '+end.get('year'))
	// 				];
	// 			}
	// 		
	// 			var blockedDates = ['1-31 '+limitedMonths.join(',')+' '+start.get('year')+','+end.get('year')].combine(blockedDatesArray);
	// 			var errorDiv = $E('#offer-'+i+' div.error');
	// 			var calObjects = {};
	// 				calObjects['offers['+i+'][arrival]'] = MooTools.lang.get('Date', 'calendar_format');
	// 				calObjects['offers['+i+'][departure]'] = MooTools.lang.get('Date', 'calendar_format');
	// 		
	// 			new Calendar(calObjects, {
	// 				blocked: blockedDates,
	// 				days: MooTools.lang.get('Date', 'days'),
	// 				months: MooTools.lang.get('Date', 'months'),
	// 				pad: pad,
	// 				classes: ['dashboard'],
	// 				direction: 0,
	// 				offset: 1,
	// 				tweak: { x: -100, y: -25 },
	// 				'onHideComplete': function(){
	// 					//console.log(Date.parse(document.id('offers['+i+'][arrival]').get('value')));
	// 					var diff = Date.parse(document.id('offers['+i+'][arrival]').get('value')).diff(Date.parse(document.id('offers['+i+'][departure]').get('value')));
	// 					if (diff != pad) {
	// 						errorDiv.removeClass('hide').set('text', 'Your client made the enquiry of '+pad+' days, please check the start and end dates.');
	// 					} else {
	// 						errorDiv.addClass('hide');
	// 					}
	// 				}
	// 			});
	// 		});
	// 	},
	
	initButtons: function(){
		/*$$('button').addEvent('focus', function(){
			this.blur();
		});*/
	},

	initSearchSlide: function(){
		var button, slider;
		
		if (button = document.id('search-form-trigger')) {
			button.addEvent('click', function(event){
				event.preventDefault();
				slider.start(!slider.element.getStyle('height').toInt() ? 280 : 0);
			});
			slider = new Fx.Tween('search', {property: 'height', duration: 500, transition: Fx.Transitions.Sine.easeOut});
			if (Controller.getInstance().methods.contains('initFixedSuitcase')) {
				slider.addEvent('complete', function(){
					Vadingo.methods['initFixedSuitcase'].update();
				});
			}
			slider.set((!$$('#search .errors').length ? 0 : 280));
		}
	},
	
	initSearchAware: function(){
		if (!document.id('bingo')) return;
		if (!Cookie.read('com.vadingo.search_popup')) {
			var element = document.id('bingo').dispose();
				element.getElement('h2').setStyles({'font-size': '1.7em', 'line-height': '1.25em'});
			SqueezeBox.open(element, {handler: 'clone', size: {x: '960', y: ''}, overlayOpacity: 0.5});
			Cookie.write('com.vadingo.search_popup', true, {duration: 7});
		}
	},
	
	initCropper: function(){
		if (!('UvumiCropper' in window)) throw new Error("The Class `UvumiCropper` does not exists or has not been included.");
		
		var viewport = {x: 200, y: 133}; // 3:2 ratio!
		var ns = this.notification;
		
		var target = document.id('cropper-target');
		var options = {
			keepRatio: true,
			coordinates: true,
			preview: 'cropper-preview',
			mini: viewport,
			handles: [['top', 'left'], ['top', 'right'], ['bottom', 'left'], ['bottom', 'right']],
			serverScriptSave: new URI(location.href).toRelative(),
			onImageLoad: function(){
				document.id('cropper-save').onclick = function(){
					if (!this.retrieve('clicked')) {
						this.store('clicked', true);
						return cropper.cropSave();
					}
					return false;
				};
				document.id('cropper-reset').onclick = function(){
					return cropper.reset();
				};
			},
			onRequestFail: function(){
				ns.notify(
					this.tm._("This request could not be completed, please try again in a few moments…", 'application')
				);
			},
			onCropFail: function(json){
				// Any error thrown by the validator OR the media manager model?
			},
			onCropSuccess: function(json){
				this.changeImage(json.meta.uri);
				ns.success(
					this.tm._("Your image was successfully cropped!", 'mediamanager.cropper')//,
					// [ this.tm._("Go to Media Manager"), json.meta.uri_redirect ],
					// 				[ this.tm._("Crop again"), location.href ]
				);
				document.id('cropper-save').hide();
				document.id('cropper-reload').show();
			},
			onCropSave: function(){
				//obscure the element with the spinner
				document.id('image').set('spinner', {msg: this.tm._('One moment…', 'application')}).spin();
			},
			onCropComplete: function(){
				document.id('image').unspin(); //hide the spinner
			}
		};
		var cropper = new UvumiCropperCustom(target, options);
		document.id('cropper-reload').hide();
		document.id('cropper-reload').addEvent('click', function(){
			document.id('cropper-coordinates').dispose();
			cropper = null;
			cropper = new UvumiCropperCustom(target, options);
			document.id('cropper-save').show();
			document.id('cropper-save').store('clicked', false);
			this.hide();
		});
	},
	
	initMediaBrowser: function(){
		if (!('MediaFileOrganizer' in window)) throw new Error("The Class `MediaFileOrganizer` does not exists or has not been included.");
		
		var loaderWrap = document.id('mediafile-browse-footer').getElement('.loader div');
		loaderWrap.get('spinner', {message: Vadingo.translationManager._('One moment…', 'application'), img: false, style: {opacity: 1}});
		
		new MediaFileOrganizer({
			wrapper: 'mediafile-browse-list', // Single element $
			collections: 'li.collection', // Collection elements $$
			files: 'li:not(.collection)', // Collection elements $$
			onReorder: function(){
				loaderWrap.spin();
			},
			onReorderComplete: function(){
				loaderWrap.unspin();
			}
		});
	},

	initMediaManagerAdd: function(){
		// start spinner 'loading...' to be able to load translations by xhr
		document.id('mediafile-upload-form').set('spinner', {message: Vadingo.translationManager._('One moment…', 'application')}).spin();
		// let's load the fun...
		Vadingo.translationManager.addEvent('load', function(){
			var up = new FancyUpload2(document.id('mediafile-upload-status'), document.id('mediafile-upload-list'), { // options object
				// we console.log infos, remove that in production!!
				//verbose: true,

				//instantStart: true,
				appendCookieData: true,

				// url is read from the form, so you just have to change one place
				url: document.id('mediafile-upload-form').get('action'),
      
				// path to the SWF file
				path: Vadingo.imagesUrl + 'mediamanager/Swiff.Uploader.swf',

				// remove that line to select all files, or edit it, add more items
				typeFilter: {
					'Media Files (*.jpg, *.jpeg, *.gif, *.png)': '*.jpg; *.jpeg; *.gif; *.png'
				},

				// this is our browse button, *target* is overlayed with the Flash movie
				target: 'browse',
			
				// 5 MB in bytes unit
				fileSizeMax: 5 * 1024 * 1024,
				fileListMax: 6,
				fileListSizeMax: 50 * 1024 * 1024,

				onFileStart: function(file) {
					var progress = file.element.getElement('.file-info');
					this.currentProgress = new Fx.SimpleProgressBar(progress);
				},
			
				// graceful degradation, onLoad is only called if all went well with Flash
				onLoad: function(){
					document.id('mediafile-upload-status').removeClass('hide'); // we show the actual UI
					document.id('mediafile-upload-list').removeClass('hide');
					document.id('mediafile-upload-fallback').destroy(); // ... and hide the plain form
					// We relay the interactions with the overlayed flash to the link
					this.target.addEvents({
						click: function() {
							return false;
						},
						mouseenter: function() {
							this.addClass('hover');
						},
						mouseleave: function() {
							this.removeClass('hover');
							this.blur();
						},
						mousedown: function() {
							this.focus();
						}
					});
					// Notification up in the form
					up.notification = Controller.getInstance().notification;
					up.notification.element = document.id('mediafile-upload-notification');
					up.notification.options.useHtml = true;
					// Upload button
					document.id('upload').addEvent('click', function() {
						up.start(); // start upload
					});
					// Stop spinner! and begin
					document.id('mediafile-upload-form').unspin();
				},

				// Edit the following lines, it is your custom event handling
				onBeforeStart: function() {
					if (!this.fileList.length) return;
				
					var isOnStatus = document.id('status').checked;
					var targetValue = $E('#target :selected').get('value');
					var parameters = {'status': Number(isOnStatus) /* 0 | 1 */, 'target': targetValue};
					up.setOptions({data: parameters});
				
					var message = new Element('ul').adopt(
						new Element('li', {text: Vadingo.translationManager._('Uploading files…', 'fancyupload')}),
						new Element('li').adopt(
							new Element('a', {text: Vadingo.translationManager._('Cancel upload', 'fancyupload'), events: {
								click: function(){
									up.fileList.call('stop');
									this.set('text', Vadingo.translationManager._('Clear list', 'fancyupload'));
									this.removeEvents('click').addEvent('click', function(){
										up.remove();
										up.notification.clear();
									});
								}
							}})
						)
					)
					up.notification.notify(message);
					return false;
				},
				/**
				 * Is called when files were not added, "files" is an array of invalid File classes.
				 *
				 * This example creates a list of error elements directly in the file list, which
				 * hide on click.
				 */
				onSelectFail: function(files) {
					files.each(function(file) {
						new Element('li', {
							'class': 'validation-error',
							html: file.validationErrorMessage || file.validationError,
							title: Vadingo.translationManager._('Click to remove this entry.', 'fancyupload'),
							events: {
								click: function() {
									this.destroy();
								}
							}
						}).inject(this.list, 'top');
					}, this);
				},

				/**
				 * This one was directly in FancyUpload2 before, the event makes it
				 * easier for you, to add your own response handling (you probably want
				 * to send something else than JSON or different items).
				 */
				onFileSuccess: function(file, response) {
					this.log(response);
					var response = JSON.decode(response, true);
					this.redirectUri = response.meta.uri_redirect;
				
					if (response.status === AjaxCommand.Json.STATUS_CREATED) {
						file.element.addClass('file-successful');
					} else {
						// Displays the error over the element as a tooltip
						var errorsDiv = new Element('div', {'class': 'errors errors-text'});
						for (var error in response.meta.messages) {
							error = response.meta.messages[error];
							errorsDiv.adopt(new Element('p', {'class': 'error-label', text: error}));
						}
						file.element.addClass('error-group').grab(errorsDiv, 'bottom');
						file.element.addClass('file-failed');
					}
				},
			
				onComplete: function(response){
					var message = new Element('ul').adopt(
						new Element('li', {text: Vadingo.translationManager._('Upload complete', 'fancyupload')}),
						new Element('li').adopt(
							new Element('a', {text: Vadingo.translationManager._('Browse your files', 'fancyupload'), href: this.redirectUri})
						),
						new Element('li').adopt(
							new Element('a', {text: Vadingo.translationManager._('Upload more files', 'fancyupload'), events: {
								click: function(){
									up.remove();
									up.notification.clear();
								}
							}})
						)
					)
					up.notification.success(message);
				},
			
				onFileError: function(object, error, file){
					this.log(arguments);
					//up.notification.warning(Vadingo.translationManager._('Server returned HTTP-Status <code>#{code}</code>', 'fancyupload').substitute({code: file.code}));
				},

				/**
				 * onFail is called when the Flash movie got bashed by some browser plugin
				 * like Adblock or Flashblock.
				 */
				onFail: function(error) {
					var msg = '';
					switch (error) {
						case 'hidden': // works after enabling the movie and clicking refresh
							msg = 'To enable the embedded uploader, unblock it in your browser and refresh (see Adblock).';
							break;
						case 'blocked': // This no *full* fail, it works after the user clicks the button
							msg = 'To enable the embedded uploader, enable the blocked Flash movie (see Flashblock).';
							break;
						case 'empty': // Oh oh, wrong path
							msg = 'A required file was not found, please be patient and we fix this.';
							break;
						case 'flash': // no flash 9+ :(
							msg = 'To enable the embedded uploader, install the latest Adobe Flash plugin.';
					}
					document.id('mediafile-upload-form').unspin();
					SqueezeDialog.open(Vadingo.translationManager._(msg, 'fancyupload'));
				}
			});
		}.bind(this));
		
		Vadingo.translationManager.load('fancyupload', 'request');
	},
	
	initRowClick: function(){
		if (!('RowClick' in window)) throw new Error("The Class `RowClick` does not exists or has not been included.");
		
		if (document.id('events')) {
			new RowClick({
				'target': '#events',
				'relay': 'li'
			});
		}
		if ($$('.backoffice-list')) {
			new RowClick({
				'target': '.backoffice-list',
				'relay': 'li'
			});
		}
	},
	
	initRowClickDashboard: function(){
		if (!('RowClick' in window)) throw new Error("The Class `RowClick` does not exists or has not been included.");
		
		if ($$('.backoffice-list')) {
			new RowClick({
				'target': '.backoffice-list',
				'relay': 'td'
			});
		}
	},
	
	initRatesCalendar: function(){
		if (!('RatesCalendar' in window)) throw new Error("The Class `RatesCalendar` does not exists or has not been included.");
		
		new RatesCalendar().startSlider();
	},
	
	/*
	initGeolocator: function(){
		if (!('GMap' in window)) throw new Error("The Class `GMap.Geolocator` does not exists or has not been included.");
		
		new GMap.Geolocator(document.id('geolocator'), {imagesUrl: Vadingo.imagesUrl, reverseGeo: true});
	},
	*/
	
	initCalculationHelper: function(){
		if (!('CalculationHelper' in window)) throw new Error("The Object `CalculationHelper` does not exists or has not been included.");

		new CalculationHelper();
	},
	
	pinSidebar: function(){
		// var sidebar = document.id('sidebar');
		// 		sidebar.pin().setStyle('top', sidebar.getPosition().y + document.getScroll().y);
	},
	
	initSimpleSlideShow: function(){
		if (!('SimpleSlideShow' in window)) throw new Error("The Class `SimpleSlideShow` does not exists or has not been included.");
		
		var slideShow;
		
		if (slideShow = document.id('slide-show')) {
			new SimpleSlideShow(slideShow, slideShow.getElements('img'));
		}
	},
	
	initHotelTabs: function(){
		var descriptions = $H(Vadingo.languages).getKeys().map(function(identifier){
			return document.id('description-' + identifier).setStyle('display', 'none');
		});
		var descriptionLinks = $$('#hotel-description .tabs a').map(function(link, index){
			return link.addEvent('click', function(event){
				event.preventDefault();
				$$(descriptionLinks).removeClass('selected');
				this.addClass('selected');
				$$(descriptions).setStyle('display', 'none');
				document.id(link.get('href').split('#')[1]).setStyle('display', '');
			});
		});
		$E(descriptionLinks[0].get('href')).setStyle('display', '');
		descriptionLinks[0].addClass('selected');
		// ---
		var cancellations = $H(Vadingo.languages).getKeys().map(function(identifier){
			return document.id('cancellation-policy-' + identifier).setStyle('display', 'none');
		});
		var cancellationLinks = $$('#hotel-cancellation-policy .tabs a').map(function(link, index){
			return link.addEvent('click', function(event){
				event.preventDefault();
				$$(cancellationLinks).removeClass('selected');
				this.addClass('selected');
				$$(cancellations).setStyle('display', 'none');
				document.id(link.get('href').split('#')[1]).setStyle('display', '');
			});
		});
		$E(cancellationLinks[0].get('href')).setStyle('display', '');
		cancellationLinks[0].addClass('selected');
		// ---
		var payments = $H(Vadingo.languages).getKeys().map(function(identifier){
			return document.id('payment-conditions-' + identifier).setStyle('display', 'none');
		});
		var paymentsLinks = $$('#hotel-payment-conditions .tabs a').map(function(link, index){
			return link.addEvent('click', function(event){
				event.preventDefault();
				$$(paymentsLinks).removeClass('selected');
				this.addClass('selected');
				$$(payments).setStyle('display', 'none');
				document.id(link.get('href').split('#')[1]).setStyle('display', '');
			});
		});
		$E(paymentsLinks[0].get('href')).setStyle('display', '');
		paymentsLinks[0].addClass('selected');
	},
	
	initGeoLookup: function(){	
		if (!('Autocompleter' in window)) throw new Error("The Class `Autocompleter` does not exists or has not been included.");
		
		Autocompleter.Ajax.GeoCityTown = new Class({
			
			Extends: Autocompleter.Ajax.Base,
			
			initialize: function(el, url, options) {
				this.parent(el, options);
				this.request = new Request.JSON.Advanced($merge({
					'url': url,
					'link': 'cancel',
					'method': 'get'
				}, this.options.ajaxOptions)).addEvent('onComplete', this.queryResponse.bind(this));
			},

			queryResponse: function(response) {
				this.parent();
				this.fireEvent('onRequestComplete');
				var data = [];
				if (response) {
					this.options.responseLookup = response.data;
					$H(response.data).each(function(i){
						data.push(i);
					});
				}
				this.update(data);
			},
			
			choiceSelect: function(choice) {
				if (choice) this.choiceOver(choice);
				this.setSelection(true);
				this.queryValue = false;
				this.hideChoices();

				var results = $H(this.options.responseLookup).filter(function(item, key) {
					return (item === choice.get('text'));
				}).getKeys();
				
				this.fireEvent('onSelected', [results]);
			}
		});
		
		var update = function(){
			document.id('geoloc-progress').setStyle('display','none');
			if (document.id('cancel_citytown')) {
				document.id('cancel_citytown').set('src', '/assets/images/country_background_button.png');
				document.id('cancel_citytown').removeEvents('mouseenter').addEvent('mouseenter', function(e) {
					this.set('src', '/assets/images/country_background_button_ro.png');
				});
				document.id('cancel_citytown').removeEvents('mouseleave').addEvent('mouseleave', function(e) {
					this.set('src', '/assets/images/country_background_button.png');
				});
				document.id('cancel_citytown').removeEvents('mousedown').addEvent('mousedown', function(e) {
					document.id('citytown_input').setStyle('display','block');
					document.id('selected_citytown').setStyle('display','none');
				});
			}
		};
		update();
		
		var citytown_handler = function() {
			if (document.id('citytown_input')) {
				var input, url = '/geo-location/search/citytowns?region='+document.id('region').get('value');
				
				if (input = $E('#citytown_input')) {
					new Autocompleter.Ajax.GeoCityTown(input, url, {
						'multiple': true,
						'selectFirst': true,
						'selectMode': 'type-ahead',
						'minLength': 2,
						'cache': true,
						'delay': 1000,
						'multiple': false,
						'selectFirst': true,
						'listenerOptions': {
							'onFired': function(){
								document.id('geoloc-progress').setStyle('display','block');
							}
						},
						'onRequestComplete': update,
						'onSelected': function(citytown_ids) {
							//console.log(citytown_ids);
							document.id('citytown_id').set('value', citytown_ids[0]|'');
							document.id('citytown_input').setStyle('display','none');
							//console.log(this.options.responseLookup[citytown_ids[0]]);
							document.id('selected_citytown').getElement('span').set('html', this.options.responseLookup[citytown_ids[0]]);
							document.id('selected_citytown').setStyle('display','block');
						}
					});
				}
			}
		}
		
		var region_handler = function() {
			if (document.id('region')) {
				var region_ajax = new Request.HTML({
					'url': '/geo-location/find-citytowns',
					'method': 'get',
					'link': 'cancel',
					'onSuccess': function(resp){
						document.id('citytown_div').empty();
						document.id('citytown_div').setStyle('display','block');
						document.id('citytown_div').adopt(resp);
						
						if (document.id('geoloc-progress')) {
							document.id('geoloc-progress').setStyle('display','none');
						}
						
						citytown_handler();
					}
				});

				document.id('region').addEvent('change', function(e) {
					region_ajax.get({'region':document.id('region').get('value')});
					if (document.id('geoloc-progress')) {
						document.id('geoloc-progress').setStyle('display','block');
					}
				});
			}
		}
	
		if (document.id('country')) {
			var country_ajax = new Request.HTML({
				'url': '/geo-location/find-regions',
				'method': 'get',
				'link': 'cancel',
				'onSuccess': function(resp){
					document.id('region_div').empty();
					document.id('region_div').setStyle('display','block');
					document.id('region_div').adopt(resp);
					
					if (document.id('geoloc-progress')) {
						document.id('geoloc-progress').setStyle('display','none');
					}
					
					region_handler();
				}
			});
			
			document.id('country').addEvent('change', function(e) {
				document.id('region_div').setStyle('display','none');
				document.id('citytown_div').setStyle('display','none');
				
				country_ajax.get({'country':document.id('country').get('value')});
				if (document.id('geoloc-progress')) {
					document.id('geoloc-progress').setStyle('display','block');
				}
			});
		}
		
		if (document.id('region')) {
			region_handler(); // load region events/request if already exists
		}
		
		if (document.id('citytown_input')) {
			citytown_handler(); // load region events/request if already exists
			if (document.id('citytown_input').value != '') {
				document.id('selected_citytown_text').set('text', document.id('citytown_input').value);
				document.id('selected_citytown').setStyle('display', 'block');
				document.id('citytown_input').setStyle('display', 'none');
			}
		}
	},
	
	initNameSearchAutocompleter: function(){
		if (!(input = $('hotel_name'))) return;
		
		var hotelNameInput = new Element('input', {'name': 'hotel_id', type: 'hidden'}).inject($pick($('search-form'), $('search-form-wide')), 'top');
		
		Meio.Element.List.append(new Storage);
		var listInstance = new Meio.Element.List();

		var autocomplete = new Meio.Autocomplete(input, 'search/hotels', {
		    delay: 200,
		    minChars: 2,
		    cacheLength: 10,
		    cacheType: 'own',
		    selectOnTab: true,
		    maxVisibleItems: 10, 
		    onNoItemToList: function(elements){
				elements.field.node.addClass('error-input');
				hotelNameInput.set('value', '');
			},
		    onSelect: function(elements, text, data, index){
				elements.field.node.removeClass('error-input');
				hotelNameInput.set('value', listInstance.retrieve(index+'.'+text));
			},
		    fieldOptions: { 
				classes: { 
 		            loading: 'loading',
 		            selected: 'ma-selected'
 		        }
 		    }, 
		    requestOptions: { 
		        formatResponse: function(jsonResponse){
					return (jsonResponse.status && jsonResponse.status === AjaxCommand.Json.STATUS_SUCCESS && $defined(jsonResponse.data))
						? jsonResponse.data.map(function(hotel, index){
							listInstance.store(index+'.'+hotel.name, hotel.hotel_id);
							return hotel.name;
						}) 
						: [];
				},
		        noCache: true, 
				link: 'cancel'
		    }
		}, 
		    listInstance
		);
	},
	
	initSearchAutocompleter: function() {
		if (!(input = $E('#destination-citytown input'))) return;
		
		/* newfix */  return null;
		
		var getCountry;
		var minChars = 1;
		var inputValue = '';
		var listener = new Listener($('country')
			.addEvent('change', function(){
				return getCountry = function(){ return $F(this); }.bind(this);
			}), function(value){
				if((inputValue = $F(input)).length >= minChars) {
					//autocomplete.data.prepare(inputValue);
					autocomplete.forceSetupList(inputValue);
					autocomplete.elements.field.fireEvent('focus');
					$('ds').set('value', '');
				}
				return getCountry = function(){ return value; };
			}, {
				periodical: 200, delay: 50
			}
		).changed(true);
		
		Meio.Element.List.append(new Storage);
		var listInstance = new Meio.Element.List();
		
		var autocomplete = new Meio.Autocomplete(input, 'geo-location/resolve', {
		    delay: 200,             // The delay before rendering the list of options. Usefull when you are using the autocomplete with ajax 
		    minChars: minChars,            // The minimum number of characters the user has to input before the list of options to select is shown. 
		    cacheLength: 30,        // The cache length. Cache will decrease the number of ajax calls. Each time you make a different query it will be cached locally. 
		    cacheType: 'own',    // 'shared' or 'own'. The cache instance can be shared with other Meio.Autocomplete instances or this instance can have its own cache. 
		    selectOnTab: true,      // If the user press the 'tab' key, the current focused option will be selected. 
		    maxVisibleItems: 15,    // Defines the height of the list. If its 10 the list will have its height adjusted to show 10 options, but you can scroll to the other of course. 
		    onNoItemToList: function(elements){ // this event is fired when theres no option to list 
				$('ds').set('value', '');
				elements.field.node.addClass('error-input');
			},
		    onSelect: function(elements, value, text, i){ // this event is fired when you select an option
				var bits = listInstance.retrieve(value).split('_');
				$$('#citytown_id, #region_id').set('value', '');
				$(bits[0]+'_id').set('value', bits[1]);
				$('ds').set('value', '1');
				elements.field.node.removeClass('error-input');
			},
		    onDeselect: function(elements){ // this event is fired when you deselect an option 
				$('ds').set('value', '');
			},
		    filter: {
				filter: function(text, data){
					return text ? data.test(new RegExp(text.escapeRegExp(), 'i')) || data.toAsciiChars().test(new RegExp(text.escapeRegExp(), 'i')) : true;
				}
		        /*
		            its posible to pass the filters directly or by passing a type and optionaly a path.
		            filter: function(text, data){}          // filters the data array
		            formatMatch: function(text, data, i){}  // this function should return the text value of the data element
		            formatItem: function(text, data){}      // the return of this function will be applied to the 'html' of the li's
		            or
		            type: 'startswith' or 'contains' // can be any defined on the Meio.Autocomplete.Filter object
		            path: 'a.b.c' // path to the text value on each object thats contained on the data array
		        */ 
		    }, 
		    fieldOptions: { 
				classes: { 
 		            loading: 'loading',  // applied to the field when theres an ajax call being made 
 		            selected: 'ma-selected' // applied to the field when theres a selected value 
 		        }
 		    }, 
		    requestOptions: { 
		        formatResponse: function(jsonResponse){ // this function should return the array of autocomplete data from your jsonResponse
					if (jsonResponse && jsonResponse.status === AjaxCommand.Json.STATUS_SUCCESS) {
						var data, asciiMatch, tokens = new Array(0);
						if (data = jsonResponse.data) {
							//listInstance.empty();
							data.exactMatches.each(function(match){
								if ($defined(match.region_name)) {
									tokens.push(match.printable_name + ' ('+match.region_name+')');
									listInstance.store(match.printable_name + ' ('+match.region_name+')', 'citytown_'+match.citytown_id);
								} else {
									tokens.push(match.printable_name);
									listInstance.store(match.printable_name, 'citytown_'+match.citytown_id);
								}
							});
							data.regions.each(function(match){
								tokens.push(match.printable_name);
								listInstance.store(match.printable_name, 'region_'+match.region_id);
							});
							data.similarMatches.each(function(match){
								if ($defined(match.region_name)) {
									tokens.push(match.printable_name + ' ('+match.region_name+')');
									listInstance.store(match.printable_name + ' ('+match.region_name+')', 'citytown_'+match.citytown_id);
								} else {
									tokens.push(match.printable_name);
									listInstance.store(match.printable_name, 'citytown_'+match.citytown_id);
								}
							});
						}
						return tokens;
					}
		            return jsonResponse || []; 
		        },
		        noCache: true,  // nocache is setted by default to avoid cache problem on ie 
		        // you can pass any of the Request.JSON options here -> http://mootools.net/docs/core/Request/Request.JSON 
				link: 'cancel'
		    }, 
		    urlOptions: {
		        queryVarName: 'destination',  // the name of the variable that's going to the server with the query value inputed by the user. 
		        extraParams: [{name: 'country', value: function(){ return getCountry(); }}],  // you can pass an array of elements or objects with 'value' and 'name' keys. the value key can 'value' can be a function. 
		                            // ex: if you pass [{'name': 'x', 'value': function(){ return 2; }}] the url generated to get the list of options will have the 'x' parameter with value '2'. 
		        max: 20             // the max number of options that should be listed. This will be sent to the ajax request as the 'limit' parameter. 
		    } 
		}, 
		    listInstance // The instance of the list. Passing a Meio.Autocomplete.List will allow you to have just one list DOM element, saving resources on a heavy page. 
		);
	},
	
	initExploringDestination: function(){
		var accordionInstance, lists, togglers, ready = false;
		var accordionOptions = {
			duration: 0,
			alwaysHide: true,
			opacity: false,
			/* newfix */ trigger: '',
			onActive: function(toggler, element){
				toggler.addClass('active');
				/* newfix */ element.addClass('active');
			},
			onBackground: function(toggler, element){
				toggler.removeClass('active');
				/* newfix */ element.removeClass('active');
			}
		};
		
		var cityTown = $('citytown').setProperty('disabled', 'disabled');
		
		Controller.getInstance().ajax.getWrapper('html').setOption('method', 'get').addEvent('success', function(){
			ready = true;
			var destinationList = $('destination-list').set('html', arguments[2]);
			lists = $$('#destination-list ul');
			togglers = $$('#destination-list h3');
			var toggleList = function(event){
				event.preventDefault();
				if (ready) {
					destinationList.toggleClass('visible');
				}
			};
			cityTown.removeProperty('disabled').addEvent('focus', toggleList);
			var $check = function(countryISO){
				var activeTogglerIndex;
				togglers.each(function(el, index){
					if (el.id === ('toggler-'+countryISO)) {
						activeTogglerIndex = index;
					}
				});
				return nil(activeTogglerIndex);
			};
			accordionInstance = new Fx.Accordion(
				togglers.addClass('toggler'),
				lists.addClass('element'),
				$extend(accordionOptions, { show: $check($F($('country'))) })
			);
			lists.addEvent('click:relay(a)', function(event){
				event.preventDefault();
				var attr = this.get('rel').split('_');
				$$('#citytown_id, #region_id').set('value', '');
				$(attr[0]+'_id').set('value', attr[1]);
				cityTown.set('value', this.get('text').replace(/\s?(\(.*\))?\s?(\d+)?$/, '')/*removes the brackets and its content=region*/).focus();
				cityTown.removeClass('error-input');
				$('ds').set('value', '1');
				$('country').set('value', attr[2]).fireEvent('change');
				cityTown.blur();
			});
			$('destination-citytown').addClass('explore').getElement('a').addEvent('click', toggleList);
			// cityTown.addEvent('focus', function(){
			// 				$('destination-list').removeClass('visible');
			// 			});
			$('country').addEvent('change', function(){
				accordionInstance.display.run([$check($F($('country'))), true], accordionInstance);
			});
		}).execute('geo-location/active-destinations');
	},
	
	initLocalizedDestination: function(){
		if (!('ListColumnator' in window)) throw new Error("The Class `ListColumnator` does not exists or has not been included.");
		
		var accordionInstance, lists, togglers, ready = false;
		var accordionOptions = {
			duration: 0,
			alwaysHide: true,
			opacity: false,
			trigger: '',
			onActive: function(toggler, element){
				toggler.addClass('active');
				element.addClass('active');
			},
			onBackground: function(toggler, element){
				toggler.removeClass('active');
				element.removeClass('active');
			}
		};
		
		var cityTown = $('citytown');
		var selectedIndexText = cityTown.selectedIndex ? cityTown.getElements('optgroup option')[cityTown.selectedIndex - 1].get('text') : cityTown.getFirst().get('text');
		var destinations = cityTown.getElements('optgroup').dispose();
		var destinationList = $('destination-list');
		
		destinations.each(function(optgroup){
			var items = optgroup.getChildren().map(function(item, i){
				return new Element('li').adopt(
					new Element('a', {href: '#', rel: item.get('rel') + '_' +item.get('value')})
					.adopt(
						new Element('strong', {'class': (item.get('rel') == 'region') ? 'b' : '', html: item.get('text').replace(/\,\s?(\d+)H/, function($0, $1){ return '<span>'+$1+'</span>' })})
						)
					);
			});
			destinationList.getElement('div').adopt(
				new Element('h3', {text: optgroup.get('label'), id: 'toggler-'+optgroup.get('rel')}),
				new Element('ul', {'id': optgroup.get('rel')}).adopt(items)
			);
			ready = true;
		});
		
		destinationList.getElements('ul').each(function(el){
			el.store('columnator', new ListColumnator(el, {columns: 3, style: 'vertical'}));
		});
		
		lists = $$('#destination-list div.columnator');
		togglers = $$('#destination-list h3');
		var $check = function(regionId){
			var activeTogglerIndex;
			togglers.each(function(el, index){
				if (el.id === ('toggler-'+regionId)) {
					activeTogglerIndex = index;
				}
			});
			return nil(activeTogglerIndex);
		};
		
		accordionInstance = new Fx.Accordion(
			togglers.addClass('toggler'),
			lists.addClass('element'),
			$extend(accordionOptions, { show: $check($F($('region'))) })
		);
		
		lists.setStyle('overflow', '');
		
		$('region').addEvent('change', function(){
			accordionInstance.display.run([$check($F(this)), true], accordionInstance);
		});
		
		var toggleList = function(event){
			event.preventDefault();
			if (ready) {
				destinationList.toggleClass('visible');
			}
		};
		$('destination-citytown').addClass('explore');
		cityTown.getFirst().set('text', selectedIndexText.replace(/\,\s?(\d+)H/, ''));
		cityTown.setStyle('cursor', 'pointer').addEvent('mousedown', toggleList);
		if (Browser.Engine.webkit) cityTown.addEvents({'focus': toggleList, 'blur': toggleList});
		$E('span.close').addEvent('click', function(){ destinationList.removeClass('visible'); });
		
		var onClickDestination = function(event){
			if(event && event.stop) {
				event.stop();
				destinationList.removeClass('visible');
			}
			var attr = this.get('rel').split('_');
			$$('#citytown_id, #region_id').set('value', '');
			$(attr[0]+'_id').set('value', attr[1]);
			cityTown.getFirst().set('text', this.get('text').replace(/\s?(\d+)/, ''));
		};
		lists.addEvent('click:relay(a)', onClickDestination);
		
		$$('#citytown, #region').removeProperty('name');
		
		new Element('input', {type: 'hidden', 'name': 'citytown_id', id: 'citytown_id'}).injectAfter(destinationList);
		new Element('input', {type: 'hidden', 'name': 'region_id', id: 'region_id', value: $('region').get('value')}).injectAfter(destinationList);
		
		// Snippet for Balearics ...
		(function(){
			$('region').addEvent('change', function(){
				var item = destinationList.getElement('a[rel="region_'+this.get('value')+'"]');
				onClickDestination.bindWithEvent(item)();
			});
		})();
	},
	
	initFixedSuitcase: function(){
		// THIS IS DIRTY BUT FAST; basic operations proves to be faster than native prototypes accessor
		// This is specially true in IE's engine, where onScroll event messes things up pretty much.
		var suitcase;
		var topper = 20;
		var correction = 15;
		var scroll, limited = false;
		if (suitcase = document.id('drop-zone-wrap')) {
			suitcase.setStyles({
				right: 0,
				top: 0,
				position: 'absolute'
			});
			// Set a minimum height to hold the search results in case there's only 1 row, since the suitcase was taller
			var size = suitcase.getSize();
			var pos = suitcase.getCoordinates();
			if (resultsDiv = suitcase.getParent().getPrevious()) {
				resultsDiv.setStyle('min-height', size.y);
			}
			// Set event to move the suitcase down when the top search box is displayed.
			var limitTop = suitcase.getPosition().y;
			var originalTop = limitTop;
			var contentHeight = window.getScrollSize().y - document.id('footer').getSize().y;
			var originalHeight = contentHeight;
			// Updater from the search toggler, height changes by 280 so we update measures.
			Vadingo.methods['initFixedSuitcase'].update = function(){
				var height = document.id('search').getStyle('height').toInt();
				limitTop = (!height) ? originalTop : (limitTop + 280);
				contentHeight = (!height) ? originalHeight : (contentHeight + 280);
			};
			// This method takes care of switching positions fixed and absolute for convenience
			// without reliying in any scroll or position document.body accessors.
			var doScrollUpdate = function(){
				scroll = Window.getScroll().y;
				if ((scroll + topper) > limitTop) {
					if ((scroll + topper + correction + 35) > (contentHeight - size.y - correction)) {
						if (limited) return;
						suitcase.setStyles({'position': 'absolute', 'top': originalHeight - size.y - pos.top - correction - topper - 25, 'right': 0, 'margin-left': ''});
						limited = true;
					} else {
						limited = false;
						suitcase.setStyles({'position': 'fixed', 'right': '', 'margin-left': 20, 'top': topper + correction});
					}
				} else {
					suitcase.setStyles({'position': 'absolute', 'top': 0, 'right': 0,'margin-left': ''});
				}
			}.bind(this);
			
			window.addEvent('scroll', doScrollUpdate);
		}
	},
	
	initCountryList: function(){
		var doInput = function() {
			if ($$("select[name='citytown_id']").get('value') == 'other') {
				if (!$$("input[name='contact[city]']").length) {
					var input = new Element('input', {
						type: 'text',
						id: 'contact[city]',
						name: 'contact[city]',
						maxlength: 255
					});
				
					$$("select[name='citytown_id']").getParent().grab(input);	
				}
			} else {
				$$("input[name='contact[city]']").destroy();
			}
		}
		doInput();
		
		if (!$$('.country-list').length) return false;
		
		if ($$("input[name='contact[city]']").get('value') == '') {
			$$("input[name='contact[city]']").destroy();
		}
		
		$$("select[name='citytown_id']").addEvent('change', function(event) {
			doInput();
		});
	},
	
	initEnquiryAtLimit: function(){
		// If Drag and Drop is in the array of the controller's execution
		if (Controller.getInstance().methods.contains('initListingDragAndDrop')) {
			var flashMessage = $E('.warning').dispose();
			
			$E('.dropzone').addEvent('drop', function(){
				SqueezeDialog.open(flashMessage.get('text'));
			}, true);
		}
	},

	/* FIXME */
	initPrintPage: function(){
		$$('.print-page').addEvent('click', function(event){
			event.preventDefault();
			window.print();
		});
	},
	
	initScrollFragment: function(){
		if (el = document.id('element-row-' + new URI(location.href).getData('highlight'))) {
			new Fx.Scroll(window).toElement(el);
		}
	},
	
	initMasonry: function(){
		if (!('MasonryClass' in window)) throw new Error("The Class `MasonryClass` does not exists or has not been included.");
		
		// document.id('specs-box-wrap').masonry({
		// 		    itemSelector: '.span-7'
		// 		});
	},

	initModalDialog: function(){
		if (!('SqueezeDialog' in window)) throw new Error("The Class `SqueezeDialog` does not exists or has not been included.");
		// Assign SqueezeDialog to all links with rel="dialog" attribute.
		// The class then reads the "text or value" for <a> and <form> elements respectively.
		$$('[rel*=dialog]').each(function(el){
			var width = SqueezeDialog.presets.size.x,
				height = SqueezeDialog.presets.size.y,
				bits;
			if (bits = new RegExp(/^dialog(?:\[(.*)\])?$/).exec(el.get('rel'))) {
				if (bits[1]) {
					bits = bits[1].split(',');
					width = bits[0];
					height = bits[1];
				}
			} else if (bits = new RegExp(/^dialog(?:\:(.+))?$/).exec(el.get('rel'))) {
				return el.addEvent('click', function(event){
					event.preventDefault();
					SqueezeDialog.open({
						msg: bits[1],
						fn: function(){
							if (newLoc = el.get('href')) location.href = newLoc;
							else if (el.form) el.removeEvents('click').click();
						}
					},{
						size: {x: width, y: height},
						handler: 'confirm'
					});
				});
			}
			el.addEvent('click', function(event){
				event.preventDefault();
				SqueezeDialog.open({
					msg: this.get('text') || el.get('value'),
					fn: function(){
						if (newLoc = el.get('href')) location.href = newLoc;
						else if (el.form) el.removeEvents('click').click();
					}
				},{
					size: {x: width, y: height},
					handler: 'confirm'
				});
			});
		});
	},
	
	initSqueezeBox: function(){
		if (!('SqueezeBox' in window)) throw new Error("The Class `SqueezeBox` does not exists or has not been included.");
		// Assign SqueezeBox to all links with rel="boxed" attribute, the class then reads the "href".
		$$('a[rel*=boxed]').each(function(el){
			var width = SqueezeBox.presets.size.x,
				height = SqueezeBox.presets.size.y,
				bits;
			if (bits = new RegExp(/^boxed(?:\[(.*)\])?$/).exec(el.get('rel'))) {
				if (bits[1]) {
					bits = bits[1].split(',');
					width = bits[0];
					height = bits[1];
				}
			}
			SqueezeBox.assign(el, {
				overlayOpacity: 0.65,
				size: {x: width, y: height},
				errorMsg: Vadingo.translationManager._('A technical error occurred. Please, try again in a few moments.', 'application'),
				onUpdate: function(){ if(!Browser.Engine.trident) Vadingo.methods['initCufon']('#sbox-window'); }
			});
		});
	},
	
	initIPhoneCheckboxes: function(){
		if (!('IPhoneCheckbox' in window)) throw new Error("The Class `IPhoneCheckbox` does not exists or has not been included.");
		
		new IPhoneCheckbox({elements: 'input[type=checkbox].icheckbox'});
	},
	
	initAmenities: function(){
		var fragment,
			options = {
				duration: 350,
				alwaysHide: true,
				onActive: function(toggler){
					toggler.addClass('active');
				},
				onBackground: function(toggler){
					toggler.removeClass('active');
				}
			};
		if (fragment = new URI(location.href).get('fragment')) {
			options = $merge({display: (fragment == 'generic') ? 0 : 1}, options);
		} else {
			//options = $merge({show: true});
		}
		
		new Fx.Accordion($$('.toggler'), $$('.element'), options);
	},
	
	initAmenitiesAdd: function(){
		var xhr = this.ajax.getWrapper('json'),
			form = document.id('amenities-custom-add').getElement('form'),
			E = '';
		form.set('spinner', {message: Vadingo.translationManager._('One moment…', 'application')});
		form.addEvent('submit', function(event){
			event.preventDefault();
			this.spin();
			ValidationErrors.assign(this).reset();
			xhr.addEvent('success', function(json){
				if ($chk(json) && json.status === AjaxCommand.Json.STATUS_CREATED) {
					document.id(json.data.category).getElement('ul').grab(
						new Element('li').adopt(
							new Element('label', {'for': json.data.cfeature.id}).adopt(
								new Element('input', {'type': 'checkbox','checked': 'checked', 'id': json.data.cfeature.id, 'name': json.data.cfeature.name, 'value': json.data.cfeature.value}),
								document.newTextNode(json.data.cfeature.text)
							)
						)
					);
				}
			}).addEvent('complete', function(){
				form.unspin();
			}).addEvent('failure', function(json){
				if ($chk(json) && json.status === AjaxCommand.Json.STATUS_VALIDATION_ERROR){
					var select = elements = null;
					for (var msg in json.meta.messages) {
						if (select = form.getElement('select[name='+msg+']')) {
							ValidationErrors.set(select, json.meta.messages[msg]);
						} else if(elements = form.getElements('input[name]')) {
							msg = json.meta.messages[msg];
							break;
						}
					}
					if($chk(elements)){
						elements.each(function(el){
							if (el.get('value') == E) {
								ValidationErrors.set(el, [msg]);
							}
						});
					}
				}
			}).execute(new URI(this.get('action')).toRelative(), this);
		})
	},
	
	initTimeframe: function(){
		if (!('Timeframe' in window)) throw new Error("The Class `Timeframe` does not exists or has not been included.");
		
		Date.defineParser('%d/%m/%Y');
		
		var start = Date.parse(document.id('offer-startdate-customer').get('value'));
		var end = Date.parse(document.id('offer-enddate-customer').get('value'));
		var rangeDiff, minNights = start.diff(end) / 2;
		
		new Timeframe('calendars-1', {
	        startField: document.id('offer-1-start'),
	        endField: document.id('offer-1-end'),
	        resetButton: 'reset-1',
			earliest: start.decrement('week', 1),
			latest: end.increment('week', 1)// ,
			// 			onUpdate: function(){
			// 				return;
			// 				rangeDiff = this.range.get('start').diff(this.range.get('end'));
			// 				if (rangeDiff < (Number.max((minNights).ceil(), minNights))) {
			// 					document.id('number-nights-1').getElement('span').set('text', rangeDiff);
			// 				}
			// 			}
		});
		
		start = Date.parse(document.id('offer-startdate-customer').get('value'));
		end = Date.parse(document.id('offer-enddate-customer').get('value'));
		
		new Timeframe('calendars-2', {
	        startField: document.id('offer-2-start'),
	        endField: document.id('offer-2-end'),
	        resetButton: 'reset-2',
			earliest: start.decrement('week', 1),
			latest: end.increment('week', 1)
		});
	},
	
	initDynamicTextarea: function(){
		if (!('DynamicTextarea' in window)) throw new Error("The Class `DynamicTextarea` does not exists or has not been included.");
		
		$$('textarea.dynamic').each(function(el){
			new DynamicTextarea(el,{
		    	minRows: 1,
		    	maxLength: (el.getProperty('maxlength') > 0) ? el.getProperty('maxlength') : Infinity
			});
		});
	},
	
	initCountdown: function(){
		if (!('CountDown' in window)) throw new Error("The Class `CountDown` does not exists or has not been included.");
		
		var time = ms = 0;
		$$('.countdown span').each(function(el){
			time = el.get('text').split(':');
			ms = new Date(+new Date() + /*hr*/time[0]*3600000 + /*min*/time[1]*60000 + /*sec*/time[2]*1000);
			el.store('countdown', new CountDown({
				date: ms,
				frequency: 100, 
				onChange: function(counter) {
					var text = '';
					counter.hours = Math.floor(counter.millis / 3600000);
					text += (counter.hours >= 10 ? '' : '0') + counter.hours + ':';
					text += (counter.minutes >= 10 ? '' : '0') + counter.minutes + ':';
					text += (counter.second >= 10 ? '' : '0') + counter.second;
					el.set('text', text);
				}
			}));
		});
	},
	
	initPanchoAndSasha: function(){
		Element.Events.addKeySequence('catzcode', 'c a t s'.split(' '));
		document.addEvent('catzcode', function() { SqueezeBox.open(Vadingo.imagesUrl + 'team/pancho-and-sasha.jpg'); });
	},

	initSlideHotellist: function(){
		
		var status = 'closed'
		
		if ($('hotel-list') && $('home')) {
			var mySlide = new Fx.Slide('hotel-list', {
				transition: 'sine:in',
				duration: 1000
				}).toggle();
			
			
			$('hotel-list-trigger').addEvent('click', function(e){
			 e = new Event(e);
			 mySlide.toggle();
			 e.stop();
			});
		}
	},
	
	
	
	initTwitterGitter: function() {
		if (!('TwitterGitter' in window)) throw new Error("The Class `TwitterGitter` does not exists or has not been included.");
		
		new TwitterGitter('vadingo', {
			count: 1,
			onComplete: function(tweets,user) {
				tweets.each(function(tweet,i) {
					$('twitter-wrapper').set('html','');
					/*new Element('div',{
						html: '<img src="' + user.profile_image_url.replace("\\",'') + '" align="left" alt="' + user.name + '" /> <strong>' + user.name + '</strong><br />' + tweet.text + '<br /><span>' + tweet.created_at + ' via ' + tweet.source.replace("\\",'') + '</span>',
						'class': 'tweet clear'
					}).inject('twitter_wrapper');*/
					new Element('div', {
						'html': '<p class="text"><a class="large" href="http://twitter.com/vadingo" title="Twitter" style="color:#000; font-weight:bold;">Twitter</a><br />'+tweet.text+'</p>',
						'class': 'tweet clear'
					}).inject('twitter-wrapper');
				});
			}
		}).retrieve();
	}
};

})(this, document.id || $);

// Domready event, Site.js main initialization.
window.addEvent('domready', function(){

	var frontController = Controller.getInstance();
	
	frontController.dispatch(); // Initialize the Front Controller.
	
	frontController.translationManager.load('application');

});
