$(document).ready(function(){
  externalLinks();
  HeaderInfo();
  StatusCookies();
  Contest();
  Newsletter();
  if ( $('#newsletterCompleteForm').length ) CompleteNewsletterSubscription();
  if ( $('.article').length ) ImageSlideshow();
  Quickbook();
  hotelAdaptions();
});

function externalLinks () {
  $('a[rel="extern"]').removeAttr('rel').attr('target', '_blank');
  $('a.relextern').removeClass('relextern').attr('target', '_blank');
}

function HeaderInfo() {
	if (! $('#headerCopyright')[0] ) return;
	
	$('#headerCopyright').bind('mouseenter focus', showInfo);
	$('#headerInfo').mouseleave(hideInfo);
	if ( $('#headerInfo a').length ) {
	  $('#headerInfo a').blur(hideInfo);
	} else {
	  $('#headerCopyright').blur(hideInfo);
	}
	
	function showInfo () {
		$('#headerInfo').hide().removeClass('hidden').fadeIn(300);
	}
	
	function hideInfo() {
		$('#headerInfo').fadeOut(500, function() {
			$('#headerInfo').addClass('hidden').show();
		});
	}
}

function StatusCookies (where) {
  var parent = where || '#mainContent';
  
  var statusMsg = readCookie('statusmsg');
  if (! statusMsg ) return;
  statusMsg = decodeURIComponent(statusMsg);
  
  // strip ""
  if ( statusMsg.charAt(0) == '"' &&  statusMsg.charAt(statusMsg.length-1) == '"' ) {
	statusMsg = statusMsg.substring(1, statusMsg.length-1);
  }
  
  // add or update message
  if (! $('#statusmsg').length ) {
    $(parent).prepend('<div id="statusmsg" class="archived"><p>'+statusMsg+'</p></div>');
  }
  else {
	$(parent).find('#statusmsg p').html(statusMsg);
  }
  
  eraseCookie('statusmsg');
}

function Contest () {
  if (! $('#field_get_newsletter_0').length ) return;
  
  var getNewsletter = $('#field_get_newsletter_0');
  var newsletterLang = $('#newsletterLang');
  
  if (! $('#field_get_newsletter_0:checked').length ) newsletterLang.hide();
  
  getNewsletter.click(function() {
    newsletterLang.toggle();
  });
}

function Newsletter () {
  if (! $('.newsletterReg')[0] ) return;
  
  var fieldsToCheck = $('#woman, #firstName, #lastName, #email, #country, #german, #html');
  var valid = true;
  var errors = [];
  
  $('#newsletterForm').submit(function() {
    removeErrMsgs();
    validateEmpty(fieldsToCheck);
    validateEmail($('#email'));
    
    if ( errors.length ) insertErrSummary();
      
    return valid;
  });
  
  // Validates if given fields are not empty
  function validateEmpty (fields) {
    fields.each(function() {
      if (! isFilled(this) ) {
        valid = false;
        addError(this);
        insertErrMsg(this);
      }
    });
  }
  
  // Validates if given fields are email address
  function validateEmail (fields) {
    fields.each(function() {
      if (! isEmail(this) ) {
        valid = false;
        addError(this, 'email');
        insertErrMsg(this, lang['error']+lang['errorEmail']);
      }
    });
  }
  
  // Is the field not empty?
  function isFilled (field) {
    if ( isOption (field) ) {
      return (fieldPlusOptions(field).filter(':checked').length);
    } else {
      return ($(field).val() == '' ? false : true);
    }
  }
  
  // Is the string in the field a valid email address?
  function isEmail (field) {
    var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
    return (filter.test($(field).val()));
  }
  
  // Add the error to the Errors Array so that we can use it in the Error Summary Box
  function addError (field, type) {
    var type = type || 'filled';
    
    if ( isOption(field) ) {
      errors.push($(field).attr('id')+','+getLabelText($(field).parents('fieldset').find('legend'))+': '+lang['errorOneOption']);
    } else {
      var message = lang['errorRequired'];
      if ( type == 'email' ) {
        message = lang['errorEmail'];
      }
      errors.push($(field).attr('id')+','+getLabelText($(field).prev('label'))+': '+message);
    }
  }
  
  // Insert the error message into the field's label
  function insertErrMsg (field, msg) {
    var msg = msg || lang['error']+lang['errorRequired'];
    
    if ( isOption (field) ) {
      msg =  lang['error']+lang['errorOneOption'];
    }
    
    fieldPlusOptions(field).prev('label').append(' <em>'+msg+'</em>').parent().addClass('error');
  }
  
  // Insert the Error Summary Box at the top
  function insertErrSummary () {
    $('p.margin').after('<div class="errors"><h2>'+lang['error']+'('+errors.length+')</h2><ul></ul></div>');
    $.each(errors, function() {
      var errorDetails = this.split(',');
      $('.errors ul').append('<li><a href="#'+errorDetails[0]+'">'+errorDetails[1]+'</a></li>');
    });
  }
  
  // Remove everything Error related so we have a clean form again
  function removeErrMsgs () {
    valid = true;
    errors = [];
    $('.errors').remove();
    fieldsToCheck.each(function() {
      fieldPlusOptions(this).parent().removeClass('error').find('label em').remove();
    });
  }
  
  // Is the field of type checkbox or Radio?
  function isOption (field) {
    return ($(field).attr('type') == 'radio' || $(field).attr('type') == 'checkbox');
  }
  
  /* If isOption(field): Returns all fields with the same name
     If ! isOption(field): Returns the field */
  function fieldPlusOptions (field) {
    if ( isOption(field) ) {
      var fieldName = $(field).attr('name');
      return $('input[name="'+fieldName+'"]');
    } else {
      return $(field);
    }
  }
  
  // Returns only the text of the label without any added <em> or <span>
  function getLabelText (field) {
    var fieldCopy = field.clone();
    fieldCopy.find('em, span').remove();
    
    return (fieldCopy.text());
  }
}

function CompleteNewsletterSubscription() {
  var nlcForm = $('#newsletterCompleteForm');
  nlcForm.hide();
  if ( nlcForm.length ) {
	var action = nlcForm.attr('action');
	var formdata = nlcForm.serialize();
	$.ajax({
	  type: 'GET',
	  url: action,
	  data: formdata,
	  dataType: 'html',
	  success: function(data, textStatus) {}
	});
	nlcForm.remove();
  }
}

function ImageSlideshow() {
	if (! $('.imageSlideshow')[0] ) return;
	
	var gallery = $('.imageGallery');
	var slideshow = $('.imageSlideshow');
	
	var list = new LinkedList();
	var slides = $('.imageSlideshow .image');
	var thumbs = $('.imageGallery .galleryImage');
	var slideNav = $('#slideNav');
	var prevLink = $('#slideNavBack');
	var nextLink = $('#slideNavForward');
	var galleryLink = $('#slideNavUp');
	var currentPage;
	var pages;
	var current = new Object();
	var gallerySize;
	
	initialize();
	
	function initialize(gallerySize, slideIndex) {
	  currentPage = 1;
	  gallerySize = gallerySize ? gallerySize : 9;
	  pages = Math.ceil(thumbs.length / gallerySize);
	  
	  var slideIndex = slideIndex ? slideIndex : 0;
	  var topMargin = parseInt($(slides[0]).css('margin-top'), 10);
	  var slideNavHeight = slideNav.height();
	  if ( slideshow.css('display') == 'none' ) {
	    slideshow.show();
	    slideNavHeight = slideNav.height();
	    slideshow.hide();
	  } 
	  var galleryShowWidth = $('#galleryShow').width();
	  var slidePage = 1;
	  
  	// add some properties to each slide object
  	slides.each(function(i){
  		this.image = $(this).children('img');
  		
  		// save all styles for the link
  		
  		$(this).addClass('hidden').show();
  		this.prevLinkStyle = {'width': this.image.attr('width')/2+'px',
  													'height': this.image.attr('height')+'px',
  													'top': slideNavHeight+topMargin+'px'
  												};
  		this.prevLinkStyle[lang['left']] = (galleryShowWidth - this.image.attr('width'))/2+'px';
  		
  		this.nextLinkStyle = {'width': this.image.attr('width')/2,
  													'height': this.image.attr('height'),
  													'top': slideNavHeight+topMargin
  												};
  		this.nextLinkStyle[lang['left']] = galleryShowWidth/2;
      $(this).hide().removeClass('hidden');
      
  		this.page = slidePage;
  		if ( ((i+1) % gallerySize) == 0 ) slidePage+=1;
  		
  		// add this slide to the linked list
  		list.append(this);
  	});
	
  	var thumbsPage = 1;
  	thumbs.each(function(i){
  	  $(this).addClass('page'+thumbsPage);
  		$(this).children('a').click(function(){
  			showSlideshow(i);
  			return false;
  		});
  		if ( ((i+1) % gallerySize) == 0 ) thumbsPage+=1;
  	});
  	
  	nextLink.children('span').addClass('hidden');
  	nextLink.click(function(){
  		nextSlide();
  		return false;
  	});
  	
  	prevLink.children('span').addClass('hidden');
  	prevLink.click(function(){
  		prevSlide();
  		return false;
  	});
  	
  	galleryLink.click(function(){
  		showGallery(currentPage);
  		return false;
  	});
  	
  	insertPagination();
  	current = list.first;
	
	  if (gallery.css('display') == 'block') {
      showGallery(currentPage, 0);
    } else {
      showSlideshow(slideIndex, 0);
    }
	}
	
	function insertPagination() {
	  if ( pages==1 ) return;
	  
	  var content = '<p class="hidden">'+lang['gotoPage']+'</p><ul id="galleryPagination" class="clearfix">';
	  for ( i=0; i<pages; i++ ) {
	    var page = i+1;
	    if ( page == currentPage) {
	      content += '<li><span>'+page+'</span></li>';
	    } else {
	      content += '<li><a href="#">'+page+'</a></li>';
	    }
	  }
	  content += '</ul>';
	  gallery.append(content);
	  updatePagination();
	}
	
	function updatePagination() {
	  var pagination = $('#galleryPagination');
	  
	  $('li', pagination).each(function(i) {
	    var page = i+1;
	    if ( page == currentPage) {
	      $(this).html('<span>'+page+'</span>');
	    } else {
	      $(this).html('<a href="#">'+page+'</a>');
	      $('a', this).click(function() {
	        showGallery(page);
	        return false;
	      });
	    }
	  });
	}
	
	function setLinks() {
		prevLink.css(current.prevLinkStyle);
		nextLink.css(current.nextLinkStyle);
		nextLink.next = current.next;
		prevLink.prev = current.prev;
	}
	
	function nextSlide() {
		current = current.next;
		currentPage = current.page;
		changeSlide(current.prev, nextLink);
	}
	
	function prevSlide() {
		current = current.prev;
		currentPage = current.page;
		changeSlide(current.next, prevLink);
	}
	
	function changeSlide(oldSlide,link) {
	  link.hide();
	  $(oldSlide).fadeTo(500, 0, function(){
			$(current).fadeIn(500, function(){
				link.show();
			});
			if ( list.length > 1 ) {
			  $(oldSlide).hide().fadeTo(0,1);
			} else {
			  $(current).fadeTo(500, 1);
			}
		});
		setLinks();
	}
	
	function showSlideshow(i, time) {
	  var time = time ? time : 500;
	  
		current = list.at(i);
		$(slides).hide();
		$(current).show();
		gallery.fadeTo(time, 0, function(){
			slideshow.fadeIn(time);
			gallery.hide().fadeTo(0,1);
		});
		setLinks();
	}
	
	function showGallery(page, time) {
	  var time = time ? time : 500;
	  var page = page ? page : currentPage;
	  var toHide = gallery.is(':hidden') ? slideshow : gallery;
	  currentPage = page;
	  
		toHide.fadeOut(time, function() {
		  updatePagination();
		  $('.galleryImage', gallery).hide();
	    $('.page' + page, gallery).show();
			gallery.fadeIn(time);
		});
		setLinks();
	}
}

function Quickbook() {
  if (! $('#quickbook').length ) return;
  
	// Tabs
	$('#quickbook > ul').show();
	$('#hotel > h3, #event > h3').addClass('hidden');
	$('#hotelListitem').addClass('state-active');
	$('#event').addClass('tabs-hide');
	
	$('#hotelListitem a, #eventListitem a').click(function() {
		$('#hotel, #event').toggleClass('tabs-hide');
		$('#hotelListitem, #eventListitem').toggleClass('state-active');
		return false;
	});
	
	// Give Common options to all Datepickers
	var startDateOptionsHotel = datepickerOptions({
	  minDate: 0,
	  onSelect: resetEnd
  });
	var	endDateOptionsHotel 	= datepickerOptions({
	  beforeShow: customRange
	});
	var	startDateOptionsEvent = datepickerOptions({
	  minDate: 0,
	  onSelect: resetEnd
	});
	var	endDateOptionsEvent 	= datepickerOptions({
	  beforeShow: customRange
	});
	
	// Datepicker Hotel	
	$("#arrival").datepicker(startDateOptionsHotel).datepicker('setDate', new Date());
  $('#departure').datepicker(endDateOptionsHotel).datepicker('setDate', +3);
  
  $('#ui-datepicker-div').hide();
	
	// Datepicker Event
	$("#from").datepicker(startDateOptionsEvent).datepicker('setDate', new Date());
  $('#to').datepicker(endDateOptionsEvent).datepicker('setDate', +3);
}

function hotelAdaptions () {
  var host = window.location.hostname;
  // if we arent on hotels.wien.info or events.wien.info => return
  if ( host != 'hotels.wien.info' && host != 'events.wien.info' ) return;
  
  // Repair the toplink here
  $('.toplink a').click(function() {
    window.location = window.location + '#skiplinks';
    return false;
  });
  
  // if the user is not logged in => return
  if (! readCookie('user') ) return;
    
  // Remove Login Links to myVienna because they don't work anyway
  $('#serviceNav .loginLogout').remove();
  $('#myviennaLoginRegister').remove();
  TopNavigation.positionLanguageMenu();
}

/* --- Datepicker Helperfunctions --- */

// Set Datepicker Options
function datepickerOptions(options) {
  var generalOptions = {
		duration: 'fast',
		constrainInput: true,
		showOn: 'both',
		buttonText: lang['chooseDate'],
		buttonImage: 'http://www.wien.info/++resource++wir/img/iconCalendar.png',
		buttonImageOnly: true
	};
	
	return $.extend(generalOptions, options);
}

// Intitialize Dates on Datepickers if the input fields are empty
function initDates (start, end, difference) {
  // 3 days is the default difference between start and end dates
  difference = difference || 3;
  
  if (start.val() == '') {
    start.datepicker('setDate', new Date());
  }
  if ( end.val() == '' ) {
    end.datepicker('setDate', +difference);
  }
}

function resetEnd() {
  // Hotel Quickbook
  if ( this.id == "arrival") {
    if ($(this).datepicker('getDate') >= $('#departure').datepicker('getDate')) {
	    $('#departure').datepicker('setDate', 0);
	  }
	// Event Quickbook
  } else if ( this.id == "from" ) {
    if ($(this).datepicker('getDate') > $('#to').datepicker('getDate')) {
	    $('#to').datepicker('setDate', 0);
	  }
	// Hotelsearch
  } else if ( this.id == "hotelArrival" ) {
    if ($(this).datepicker('getDate') >= $('#hotelDeparture').datepicker('getDate')) {
	    $('#hotelDeparture').datepicker('setDate', 0);
	  }
  // Eventsearch
  } else if ( this.id == "eventFrom" ) {
    if ($(this).datepicker('getDate') > $('#eventTo').datepicker('getDate')) {
	    $('#eventTo').datepicker('setDate', 0);
	  }
	// Hotelbooking
  } else if ( this.id == "bookingArrival" ) {
    if ($(this).datepicker('getDate') >= $('#bookingDeparture').datepicker('getDate')) {
	    $('#bookingDeparture').datepicker('setDate', 0);
	  }
  }
}

function customRange() {
	var myDate = new Date();
	
	if (this.id == 'departure') {
		myDate = $('#arrival').datepicker('getDate');
		if (myDate == null) myDate = new Date();
		myDate.setDate(myDate.getDate()+1);
	} else if (this.id == 'to') {
		myDate = $('#from').datepicker('getDate');
		if (myDate == null) myDate = new Date();
	} else if (this.id == 'hotelDeparture') {
		myDate = $('#hotelArrival').datepicker('getDate');
		if (myDate == null) myDate = new Date();
		myDate.setDate(myDate.getDate()+1);
	} else if (this.id == 'eventTo') {
		myDate = $('#eventFrom').datepicker('getDate');
		if (myDate == null) myDate = new Date();
	}
	else if (this.id == 'bookingDeparture') {
		myDate = $('#bookingArrival').datepicker('getDate');
		if (myDate == null) myDate = new Date();
		myDate.setDate(myDate.getDate()+1);
	}
	
  return { minDate: myDate };
}

/* --- A Linked List --- */

function LinkedList() {}
LinkedList.prototype = {
  length: 0,
  first: null,
  last: null
};

LinkedList.prototype.append = function(node) {
  if (this.first === null) {
    node.prev = node;
    node.next = node;
    this.first = node;
    this.last = node;
  } else {
    node.prev = this.last;
    node.next = this.first;
    this.first.prev = node;
    this.last.next = node;
    this.last = node;
  }
  this.length++;
};

LinkedList.prototype.at = function(i) {
  if (!(i >= 0 && i < this.length)) { return null; }
  var node = this.first;
  while (i--) { node = node.next; }
  return node;
};

LinkedList.prototype.each = function(fn) {
  var node = this.first, n = this.length;
  for (var i = 0; i < n; i++) {
    fn(node, i);
    node = node.next;
  }
};

/* --- Delete Value on Focus --- */

function deleteContent (field, content) {
  if ( field.val() == content ) {
    field.removeClass('hint').val('');
  }
}

function restoreContent (field, content) {
  if ( field.val() == '') {
    field.addClass('hint').val(content);
  }
}

/* --- Cookie Helpers --- */

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/; domain="+getCookieDomain();
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[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,"",-1);
}

function getCookieDomain() {
  var domain = window.location.hostname;
  var parts = domain.split('.');
  var num = parts.length;
  
  if ( num > 1 ) {
    if ( num == 4 ) {
      if ( domain.match(/\d+.\d+.\d+.\d+/) ) {
        return domain;
      }
    }
    for (var i=0; i<num-2; i++) {
      parts.shift();
    }
    domain = '.' + parts.join('.');
  }
  return domain;
}