var Highlighter = function(overrideOptions){
	classThis = this;
	this.previousHighlight = {}
	this.options = { 
		caseSensitive: false,
		searchTerms: false,
		highlightClassName: 'highlightedTerm'
	}
	$.extend(this.options, overrideOptions);
	this.highlight = function(elementSelector) {
		if(!this.options.searchTerms){
			return;
		}
		var pattern = '(' + this.options.searchTerms.join(')|(') + ')';
		var highlightRegex = new RegExp(pattern, this.options.caseSensitive?"":"i");
		$(elementSelector).each(function(index, item){
			classThis.highlightRecursively(item,highlightRegex);
		});
	}
	this.highlightRecursively = function(element, regex){
		var children = $(element).children();
		if(children.length>0){
			children.each(function(index, child){
				classThis.highlightRecursively(child, regex);
			});
		} else {
			var text = $(element).text();
			var match = text.match(regex)
			if(match && match[0].length>0){
				var html = "";
				while(match){
					html += text.substring(0,match.index);
					html += '<span class="' + this.options.highlightClassName + '">' +
								text.substring(match.index,match.index+match[0].length) + 
							'</span>';
					text = text.substring(match.index+match[0].length);
					match = text.match(regex);
				}
				$(element).html(html+text);
			}
		}
	}
	
	var nonEmptySearchTerms = [];
	$.each(this.options.searchTerms, function(index, item){
		if(item.length>1 && !(item.toLowerCase()=="the") && !(item.toLowerCase()=="and") && !(item.toLowerCase()=="a") && !(item.toLowerCase()=="of") && !(item.toLowerCase()=="an") && !(item.toLowerCase()=="at") && !(item.toLowerCase()=="in") ){
			// Strip special characters off except *
			item = item.replace(/[\/\\.+?\[{(|)}\]$^]/g, '');
			item = item.replace(/\*/g, '');
			nonEmptySearchTerms[nonEmptySearchTerms.length]=item;
		}
	});
	this.options.searchTerms = nonEmptySearchTerms;
}



Tools = {}
Tools.Pagination = function(itemsPerPage, totalItems, overrideOptions){
	pageThis = this;
	this.itemsPerPage=2
	this.page=1
	this.lastPage=1
	this.totalItems=10
	this.sliders={}
	this.options= {
		pageBaseId:                 'page',
		activeButtonClass:          'active',
		inactiveButtonClass:        'inactive',
		buttonPrevSelector:         '',
		buttonNextSelector:         '',
		pageNavButtonNextSelector:  '',
		pageNavButtonLastSelector:  '',
		firstVisibleItemSelector:   '',
		lastVisibleItemSelector:    ''
	}
	
	this.init_slider= function(pageNum){
		if(this.page == pageNum){
			this.showPage(pageNum);
		} else {
			this.hidePage(pageNum);
		}
		if(this.lastPage<pageNum){
			this.lastPage=pageNum;
		}
	}
	this.showPage= function(pageNum){
		$('#'+this.options.pageBaseId+pageNum).show();
	}
	this.hidePage= function(pageNum){
		$('#'+this.options.pageBaseId+pageNum).hide();
	}
	this.getHashedPage= function(){
		var hash = document.location.hash.substring(1);
		if(hash==null || hash.length==0 || isNaN(hash) || $('#'+this.options.pageBaseId+hash).length==0){
			return 1;
		}
		return hash-0;
	}
	this.goToPage= function(page){
		if($('#'+this.options.pageBaseId+page).length>0){
			pageThis.hidePage(this.page);
			pageThis.showPage(page);
			pageThis.page = page;
		}
		this.updateButtonClasses();
		ajaxUrl = $('#'+this.options.pageBaseId+page).attr('url');
		if(ajaxUrl){
			$('#'+this.options.pageBaseId+page).load(ajaxUrl, function(response, status, xhr) {
				if (status == "error" && pageThis.options.onAjaxFail){
					pageThis.options.onAjaxFail(pageThis.options.pageBaseId+page);
				} else if(status == "success" && pageThis.options.onAjaxLoad){
					pageThis.options.onAjaxLoad(pageThis.options.pageBaseId+page);
				}
			});
			$('#'+this.options.pageBaseId+page).attr('url',null);
		}
	}
	this.updateButtonClasses= function(){
		//update the status
		pageThis = this;
		$(this.options.firstVisibleItemSelector).each(function(i,item){
			var firstItem = (pageThis.page-1)*pageThis.itemsPerPage+1;
			if(firstItem>pageThis.totalItems){
				firstItem = pageThis.totalItems;
			}
			$(item).html(firstItem);
		});
		$(this.options.lastVisibleItemSelector).each(function(i,item){
			var lastItem = pageThis.page*pageThis.itemsPerPage;
			if(lastItem>pageThis.totalItems){
				lastItem = pageThis.totalItems;
			}
			$(item).html(lastItem);
		});
		
		//update the button classes
		$(this.options.buttonPrevSelector+","+this.options.buttonFirstSelector).each(function(i,item){
			if(pageThis.page==1){
				$(item).removeClass(pageThis.options.activeButtonClass);
				$(item).addClass(pageThis.options.inactiveButtonClass);
			} else {
				$(item).removeClass(pageThis.options.inactiveButtonClass);
				$(item).addClass(pageThis.options.activeButtonClass);
			}
		});
		$(this.options.buttonNextSelector+","+this.options.buttonLastSelector).each(function(i,item){
			if(pageThis.page==pageThis.lastPage){
				$(item).removeClass(pageThis.options.inactiveButtonClass).removeClass(pageThis.options.activeButtonClass);
				$(item).removeClass(pageThis.options.inactiveButtonClass).addClass(pageThis.options.inactiveButtonClass);
			} else {
				$(item).removeClass(pageThis.options.inactiveButtonClass).removeClass(pageThis.options.inactiveButtonClass);
				$(item).removeClass(pageThis.options.inactiveButtonClass).addClass(pageThis.options.activeButtonClass);
			}
		});
		
		if(document.location.hash.length!=0 || this.page!=1){
			document.location.hash = "#"+this.page;
		}
	}
	
	$.extend(this.options, overrideOptions);
	this.itemsPerPage = itemsPerPage-0;//minus zero forces it to be an int
	this.totalItems = totalItems-0;
	this.page = this.getHashedPage();
	//minus zero forces it to be an int
	var pageNum = 1;
	while($('#'+this.options.pageBaseId+pageNum).length>0){
		this.init_slider(pageNum);
		lastPage = pageNum;
		pageNum = pageNum+1;
	}
	this.updateButtonClasses();
	pageThis = this;
	$(this.options.buttonFirstSelector).each(function(i,item){
		$(item).click(function(e){ pageThis.goToPage(1); });
		$(item).disableSelection();
	});
	$(this.options.buttonPrevSelector).each(function(i,item){
		$(item).click(function(e){ pageThis.goToPage(pageThis.page-1); });
		$(item).disableSelection();
	});
	$(this.options.buttonNextSelector).each(function(i,item){
		$(item).click(function(e){pageThis.goToPage(pageThis.page+1);});
		$(item).disableSelection();
	});
	$(this.options.buttonLastSelector).each(function(i,item){
		$(item).click( function(e){ pageThis.goToPage(lastPage); });
		$(item).disableSelection();
	});
	this.goToPage(this.page);
	if($(window).hashchange){
		$(window).hashchange(function(){
			var hashedPage = pageThis.getHashedPage();
			if(hashedPage!=pageThis.page){
				pageThis.goToPage(hashedPage);
			}
		});
	}
}





var searchableCategoryStuff = {};

var createSearchSelectors = function(page){
	middleSelector = '';
	if(page){
		middleSelector = '#'+page
	}
	return '#searchResults '+middleSelector+' .gameName,#searchResults '+middleSelector+' .gameDesc';
}

$(document).ready(function(){
	//Load the like buttons
	var fbroot = jQuery('fb-root');
	if (fbroot.length==0) {
		$(document.body).append("<div id='fb-root'></div>")
	}
	FB.XFBML.parse();
	
	//set up the pagination
	gameListPagination = new Tools.Pagination($('#stepSize').html(),$('#totalItems').html(),
	{
		firstVisibleItemSelector: '.firstVisibleItem',
		lastVisibleItemSelector: '.lastVisibleItem',
		buttonFirstSelector: '.pageNavButtonFirst',
		buttonPrevSelector: '.pageNavButtonPrev',
		buttonNextSelector: '.pageNavButtonNext',
		buttonLastSelector: '.pageNavButtonLast',
		onAjaxLoad: ajaxCallback
	});
	
	var searchTerms;
	if($("#searchResults").length>0 && $("#searchResults").attr("searchQuery")){
		if($("#searchResults").attr("suggestion")){
			searchTerms = $("#searchResults").attr("suggestion").trim().split(/\s+/);
		} else {
			searchTerms = $("#searchResults").attr("searchQuery").trim().split(/\s+/);
		}
		searchableCategoryStuff.highlighter = new Highlighter({
			searchTerms:searchTerms
		});
	}
	
	//set up the favorite buttons
	setUpFavClass();
	
	//setup the flyouts
	setUpFlyout();

	//highlight the searchterms
	if(searchableCategoryStuff.highlighter){
		searchableCategoryStuff.highlighter.highlight(createSearchSelectors());
	}
});

var ajaxCallback = function(pageId){
	setUpFavClass(pageId);
	setUpFlyout(pageId);
	FB.XFBML.parse(document.getElementById(pageId));
	if(searchableCategoryStuff.highlighter){
		searchableCategoryStuff.highlighter.highlight(createSearchSelectors(pageId));
	}
}

var setUpFlyout = function(pageId){
	selectorPrefix = '';
	if(pageId){
		selectorPrefix = '#'+pageId +' ';
	}
	var divToShow = null;
	var delayedShowId = null;
	var divShown = false;
	$('.gridView '+selectorPrefix+'.searchResult').mouseenter(function(e){
		divToShow = $(this);
		if(delayedShowId){
			clearTimeout(delayedShowId);
		}
		delayedShowId = setTimeout(function(){
			delayedShowId = null;
			divToShow.css('z-index','101');
			divToShow.find('.visiblePart').css('z-index','102');
			divToShow.find('.gameDetail').show("fade", {}, 700);
		},200);
	});
	$('.gridView '+selectorPrefix+'.searchResult').mouseleave(function(e){
		if(delayedShowId){
			clearTimeout(delayedShowId);
		}
		delayedShowId = null;
		$(this).css('z-index','100');
		$(this).find('.visiblePart').css('z-index','100');
		$(this).find('.gameDetail').stop(true, true).hide();
	});
}


var setFavoriteClass = function(item, className){
	$(item).removeClass('favoriteNoFav');
	$(item).removeClass('favoriteIsFav');
	$(item).removeClass('favoriteLoading');
	$(item).addClass(className);
}

var setUpFavClass = function(pageId){
	selectorPrefix = '';
	if(pageId){
		selectorPrefix = '#'+pageId+' ';
	}
	$(selectorPrefix+'.favoriteNoFav,'+selectorPrefix+'.favoriteIsFav').each(function(i,item){
		$(item).click(function(e){
			if($(item).hasClass('favoriteLoading')){
				return;
			}
			var action = 'add';
			if($(item).hasClass('favoriteIsFav')){
				action = 'remove'
			}
			var gameCode = $(item).attr("gameCode");
			var requestURL = '/home/club/favorites/'+action+'.do?games='+gameCode;
			if(typeof OmnitureCustomLink=='function'){
				OmnitureCustomLink($(item).attr("pageSection"));
			}
			setFavoriteClass($(item), 'favoriteLoading');
			var addFavsLocalizedText = $('addFavoritesLocalizedText').html();
			var removeFavsLocalizedText = $('removeFavoritesLocalizedText').html();
			$.ajax({
				url: requestURL,
				success: function(data) {
					if(action=='add'){
						setFavoriteClass(item, 'favoriteIsFav');
						$('#favIcon-' + gameCode).title=removeFavsLocalizedText;
					} else {
						setFavoriteClass(item, 'favoriteNoFav');
						$('#favIcon-' + gameCode).title=addFavsLocalizedText;
					}
				},
				error: function() {
					if(action=='add'){
						setFavoriteClass(item, 'favoriteNoFav');
						$('#favIcon-' + gameCode).title=removeFavsLocalizedText;
					} else {
						setFavoriteClass(item, 'favoriteIsFav');
						$('#favIcon-' + gameCode).title=addFavsLocalizedText;
					}
				}
			});
		});
	});
}


