//namespace
var ha = {
	ajax: {}, map: {}, geocode: {}, reviews: {}, page: {}, settings: {}, site: {}, strings: {}, ui: {},
	
    seo: {
    	/* business requirement to have markup up high but display down low */
    	showSeoText: function() {
    		// check if the elements exist before calling them - the no search results page and some decorates
    		// do not for instance
    		if ($('#searchText') && $('#searchTextPosition')) {
    			$('#searchTextPosition').append($('#searchText'));
    		}
    	}
    },
    
    util: {
    	isInt: function(c){ return((c>="0")&&(c<="9")) },
    	
    	initToggles: function(){
			$(".expand .content").addClass("hidden");
			$(".expand .show").removeClass("hidden");
			$(".expand .action").bind("click", function(){
				var el = $(this).parent("div.container").children("div.content");
				if(el.hasClass("hidden")){
					el.removeClass("hidden");
					$(this).addClass("open");
				}
				else{
					el.addClass("hidden");
					$(this).removeClass("open");
				}
			});
		},
		
		initPopupUrls: function(){
			$(".popup-url").bind("click", function(){
				window.open(this.href);
				return false;
			});
		},	
		
		initSearchSwap: function(){
			$(".input-keyword").each(function(){
		        var val = $(this).val();
		        var rel = $(this).attr("rel");
		        if(val == ""){ 
		        	$(this).addClass("default");
		        	$(this).val(rel);
		        }
		        else if(val != rel){
		        	$(this).removeClass("default");
				}
			});
			$(".input-keyword").focus(function(){
				var val = $(this).val();
				$(this).removeClass("default");	
				if($(this).attr("rel") == $(this).val()){
					$(this).val("");
				}
			});
			$(".input-keyword").blur(function(){
				var val = $(this).val();
				$(this).removeClass("default");
				if($(this).val() == ""){
					$(this).addClass("default");
					$(this).val($(this).attr("rel"));
				}
			});
		},
		
		// used to get dateformat for the datepicker
		calDateFmt: function() {
			var dateSplit = brand.javaDateInputPattern.split("/");
			return (dateSplit[0].charAt(0) + "-" + dateSplit[1].charAt(1) + "-" + dateSplit[2].charAt(0)).toLowerCase();
		},
		
		//onkeyup: monitor length and update counter
		limiter: function(event){
			var maxChars = $(this).attr('maxlength');
			var charCount = $(this).val().length;
			var lineCount = $(this).val().split(/\r\n|\n|\r\|\f/).length;
			var totalCount = (charCount > 0) ? charCount + lineCount : 0;
			var remainder = ((maxChars - totalCount) > -1) ? maxChars - totalCount : 0;
			var allowedKeys = new Array(8,9,27,46,33,34,35,36,37,38,39,40,45);
						
			if(event.metaKey || event.ctrlKey || event.altKey) return true;
			
			if(jQuery.inArray(event.keyCode, allowedKeys) != -1){
				$('#remainder').text(remainder);
				return true;
			}
			
			if(totalCount >= maxChars){
				$(this).val($(this).val().substr(0,maxChars-lineCount));
				$('#remainder').text(remainder);
				return false;
			}
			$('#remainder').text(remainder);
		},
		
    	partialBox: function(partialHeight,duration){
    		$(".partial-box .toggles").click(function(){
				var contentHeight = $(this).siblings(".content").children("div").height();
				if (contentHeight > partialHeight){
					if ($(this).children(".fade").css("display") == "block"){
						$(this).children(".fade").css("display","none");
						$(this).siblings(".content").animate({height: contentHeight}, duration);
						var sibling = $(this).children(".hide");
						var delay = function() { toggle(sibling); };
						setTimeout(delay, duration+1);
					} else {
						$(this).children(".hide").css("display","none");
						$(this).siblings(".content").animate({height: partialHeight + "px"}, duration);
						var sibling = $(this).children(".fade");
						var delay = function() { toggle(sibling); };
						setTimeout(delay, duration+1);
					}
					function toggle(el){ $(el).css("display","block"); }
				} else {
					$(this).children(".fade").css("display","none");
					$(this).children(".all").css("display","block");
				}
    		});
    	}, 
    	
    	resetSearch: function(){
    		$.cookie("HomeAwaySearch", null, {path: '/'});
    		$.cookie("s_url", null, {path: '/' });
    		return true; 
    	}
    }
    
};

/* 
 * Straightforward/simple Observer pattern implementation
 * Example useage:
 * var publisher = new Observer
 * publisher.subscribe(function(msg){
 *    alert(msg);
 * });
 * publisher.fire("Event fired!");
 */
function Observer() {
	this.fns = [];
}

Observer.prototype = {
	subscribe : function(fn) {
		this.fns.push(fn);
	},
	unsubscribe : function(fn) {
		this.fns = this.fns.filter(
			function(el) {
				if (el !== fn) {
					return el;
				}
			}
		);
	},
	fire : function(o, thisObj) {
		var scope = thisObj || window;
		this.fns.forEach(
			function(el) {
				el.call(scope, o);
			}
		);
	}
};
// Add some sugar to the Array prototype
Array.prototype.forEach = function(fn, thisObj) {
    var scope = thisObj || window;
    for ( var i=0, j=this.length; i < j; ++i ) {
        fn.call(scope, this[i], i, this);
    }
};
Array.prototype.filter = function(fn, thisObj) {
    var scope = thisObj || window;
    var a = [];
    for ( var i=0, j=this.length; i < j; ++i ) {
        if ( !fn.call(scope, this[i], i, this) ) {
            continue;
        }
        a.push(this[i]);
    }
    return a;
};

//TO-DO: deprecate these
var jsEnabled = function(s){ this.s=s;}

/*
 * GLOBAL
 * advancedSearchForm, homeSearchForm, keywordSearchForm, refineSearchForm (aka sidebar)
 * noResults, 404error, error, secondary pages, etc.
 */
var searchErrorObserver = new Observer;

ha.site.searchform = {
    init: function(){
        
        $('.input-keyword').keyup(function(e){
        	e = e || window.event;
        	var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;
        	if (keyCode == 13) {
        		ha.site.searchform.submit(e);
        	}
        });
        
        $(".go-btn-sq").click(function(e){
    		ha.site.searchform.submit(e);
        });
        
    	$('form[name=searchForm],form[name=refineSearchForm]').each(function(){
    		$(this).submit(function(e){ return false; });
    		
    		$('.search-submit-button', $(this)).click(function(e){
    			ha.site.searchform.submit(e);
    		});
    	});
    	
    	$("#price-range-fields .input").bind("focus", function(){
    		$("#price-range-vaidation").addClass("hidden").css("display", "");
    	});
    	
    },

    isDigit: function(e){
    	var charCode = (e.which) ? e.which : window.event ? window.event.keyCode : 0;
   		if (charCode > 31 && (charCode < 48 || charCode > 57)){
   			return false;
   		}
   		return true;
    },
    
    submit: function(e){
    	var formObj = $('form[name=searchForm],form[name=refineSearchForm]');
    	if (e) formObj = $(e.target).parents('form');

    	// determine what sort of search has been performed
    	var searchType = formObj.attr("id");
    	if(searchType == "simple-search") searchType = "simple";
    	else if(searchType == "keywordSearchForm") searchType = "keyword";
    	else if(searchType == "adv-search-form") searchType = "advanced";
    	else if(searchType == "refineSearchform") searchType = "availability";
    	else searchType = "notknown";
    	
    	if (searchType != "availability"){
			ha.util.resetSearch();
    	}
    	
    	$.cookie('searchType', searchType, {expires: 1, path: '/'});	

    	// get keywords
    	var keywords = ($("input[name=keywords]", formObj).length > -1) ? $("input[name=keywords]", formObj).val() : "";
    	var defaultMessage = $("input[rel]", formObj).attr("rel");

    	if ($.trim(keywords) !="" && keywords!=defaultMessage) {
    		if(searchType == "availability"){
    			// avoid double encoding
        		keywords = "/keywords:" + keywords;
    		}
    		else{
        		keywords = "/keywords:" + encodeURIComponent(keywords);
    		}
    	}
    	else{
    		keywords = "";
    	}

    	var refinements = "";
    	if ($("#refinements",formObj).val() != null && $.trim($("#refinements",formObj).val()) != ''){
    		// get refineSearchForm refinements aka sidebar
    		refinements += $("#refinements",formObj).val().replace("+", "*");
    	}
    	else{
    		// get advancedSearchForm refinements
    		var refinements = "";
    		$('input, select',formObj).each(function(i,el){
    			if ((el.type == "select-one" && el.value != '') || (el.type == "checkbox" && el.checked)){
    				refinements += '/' + el.value;
    			}
    		});
    	}

    	// validate price range        	
    	var prices = "";
    	var priceFrom = $("#priceFrom").val(); 
    	var priceTo = $("#priceTo").val();
    	var hasPriceFrom = (priceFrom !=null && priceFrom > 0);
    	var hasPriceTo = (priceTo !=null && priceTo > 0);
    	
    	if(priceFrom !=null && priceTo != null && parseInt(priceFrom) > parseInt(priceTo)){
    		searchErrorObserver.fire();
    		$("#price-range-vaidation").fadeIn("def");
    		return false;
    	}
    	//Were prices provided?
    	if(hasPriceFrom){
    		prices += "&minPrice=" + priceFrom;
    	}
    	if (hasPriceTo) {
    		prices += "&maxPrice=" + priceTo;
    	}
    	//If prices provided, add currency 
    	if(hasPriceFrom || hasPriceTo) {
    		prices += "&currency=" + brand.baseCurrency;
    		if (searchType == "advanced"){
    			$.cookie('HomeAwaySearch', prices.substring(1, prices.length), { path: '/' });
    		}
    		prices = prices.replace(/&/g, "/").replace(/=/g,"/");
    	}
    	
    	// if a startDate was not entered then set it to the end date
    	if (searchType != "keyword") {
    		ha.util.datePickControl.checkStart('startDateInput','endDateInput');
    	}
    	
    	var startDate = ha.site.searchform.dateParam($('#startDateInput', formObj),'arrival');
		var endDate = ha.site.searchform.dateParam($('#endDateInput', formObj),'departure');

		var url = '';
    	if (searchType == "availability" && $("body.search-page.dynamic").length > 0){
        	url = ha.site.searchform.buildUrl(urlData.url, startDate, endDate);
        	urlData.url = url;
    		ha.ui.search.update(url,false);
    	} else {
    		url += '/search';
    		if (refinements != ''){ url += '/refined'; }
    		url += keywords;
    		url += refinements;
    		url += prices;
    		url += startDate;
    		url += endDate;
    		window.location = url;
    	}
    },
    
    buildUrl: function(url, startDate, endDate){
    	if (url.indexOf("/arrival:") > -1 && url.indexOf("/departure:") > -1) {
    		var s, tmp;
    		var tokens = url.split("/arrival:");
    		var urlEnd = tokens[1].substring(tokens[1].indexOf("/"), tokens[1].length);
    		tmp = tokens[0] + startDate + urlEnd;

    		tokens = tmp.split("/departure:");
    		urlEnd = "";
    		if (tokens[1].indexOf("/") > -1){
    			urlEnd = tokens[1].substring(tokens[1].indexOf("/"), tokens[1].length);
    		}
    		s = tokens[0] + endDate + urlEnd;
        	return s;
		} else {
			return url + startDate + endDate;
		}
    },
    
    // return a formatted url param for a given search date string
    dateParam: function(o,s){
    	if ((typeof $(o).val() == "undefined") || (ha.site.searchform.delim($(o).val()) == "") || ($(o).val().indexOf("/") == -1)){
    		return "";
    	} else if ($(o).val() != brand.dateInputHelpText){
    		if (brand.dateInputHelpText == 'mm/dd/yyyy'){
    			var parts = $(o).val().split("/")
    			return '/' + s + ':' + parts[2] + '-' + parts[0] + '-' + parts[1];
    		}
    		return '/' + s + ':' + $(o).val().split("/").reverse().join("-");
    	}
    	return "";
    },
    
    // set the date string delimiters
    delim: function(s){
		if(s.indexOf("/") == -1){
			if(s.indexOf("-") > -1) s = s.replace(/-/g, "/");
			else if(s.indexOf(".") > -1) s = s.replace(/\./g, "/");
			else s = "";
		}
		return s;
    }
};

/*
 * HOME PAGE
 */
 	var fadeCount = 0;
	var layerCount = 1;
 
ha.page.home = {
	init: function(){
		ha.util.initToggles();
		$('#map_home').click(function(){ha.util.resetSearch();});
		if (heroTotal > 1){
			ha.page.home.fade(true);
		}
	},
		
	fade: function (init){
		var timeout, duration;
		var fadeTimer = 1500;
		var layer = $("#layer" + layerCount);
			
		if (init || ha.page.home.faded()) {
			$(layer).fadeIn(fadeTimer);
			fadeCount++;
			duration = 8000; // 5 seconds
		} else {
			$(layer).fadeOut(fadeTimer);
				
			layerCount++;
			if (layerCount == $(".fade-layer").length + 1) layerCount = 1;
			fadeCount = 0;
				
			duration = 10; // about half of fadeTimer/fadeIn
		}
			
		timeout = setTimeout(ha.page.home.fade, duration);
	},
		
	faded: function(){
		return (fadeCount % 2) ? false : true;
	}
};

/*
 * SEARCH PAGE
 */
ha.page.search = {
	initDynamic: function(){
		ha.seo.showSeoText();
		ha.page.search.initAttractions();
	},
	
	init: function(){
		$.cookie('newSort', null);
		
		$("#sortingSelect").change(function(){
			ha.page.search.onSortChange();
		});
		
		if($("#fullAdsFirst")) {
			$("#fullAdsFirst").change(function(){
				ha.page.search.onFullAdsFirstChange();
			});
		}
		
		// set up Omniture events
		ha.page.search.setOmnitureEvents();
		ha.util.initToggles();
		ha.page.search.initCollapsableRegions();
		ha.page.search.initPriceToggle();
		ha.page.search.initReviewsRefinement();
		ha.page.search.initAttractions();
		ha.seo.showSeoText();
    },

	/**
	* This method is tied to the select box 'sortingSelect'.  When its state changes, 
	* this method will change the current page's URL to the destination in the sort select. 
	**/
	onSortChange: function(){
	    // find the select
		select = document.getElementById("sortingSelect");
		
		// grab the destination string
		destination = select[select.selectedIndex].value;
			
		// if it exists (i.e. is not the "Select One:" option
		if (destination) {
			//null expires deletes cookie at browser exists
			if ($.cookie('orderByOffer') != null) {
				$.cookie('orderByOffer', null, {path: '/'});
			}
			$.cookie('orderBy', destination, {path: '/'});
			$.cookie('searchType', "newsort", {expires: 1, path: '/'});
			// then go there
			ha.page.search.doSort();
		}
	},
	
	/**
	* This method is tied to the checkbox for showing properties with images first
	**/
	onFullAdsFirstChange: function() {
	    checkbox = document.getElementById("fullAdsFirst");	    
	    $.cookie('fullAdsFirst', null, {path: '/'}); // This ensures that non-session cookies are deleted
		$.cookie('fullAdsFirst', checkbox.checked, {path: '/'});
		ha.page.search.doSort();	    
	},

	/**
	 * Sets the page size via a cookie.
	 */
	doSetPageSize: function(pageSizeSelect){
		var newPageSize = Number(pageSizeSelect.options[pageSizeSelect.selectedIndex].text);
			
		$.cookie('pageSize', newPageSize, {expires: 7, path: '/'});
		ha.page.search.doSort();
	},
	
	doSort: function(){
		$.cookie('newSort', 1);
		var pageUrl = location.href;
		pageUrl = pageUrl.split("#main")[0];
		window.location = pageUrl;
	},
	
	setOmnitureEvents: function(){
		$("#sidebarContent ul.criteria ul.criteria li").bind("click", function(event){
			$.cookie('searchType', "refinement:" + $(this).attr("id"), {expires: 1, path: '/'});
		});
	},
	
	initPriceToggle: function(){
		var priceValues = ($('#priceFrom.input').val() + $('#priceTo.input').val());
		if (priceValues > 0) {
			$("#price-range .action").addClass("open");
			$("#price-range .content").removeClass("hidden");
			$("#findByDateButton").insertAfter("#price-range-fields");
		}

		$("#price-range .action").bind("click", function(){
			if($(this).hasClass("open")){
				$("#findByDateButton").insertAfter("#price-range-fields");
				$("#priceFrom").focus();
			}
			else{
				$("#findByDateButton").insertAfter("#findByDateForm");
	    		$("#price-range-vaidation").addClass("hidden").css("display", "");
				$("#price-range-fields input").val("");
			}
		});
	},
	
	
	initCollapsableRegions: function(){
		$("body.consolidated-region ul.criteria li ul.region > li").each(function(){
			// only apply the event to regions which have child nodes to display
			if($(this).find("ul.children").size() > 0){
				$(this).addClass("parent");
				$(this).click(function(event){
					var target = $(event.target);
					if(target.attr("tagName") == "A"){
						return true;
					}
					if(target.hasClass("parent")){
						target.toggleClass("open");
					}
				});
			}
		});

	},
	
	initReviewsRefinement: function(){
		$("input[name=review_count_refinement]").change(function(){
			document.location = $(this).val();
		});
	},
	
	initAttractions: function(){
		$("#attractions-lnk").click(function(){ 
			$.cookie('ha-search-url', document.location, {path: '/'});
		});
	}
};

/*
 * LANDING PAGE
 */ 
ha.page.landing = {
	init: function(){
		if ($("#mapLink").length > 0){
			$("#mapLink").click(function(){
				ha.page.landing.showMap();
			});
		}else if ($("#map").length > 0){
			$("#map").css("display","block");
		}
		$(".zero-features a.headerLink").click(function(){
			return false;
		});
		ha.page.landing.seoCoulmn();
		ha.seo.showSeoText();

	},
		
	showMap: function showMap(){
		if($("#mapTxt").html() == ha.strings.viewMapMsg) {
			$("#mapTxt").html(ha.strings.closeMapMsg);
				
			$("#map").css({display:"block", backgroundColor:"#fff", borderColor:"#fff", textAlign:"center"});	
			$("#regionMapImage").css({margin:"10px"});
		} else {
			$("#map").css({display:"none"});
			$("#mapTxt").html(ha.strings.viewMapMsg);
		}
	},
	
	seoCoulmn: function(){
		/* Show and Hide seo content on right column of landing page */

		$(document).ready(function(){
			var h = $("#searchText").height();
			if(h >= 300) {
				$("#searchText").addClass("closed-seo");
				$("#fade span").click(function(){
					$('#searchText').removeClass("closed-seo");
				});
				$("#hideSeo").click(function(){
					$('#searchText').addClass("closed-seo");
				});
			}
			else{ 
				$("#hideSeo").css("display","none");
			};
		});		
	}
};

/*
 * ADVANCED SEARCH
 */
ha.page.advancedSearch = {
	init: function(){
		$('#refinementsContent0, #refinementsContent1, #refinementsContent2').hide();
		if ($("#keywords").val()){
			document.searchForm.keywords.focus();
		}
		
		searchErrorObserver.subscribe(function(){
			//scroll into view
	        $('html,body').animate({scrollTop: $("#price-range-fields").offset().top}, 500);
		});
		ha.util.initToggles();
	}
};

/*
 * PROPERTY DETAILS
 */
ha.reviews = {
	voteHelpful: function(reviewId, helpful) {
		
		if(ha.page.property.notVoted(reviewId)) {
			$.ajax({ 
				type: "GET", 
				url: "/vacation-rental/reviews/vote", 
				data: ({helpful : helpful, reviewId: reviewId}),
				dataType: "xml",
	  	        success:function(data){ 
				 	helpful = $(data).find('helpful').text();
				 	total = $(data).find('total').text();
		
				 	ha.page.property.updateVotes(reviewId, helpful, total, true);
				}, 
				error:function(xhr,err,e){ alert( "Error: " + err ); }
			});
		}
	}
}

ha.page.property = {
    init: function(){
		ha.ui.modalbox.init();
		ha.page.property.initNavBar();
		ha.ajax.inquiry.init();
		ha.page.property.initInquired();
		if (ha.settings.similarPropertiesOn){
			ha.util.initToggles();
		}
		
		if(window.ie6) { 
        	// get the image tag
        	image = $('#regionMapImage');
        	if(image) {
        		imageSourceUrl = image.srcsure
        		image.src="";
        		image.src=imageSourceUrl;
        	}
        }
	},
	
	initNavBar: function(){
		var anchors = new Array('photos','location','rates','amenities');
		for (var i=0; i< anchors.length; i++){
			if ($('#'+anchors[i]+'-bar').length == 0 || $('#'+anchors[i]+'-bar').css("display") == "none"){
				$('.'+anchors[i]+'-link').css("display","none");
			}
		}
	},
	
	initInquired: function() {
		if ($('a#inquired').length > 0){
        	$('a#inquired').hover(function(e) {
        		var offset = $("#inq-icon").offset();
            	var isSafari = (navigator.userAgent.toLowerCase().indexOf("safari") != -1);
        		var topPos = offset.top-338;
        		if (isSafari) topPos = topPos - 15;
        		$('#inquired-msg').css({top: topPos, left: 703}).fadeIn(200);
        	},
        	function() { // out function
        		$('#inquired-msg').fadeOut(100);
        	});
        }
	}
};

/*
 * WRITE REVIEW PAGE
 */ 
ha.page.writeReview = {
	init: function(){
		$('#body').keyup(ha.util.limiter);
		if($('#body').val() == ""){
			$('#remainder').text($('#body').attr("maxlength"));
		}
		else{
			$('#body').change(ha.util.limiter).change();
		}  
		
		$("#ratings label").click(function(){
			$("#ratings label").removeClass("checked");
			backgroundPositon = $(this).attr("for").substr($(this).attr("for").length-1) * 71;
			$("#ratings").css("background-position",  "0 -" + backgroundPositon + "px" );
			$("#" + $(this).attr("for")).attr("checked", "checked");
			$(this).addClass("checked");
		});
		
		$("#ratings label input[checked]").parent().triggerHandler("click");
		
	}
};

/*
 * ATTRACTIONS PAGE
 */
ha.page.attraction = {
	init: function(){
		$("a.set-page").click(function(e){
			var pageNum = "1";
			var url = location.href;
			if (url.indexOf("/page:") > -1) {
				pageNum = url.split("/page:")[1];
			}
			$.cookie('atrcnPage', pageNum, {path: '/'});
		});
	}
};

$(document).ready(function(){
	//global
	ha.site.searchform.init();
	$.cookie('searchType', null, {path: '/'});	 //clear search type cookie
	
	// init pop-up url's
	ha.util.initPopupUrls();

	if ($("body.homePage").length > 0) ha.page.home.init();
	else if ($("body.search-page.static").length > 0) ha.page.search.init();
	else if ($("body.search-page.dynamic").length > 0) ha.page.search.initDynamic();
	else if ($("body.landing").length > 0) ha.page.landing.init();
	else if ($("body.adv-search").length > 0) ha.page.advancedSearch.init();
	else if ($("body.property").length > 0) ha.page.property.init();
	else if ($("body.attractions.review-add").length > 0 || $("body.attractions.review-write").length > 0 || $("body.reviews-write").length > 0 || $("body.review-response-write").length > 0 || $("body.report-abuse").length > 0) ha.page.writeReview.init();
	else if ($("body.attractions.overview").length > 0) ha.util.partialBox(200,800);
	
	if ($("#attraction-listings").length > 0) ha.page.attraction.init();
	
	$("iframe[rel]").each(function(){
		$(this).attr("src", $(this).attr("rel"));
	});
});



