
	vp.publicURL = null;
	
	function vp ( publicURL )
	{
		vp.publicURL = publicURL;
	};
	
	/******************** gallery ********************/
	
	vp.gallery = function ( detailPath, leftPath, rightPath, thumbnailsPath )
	{
		this.detailImg			= $(detailPath);
		this.currentPosition	= 1;
		this.thumbs				= $(thumbnailsPath + ' a' );
		
		this.bindControls ( $(leftPath), $(rightPath) );
		
		var self	= this,
			counter = 1;
		
		this.thumbs.each ( function ( index, element ) {
			$(element).click ( ( function ( counter ) { return function ( e ) {
				e.preventDefault();
				self.displayDetail ( $(this) );
				self.currentPosition = counter;
				}; } ) ( counter++ ) );
			} );
	};
	
	vp.gallery.prototype.bindControls = function ( leftControl, rightControl )
	{
		var self = this;
		leftControl.click ( function ( e ) { e.preventDefault(); self.displayRelativePosition ( -1 ); } );
		rightControl.click ( function ( e ) { e.preventDefault(); self.displayRelativePosition ( 1 ); } );
	};
	
	vp.gallery.prototype.displayDetail = function ( aEl )
	{
		this.detailImg.attr ( {
			src:	aEl.attr ( 'href' ),
			alt:	aEl.attr ( 'title' ),
			title:	aEl.attr ( 'title' )
			} );
	};
	
	vp.gallery.prototype.displayRelativePosition = function ( relative )
	{
		this.currentPosition += relative;
		
		if ( this.currentPosition == 0 )
			this.currentPosition = this.thumbs.length;
		else if ( this.currentPosition > this.thumbs.length )
			this.currentPosition = 1;

		this.displayDetail( $(this.thumbs.get(this.currentPosition - 1 ) ) );
	};
	
	/*********************** google map ***********************/
	
	vp.map = function ( mapPath, iconType, lat, lng, infoName, infoDescription )
	{
		var defaultZoom = 16;
		
		if ( ( this.canvas = vp.map.initMap ( mapPath, defaultZoom, lat, lng ) ) == null )
			return;
		
		this.infoWindow = new google.maps.InfoWindow();

		this.addPoint ( iconType, lat, lng, infoName, infoDescription );
	};
	
	vp.map.initMap = function ( mapPath, zoomLevel, lat, lng )
	{
		var mapEl = $(mapPath).get(0);
		if ( ! mapEl )
			return null;
		
		return new google.maps.Map (
			mapEl,
			{
				zoom:			zoomLevel,
				center:			new google.maps.LatLng ( lat, lng ),
				mapTypeId:		google.maps.MapTypeId.ROADMAP,
				scrollwheel:	false
			} );
	};

	vp.map.icons = new Object();
	
	vp.map.createIcon = function ( type )
	{
		if ( ! vp.map.icons [ type ] )
		{
			var icon;
			
			if ( type == 'shadow' )
				icon = new google.maps.MarkerImage (
					this.getIconURL ( 'shadow' ),
					new google.maps.Size ( 52, 29 ),
					new google.maps.Point ( 0, 0 ),
					new google.maps.Point ( 12, 30 )
					);
			else
				icon = new google.maps.MarkerImage (
					this.getIconURL ( type ),
					new google.maps.Size ( 21, 31 ),
					new google.maps.Point ( 0, 0 ),
					new google.maps.Point ( 10, 31 )
					);
			
			vp.map.icons [ type ] = icon;
		}
		
		return vp.map.icons [ type ];
	};
	
	vp.map.getIconURL = function ( type )
	{
		return vp.publicURL + 'img/googleMarker-' + type + '.png';
	};
	
	vp.map.prototype.addPoint = function ( type, lat, lng, name, description )
	{
		var marker = new google.maps.Marker ( {
				icon:		vp.map.createIcon ( type ),
				shadow:		vp.map.createIcon ( 'shadow' ),
				map:		this.canvas,
				position:	new google.maps.LatLng ( lat, lng )
				} );
		
		var contentInner,
			content = $('<div></div>')
			. append ( contentInner = $('<div class="googleMapWindow"></div>')
					.append( $('<h3>').text(name) )
					);
		
		if ( description != undefined )
			contentInner.append ( $('<p>').text ( description ) );
		
		var self = this;
		google.maps.event.addListener (
			marker,
			'click',
			function() { self.showInfo( marker, content.html() ); }
			);
	};
	
	vp.map.prototype.showInfo = function ( marker, content )
	{
		this.infoWindow.close();
		this.infoWindow.setContent ( content );
		this.infoWindow.open ( this.canvas, marker );
	};

	/******************* partner links *******************/

	vp.partnerLinks = function ( mapPath, targetPath )
	{
		var target = $(targetPath);
		
		$(mapPath + ' > area')
			.mouseover ( function ( e ) { target.text ( $(this).attr('alt') ); } )
			.mouseout ( function() { target.html( '&nbsp;' ); } );
	};
	
	/******************** performance photo ********************/
	
	vp.performanceGallery = function ( picturePath, pictureDetailPath, pictureLeftControlPath, pictureRightControlPath )
	{
		this.current	= 0;
		this.details	= $(pictureDetailPath);
		
		var self	= this,
			counter	= 0;
		
		$(picturePath).each ( function ( index, element ) {
			$(element).click ( ( function ( counter ) {
				return function ( e ) { e.preventDefault(); self.displayDetail ( counter ); };
				} ) ( counter++ ) );
			} );
		
		$(pictureLeftControlPath).click ( function ( e ) { e.preventDefault(); self.displayPrevious(); } );
		$(pictureRightControlPath).click ( function ( e ) { e.preventDefault(); self.displayNext(); } );
	};

	vp.performanceGallery.prototype.displayDetail = function ( counter )
	{
		this.details.removeClass('visible');
		this.details.filter(':eq(' + counter + ')').addClass('visible');
		
		this.current = counter;
	};
	
	vp.performanceGallery.prototype.displayPrevious = function()
	{
		this.displayRelative ( -1 ); 
	};
	
	vp.performanceGallery.prototype.displayNext = function()
	{
		this.displayRelative ( 1 ); 
	};
	
	vp.performanceGallery.prototype.displayRelative = function( value )
	{
		this.current += value;
		
		if ( this.current < 0 )
			this.current = this.details.length - 1;
		else if ( this.current >= this.details.length )
			this.current = 0;
		
		this.displayDetail ( this.current );
	};

	/*********************** hotel search date & hotel search ***********************/
	
	var currentDate;

	vp.hotelSearchDate = function ( inputID, urlToCalendar, popupTitle, minDate, maxDate )
	{
		this.minDate	= minDate;
		this.maxDate	= maxDate;
		
		daySuffix		= '_day';
		monthSuffix		= '_month';
		yearSuffix		= '_year';
		hourSuffix		= '_hour';
		minuteSuffix	= '_minute';
		calendarSuffix	= '_calendar';

		if ( ! ( this.dayEl = document.getElementById ( inputID + daySuffix ) ) )
			return;

		if ( ! ( this.monthEl = document.getElementById ( inputID + monthSuffix ) ) )
			return;
			
		if ( ! ( this.yearEl = document.getElementById ( inputID + yearSuffix ) ) )
			return;

		this.hourEl		= document.getElementById ( inputID + hourSuffix );
		this.minuteEl	= document.getElementById ( inputID + minuteSuffix );
		
		if ( ! ( this.calendarEl = document.getElementById ( inputID + calendarSuffix ) ) )
			return;

		this.dayEl.onchange		= this.createDayHandler();
		this.monthEl.onchange	= this.createMonthHandler();
		this.yearEl.onchange	= this.createYearHandler();
		this.calendarEl.href	= urlToCalendar;
		this.calendarEl.onclick	= this.createCalendarHandler( '' );
		
		this.calendarEl.style.display = 'inline';
		this.chainToObject = null;
		
		this.updateDays();
	};

	vp.hotelSearchDate.prototype.setTime = function ( epochTime )
	{
		var date = new Date( epochTime );
		
		this.dayEl.value	= date.getDate();
		this.monthEl.value	= date.getMonth() + 1;
		this.yearEl.value	= date.getFullYear();
		
		this.updateDays();
		
		if ( this.hourEl )
			this.hourEl.value = date.getHours();
		
		if ( this.minuteEl )
			this.minuteEl.value = date.getMinutes();
	};

	vp.hotelSearchDate.prototype.getTime = function()
	{
		if ( ( this.dayEl.value == '' ) || ( this.monthEl.value == '' ) || ( this.yearEl.value == '' ) )
			return null;
			
		var date = new Date();
		
		date.setDate ( this.dayEl.value );
		date.setMonth ( this.monthEl.value - 1 );
		date.setFullYear( this.yearEl.value );
		
		return date.getTime();
	};
	
	vp.hotelSearchDate.prototype.chainTo = function ( dateObject )
	{
		this.chainToObject = dateObject;
	};

	vp.hotelSearchDate.prototype.updateInChain = function()
	{
		if ( this.chainToObject != null )
			if ( this.getTime() != null )
				if ( this.chainToObject.isEmpty() || ( this.chainToObject.getTime() <= this.getTime() ) )
					this.chainToObject.setTime ( this.getTime() + 86400000 );
	};
	
	vp.hotelSearchDate.prototype.toString = function()
	{
		if ( this.dayEl.value != '' )
			if ( this.monthEl.value != '' )
				if ( this.yearEl.value != '' )
					return this.monthEl.value + '-' + this.dayEl.value + '-' + this.yearEl.value;
		
		return null;
	};
		
	vp.hotelSearchDate.prototype.onChange = function()
	{
	};
	
	vp.hotelSearchDate.prototype.isEmpty = function()
	{
		return ( this.monthEl.value == '' ) && ( this.dayEl.value == '' );
	};
	
	vp.hotelSearchDate.prototype.createDayHandler = function()
	{
		var dateObject = this;
		return function() { dateObject.onChangeDay ( this ); };
	};
	
	vp.hotelSearchDate.prototype.createMonthHandler = function()
	{
		var dateObject = this;
		return function() { dateObject.onChangeMonth ( this ); };
	};
	
	vp.hotelSearchDate.prototype.createYearHandler = function()
	{
		var dateObject = this;
		return function() { dateObject.onChangeYear ( this ); };
	};
	
	vp.hotelSearchDate.prototype.createCalendarHandler = function ( popUpTitle )
	{
		var dateObject = this;
		return function() { dateObject.openCalendarWindow ( this.href, popUpTitle ); return false; };
	};
	
	vp.hotelSearchDate.prototype.onChangeDay = function( element )
	{
		this.updateInChain();
		this.onChange();
	};
	
	vp.hotelSearchDate.prototype.onChangeMonth = function( element )
	{
		this.updateDays();
		this.updateInChain();
		this.onChange();
	};
	
	vp.hotelSearchDate.prototype.onChangeYear = function( element )
	{
		this.updateDays();
		this.updateInChain();
		this.onChange();
	};
	
	vp.hotelSearchDate.prototype.updateDays = function()
	{
		nextMonth		= ( parseInt ( this.monthEl.value ) + 1 ) % 12;
		nextMonthYear	= parseInt ( this.yearEl.value ) + ( nextMonth == 1 ? 1 : 0 );
		
		if ( isNaN ( nextMonth ) || isNaN ( nextMonthYear ) )
			daysInThisMonth = 31;
			
		else
		{
			nextMonthDate	= new Date ( nextMonthYear, nextMonth - 1, 1 );
			miliSecs		= nextMonthDate.getTime();
	
			nextMonthDate.setTime ( miliSecs - 60 * 60 * 24 );
	
			daysInThisMonth	= nextMonthDate.getDate();
		}

		var dayMin	= this.getDayByRestriction ( this.minDate, 1 );
		var dayMax	= Math.min( this.getDayByRestriction ( this.maxDate, 31 ), daysInThisMonth );
		var dayOrig	= parseInt ( this.dayEl.value );
		
		this.dayEl.options.length = 1;
		
		for ( i = dayMin; i <= dayMax; i++ )
			this.dayEl.options[i - dayMin + 1 ] = new Option ( i, i, false, false );
		
		if ( dayOrig > 0 )
			this.dayEl.value = Math.min ( Math.max ( dayOrig, dayMin ), dayMax );
	};
	
	vp.hotelSearchDate.prototype.getDayByRestriction = function ( timestamp, defaultReturn )
	{
		if ( timestamp != undefined )
		{
			var date = new Date ( timestamp * 1000 );
			
			if ( ( date.getMonth() == parseInt ( this.monthEl.value ) - 1 ) && ( date.getFullYear() == parseInt ( this.yearEl.value ) ) )
				return date.getDate();
		}
		
		return defaultReturn;
	};
	
	vp.hotelSearchDate.prototype.openCalendarWindow = function ( urlToCalendar, popupTitle )
	{
		urlParams = '';
			
		if ( ( this.monthEl.value != '' ) && ( this.yearEl.value != '' ) && ( this.dayEl.value != '' ) )
			urlParams = '&selectedDate=' + escape( this.yearEl.value ) + '-' + escape ( this.monthEl.value ) + '-' + escape ( this.dayEl.value );
		
		if ( this.minDate != undefined )
			urlParams += '&minDate=' + this.minDate;
	
		if ( this.maxDate != undefined )
			urlParams += '&maxDate=' + this.maxDate;
		
		var w = 300;
		var h = 260;
		
		var l = (screen.width) ? ( screen.width - w ) / 2 : 0;
		var t = (screen.height) ? ( screen.height - h ) / 2 : 0;
	
		var win = window.open(
			urlToCalendar + urlParams,
			popupTitle,
			'toolbar=0,location=0,directories=0,status=1,menubar=0,scrollbars=0,resizable=1,width=' + w + ',height=' + h + ',top=' + t + ',left=' + l
			);
	

		currentDate = this;			
		
		win.onblur = win.close;
		return true;
	};

	vp.hotelSearchDate.prototype.setValuesWithoutOnChange = function ( day, month, year )
	{
		this.dayEl.value	= day;
		this.monthEl.value	= month;
		this.yearEl.value	= year;
		
		if ( this.hourEl )
			this.hourEl.value = 0;
		
		if ( this.minuteEl )
			this.minuteEl.value = 0;
	};
	
	vp.hotelSearchDate.prototype.setValues = function ( day, month, year )
	{
		this.setValuesWithoutOnChange( day, month, year);
		this.onChange();
	};
	
	vp.hotelSearchDate.prototype.takeReturnValue = function ( day, month, year )
	{
		currentDate.setValuesWithoutOnChange ( day, month, year );
		currentDate.updateInChain();
		currentDate.onChange();
	};
	
	//------------------------- hotel search update counts ----------------------------//
	
	vp.hotelSearchUpdateCounts = function ( updateURL, checkInobj, checkOutobj,
		categoryID, roomSizeID, areaID, onlineOnlyID, countsID )
	{
		if ( ! ( this.categoryEl = document.getElementById ( categoryID ) ) )
			return;
		
		if ( ! ( this.roomSizeEl = document.getElementById ( roomSizeID ) ) )
			return;
		
		if ( ! ( this.areaEl = document.getElementById ( areaID ) ) )
			return;
		
		if ( ! ( this.countEl = document.getElementById ( countsID ) ) )
			return;

		if ( onlineOnlyID != null )
			this.onlineOnlyID = document.getElementById ( onlineOnlyID );
					
		this.updateURL	= updateURL;
		this.xmlHttp	= null;

		sendHandler = this.createSendHandler();
		
		this.categoryEl.onchange	= sendHandler;
		this.roomSizeEl.onchange	= sendHandler;
		this.areaEl.onchange		= sendHandler;
		
		this.checkIn	= checkInobj;
		this.checkOut	= checkOutobj;
		
		if ( this.onlineOnlyID != undefined )
			this.onlineOnlyID.onchange = sendHandler;
			
		this.bindDateObject ( checkInobj, sendHandler );
		this.bindDateObject ( checkOutobj, sendHandler );
	};
	
	vp.hotelSearchUpdateCounts.prototype.bindDateObject = function( dateObject, sendHandler )
	{
		var origOnChange = dateObject.onChange;
		dateObject.onChange = function() { sendHandler(); origOnChange(); };
	};
	
	vp.hotelSearchUpdateCounts.prototype.createSendHandler = function()
	{
		dateObject = this;
		return function() { dateObject.sendRequest(); };
	};
	
	vp.hotelSearchUpdateCounts.prototype.sendRequest = function()
	{
		if ( this.xmlHttp != null )
			this.xmlHttp.abort();
		
		var self = this,
			params = {
				hotelSearchRoomSize:	this.roomSizeEl.value,
				hotelSearchCategory:	this.categoryEl.value,
				hotelSearchAreaID:		this.areaEl.value
				};
					
		if ( ( from = this.checkIn.toString() ) !== null )
			params.hotelSearchFrom = from;
			
		if ( ( to = this.checkOut.toString() ) !== null )
			params.hotelSearchTo = to;
		
		if ( this.onlineOnlyID != undefined )
			params.hotelSearchOnlineOnly = this.onlineOnlyID.checked ? 1 : 0;

		this.xmlHttp = $.ajax ( {
			type:		'post',
			url:		this.updateURL,
			success:	function ( xmlHttp ) { self.doUpdate ( xmlHttp ); },
			data:		params
			} );
	};
	
	vp.hotelSearchUpdateCounts.prototype.doUpdate = function ( data )
	{
		$(this.countEl).html ( $(data).find('counts').text() );
	};
	
