if (!window.PageElements) { PageElements = {}; }
if (!window.GrantModules) { GrantModules = {}; }

/*
 *   Blur and focus textbox with default text
 *   Arguments:
 *       -- box_id: the id of the text box
 *       -- default_text: the default text of the text box
 */
GrantModules.BlurBox = function(box_id, default_text) {
    if(box_id == undefined) {
				logger.log('box_id is undefined');
				return;
    }
    
    var $box = $(box_id);
    $box.val(default_text);
    $box.blur(function() {
				if($box.val() == '') {
						$box.attr('style', 'color:#666666');
						$box.val(default_text);
				}
    }).focus(function() {
				if($box.val() == default_text) {
						$box.attr('style', 'color:#ffffff');
						$box.val('');
				}
    });
    
    return $box;
}

/*
 *   Animates the top menus
 */
GrantModules.MenuAnimations = function() {
    $('.main-nav li')
				.removeClass('highlight')
				.find('a')
				.mouseover(function() {
						$(this).stop(true, true).animate({'color': '#990000'}, 500);
				})
				.mouseout(function() {
						$(this).stop(true, true).animate({'color': '#ffffff'}, 500);
				});
    
    $('#bottom_nav > ul > li')
    //Disable current hover action
				.removeClass('highlight')
    
    //Get the link element
				.find('> a')
    
    //Add span with background in it and then add the animations
				.append('<span class="hover" />').each(function() {
						var $span = $('> span.hover', this).css('opacity', 0);
						$span.html($('> span.text', this).html());
						$(this).parent().hover(function () {
								$('> ul', this).stop(true, true).slideDown(500).delay(490);
								$span.stop(true, true).fadeTo(500, 1);
						}, function () {
								$('> ul', this).stop(true, true).slideUp(500).delay(490);
								$span.stop(true, true).fadeTo(500, 0);
						});
				})
						
						//Find the parent
						.parent()
    
    //Get the subnav
				.find('> ul > li > a')
    
    //Do the same thing as above
				.append('<span class="hover" />').each(function() {
						var $span = $('> span.hover', this).css('opacity', 0);
						$span.html($('> span.text', this).html());
						$(this).parent().hover(function () {
								$span.stop(true, true).fadeTo(500, 1);
						}, function () {
								$span.stop(true, true).fadeTo(500, 0);
						});
				});
}

/*
 *   Makes the rotator work
 *   Arguments
 *       -- rotator_div: the div that will become the rotator
 *       -- options: config options
 */
GrantModules.Rotator = function($rotator_div, options) {
    var o = options;
    var navigationNumbers = null;
    var navigationTitles = null;
    var selectedIndex = 1;
    var timer = 0;
    var timer_enabled = true;
    
    var num_items = $('.items .overlay').length;
    $('.items', $rotator_div).width(num_items * 1000);
    num_items = num_items - 1
    
    function startTimer() {
				if(timer_enabled)
						$(document).everyTime(6000, function() { nextStory() });
    }
    
    function stopTimer() {
				if(timer_enabled)
						timer_enabled = false;
				$(document).stopTime();
    }
    
    function nextStory(clearTimer) {
				var newIndex = 0;
				if(selectedIndex < num_items)
						newIndex = selectedIndex + 1;
				else
						newIndex = 0;

				switchStory(newIndex);	
				
				if(clearTimer) { 
						stopTimer();
						timer_enabled = true;
						startTimer();
				}		
    }
    
    $rotator_div.mouseenter(function() {
				stopTimer();
    }).mouseleave(function() {
				timer_enabled = true;
				$(document).oneTime(2000, function() { nextStory(true); } );
    });
    
    function switchStory(which, callback) {
				oldIndex = selectedIndex;
				selectedIndex = which;
				
				diff = Math.abs(selectedIndex - oldIndex);
				
				var $prev_nav_element = $('div#rotator_nav li#' + oldIndex);
				var $current_nav_element = $('div#rotator_nav li#' + selectedIndex)
				var $nav_container = $('#rnav_container');
				
				//Animate nav menu
				$prev_nav_element.css({ 'font-size': '10px' })
				$current_nav_element.css({ 'font-size': '12px' })
				
				offset = ($nav_container.width() - $current_nav_element.width()) / 2;
				$nav_container.scrollTo($current_nav_element, { duration: o.overlay_duration * diff, offset: -offset, easing: 'easeOutQuad' });
				
				//Animate overlays			
				var $items_container = $('.items-container', $rotator_div);
				var $overlays = $('.items .overlay', $items_container);
				
				$items_container.scrollTo($overlays[selectedIndex], {
						queue:true,
						axis:'x',
						duration: o.overlay_duration * diff,
						onAfter: callback
				});
				
    }
    
    var rotatorNav = function($container) {
				var $first_el = $('li:first-child', $container);
				$first_el.css('font-size', '12px');
				var first_el_margin = ($container.width() - $first_el.width()) / 2;
				$first_el.css('margin-left', first_el_margin);
				$container.scrollTo(0);
				if(!$.browser.isIE) {
						$container.fadeTo(500, 1); //Fade in if browser isn't ie and supports cool effects
				}

				var $prev_element = $first_el;

				var navFromPoint = function(xval, yval) {
						var return_element = null;
						$('div#rnav_container li').each(function(index, el){
								var $theel = $(el);
								$(this).data('top', $theel.offset().top);
								$(this).data('bottom', $(this).data('top') + $theel.outerHeight(true));
								$(this).data('left', $theel.offset().left);
								$(this).data('right', $(this).data('left') + $theel.outerWidth(true));
								if(xval >= $(this).data('left') && xval <= $(this).data('right') && yval >= $(this).data('top') && yval <= $(this).data('bottom')) {
										return_element = $theel;
								}
						});
						return return_element;
				}

				var clickNav = function(el) {
						switchStory(parseInt($(el).attr('id')));
				}

				$('div#rotator_nav').click(function(event) {
						var el = navFromPoint(event.pageX, event.pageY);
						if(el != null) {
								clickNav(el);
						}
				}).mousedown(function() {
						return false;
				});
    }
    
    switchStory(0, function() {
				if($.browser.isIE) { //Don't bother with cool fade
						rotatorNav($('#rnav_container'));
						startTimer();
				} else {
						$rotator_div.fadeTo(500, 1, function() {
								rotatorNav($('#rnav_container'));
								startTimer();
						});
				}
    });
    
    return $rotator_div;
}

GrantModules.Filter = function() {
    var filter = "";
    
    var ajax = {
				filterUrl: "/products/attr_list/",
				buildUrl: function(base, what, filter) {
						url = base;
						if(what != null) {
								url += "?what=" + what;
								if(filter != null) {
										url += "&filter=" + filter;
								}
						} else if (filter != null) {
								url += "?filter=" + filter;
						}
						return url;
				}
				
    }
    
    $('filter-box').each(function(el) {
				var attr = $(el).attr('rel');
    });
}

GrantModules.ProductList = function() {
    var scrollElement = window;
    var refElement = $("div#content");
    
    var ajax = {    
				loading: false,
				results: false,
				done: false,
				showLoadingNotification: function() {
						$("#ajax-loader").stop(true, true).fadeIn('fast');
						ajax.loading = true;
				},
				hideLoadingNotification: function() {
						$("#ajax-loader").stop(true, true).fadeOut('fast');
						ajax.loading = false;
				},
				loadData: function(url, container, totop) {
						if(!ajax.loading && !ajax.done) {
								$.ajax({
                    url: url,
                    data: {},
                    beforeSend: ajax.showLoadingNotification,
                    success: function(data) { ajax.results = ajax._loadDataCallback(data, container, totop) }
								});
						}
						return ajax.results;
				},
				_loadDataCallback: function(data, container, totop) {
						if(data != "none") {
								ajax.done = false;
								var $mod_data = $(data);
								$(container).find('td').removeClass('new');
								$mod_data.find('td').css('opacity', 0).addClass('new');                
								var $mod_container = $(container).append($mod_data);
								
								$mod_container.find('td').hover(function (){
										$(this).addClass('selected');
								}, function() { $(this).removeClass('selected'); });
								
								$mod_container.find('a.quick-view').fancybox({
										'width': 450,
										'height': 310,
										'autoScale': false,
										'type': 'iframe'
								});
								
								//$mod_container.find('td.new').animate({ opacity: 1 }, 800);
								(function fadenext(jq){
										jq.eq(0).animate({ opacity: 1 }, 100, function(){
												(jq=jq.slice(1)).length && fadenext(jq);
										});
								})($mod_container.find('td.new')); //Fade in each td
								ajax.hideLoadingNotification();
								if(totop != undefined)
										window.scrollTo(0,0);
								return true;
						}
						ajax.done = true;
						ajax.hideLoadingNotification();
						return false;
				}
    }
    
    var filter = {
				filtered: false,
				filter: function(url, page, container, filter) {
						url += "?filter=" + filter + "&page=";
						if(page == 1)
								ajax.loadData(url + page, container, true);
						else
								ajax.loadData(url + page, container);
						return url;
				}
    }
    
    var currentPage = 1;
    var regex = new RegExp("/products/browse/([\\w\\-]+)/?(([\\w\\-]+)/?)?");
    var category = "";
    var application = "";
    var matches = regex.exec(window.location);
    if(matches) {
				category = matches[1];
				application = matches[3];
    }
    
    var url = "/products/product_list/"+category+"/"
    
    if(application != undefined) {
				url += application+"/";
    }
    
    url += "?page=";
    
    
    
    var container = $('table#product-table');
    if(currentPage == 1)
				ajax.loadData(url + currentPage, container, true);
    else
				ajax.loadData(url + currentPage, container);
    
    //Infinite Scroll
    $(scrollElement).scroll(function() {
				if($(this).scrollTop() + $(scrollElement).height() >= $(refElement).offset().top + $(refElement).height()) {
						if(!ajax.loading) {
								currentPage += 1;
								logger.log(currentPage);
								result = ajax.loadData(url + currentPage, container);
								if(!result)
										currentPage -= 1;
						}
				}
    });
    
    $('div.filter-list a').each(function(el) {
				var attr = $(this).parent().attr('rel');
				$(this).click(function() {
						
				});
    });
    
    var filters = [];
    
    function filterProducts() {
				filterstring = filters.join(',');
				filter_url = "/products/product_list/"+category+"/";
				if(application != undefined) {
						filter_url += application+"/";
				}
				filter_url += "?filter=" + filterstring + "&page=";
				url = filter_url;
				currentPage = 1;
				$(container).empty();
				ajax.done = false;
				if(currentPage == 1) 
						result = ajax.loadData(url + currentPage, container, true);
				else
						result = ajax.loadData(url + currentPage, container);
    }

    function clearSelection() {
				filters = [];
				$.each($('div.filter-box > a.selected'), function(i, x) {
						$(x).removeClass('selected');
						$(x).parent().removeClass('selected');
				});
				filterProducts();
				loadFilters('div.filter-box');
    }

    $('div.filter_bar a').click(function() {
				clearSelection();
    });
    
    //Load filter
    function loadFilters(containers) {
				$(containers).each(function(i, el) {
						var attr = $(el).attr('rel');
						var the_url = "/products/attr_list/"+category+"/";
						if(application != undefined) {
								the_url += application+"/";
						}
						the_url += "?what=" + attr
						if(filters.length != 0) {
								filterstring = filters.join(',');
								the_url += "&filter=" + filterstring;
						}
						$.ajax({
								url: the_url,
								data: {},
								beforeSend: ajax.showLoadingNotification,
								success: function(data) { 
										$(el).html(data);
										$(el).find('a').click(function() {
												var $a = $(this);
												var filter = $a.parent().attr('rel') + ":" + $a.html();
												if($a.hasClass('selected')) {
														filters.splice(filters.indexOf(filter),1);
														$a.removeClass('selected');
														$a.parent().removeClass('selected');
												} else {
														in_array = false;
														$.each(filters, function(i, x) {
																if(x.indexOf($a.parent().attr('rel')) != -1) {
																		filters[i] = filter;
																		in_array = true;
																}
														});
														if(!in_array)
																filters.push(filter);
														$a.parent().find('a').removeClass('selected');
														$a.addClass('selected');
														$a.parent().addClass('selected');
												}
												filterProducts();
												loadFilters('div.filter-box:not(.selected)');
										});
								}
						});
				});
    }
    
    loadFilters('div.filter-box');
    
    return {
				ajax: ajax
    }
}

GrantModules.InstructionManualSearch = function() {
    $('#inst-search').fancybox({
				'width': 450,
				'height': 310,
				'autoScale': false,
				'type': 'iframe'
    });
}

GrantModules.ApplicationSearch = function(select_container) {
    var $select_container = $(select_container);
    var $year_select = $select_container.find('#vehicle_year');
    var $make_select = $select_container.find('#vehicle_make');
    var $model_select = $select_container.find('#vehicle_model');
    var $submodel_select = $select_container.find('#vehicle_submodel');
    
    var ajax = {    
				loading: false,
				results: false,
				done: false,
				showLoadingNotification: function() {
						$("#ajax-loader").stop(true, true).fadeIn('fast');
						ajax.loading = true;
				},
				hideLoadingNotification: function() {
						$("#ajax-loader").stop(true, true).fadeOut('fast');
						ajax.loading = false;
				},
				loadData: function(url, container) {
						if(!ajax.loading && !ajax.done) {
								$.ajax({
                    url: url,
                    data: {},
                    beforeSend: ajax.showLoadingNotification,
                    success: function(data) { ajax.results = ajax._loadDataCallback(data, container) }
								});
						}
						return ajax.results;
				},
				_loadDataCallback: function(data, container, callback) {
						if(data != "none") {
								ajax.done = false;
								var $mod_data = $(data);
								$(container).find('td').removeClass('new');
								$mod_data.find('td').css('opacity', 0).addClass('new');                
								var $mod_container = $(container).append($mod_data);
								
								$mod_container.find('td').hover(function (){
										$(this).addClass('selected');
								}, function() { $(this).removeClass('selected'); });
								
								$mod_container.find('a.quick-view').fancybox({
										'width': 450,
										'height': 310,
										'autoScale': false,
										'type': 'iframe'
								});
								
								//$mod_container.find('td.new').animate({ opacity: 1 }, 800);
								(function fadenext(jq){
										jq.eq(0).animate({ opacity: 1 }, 100, function(){
												(jq=jq.slice(1)).length && fadenext(jq);
										});
								})($mod_container.find('td.new')); //Fade in each td
								ajax.hideLoadingNotification();
								window.scroll(0, 625);
								return true;
						}
						ajax.done = true;
						ajax.hideLoadingNotification();
						return false;
				}
    }
    
    function populate_select(select, url) {
				select.options.length = 0;
				$(select).nextAll('select').each(function(i, el) {
						$(el).fadeOut('fast').addClass('hidden');
				});
				select.options[0] = new Option($(select).attr('rel'), '[none]');
				$.ajax({
            url: url,
            data: {},
            success: function(data) {
								if(data.length != 0) {
                    $(select).fadeIn('fast').removeClass('hidden');
                    $(data).each(function(i, el) {
												select.options[select.options.length] = new Option(el.label, el.id);
										});
								}
            },
            dataType: 'json'
				});
    }
    
    $select_container.find('select').change(function() {
				$(this).blur();
				id = $(this).attr('id');
				this_val = $(this).val();
				if(this_val != "[none]") {
						year = $year_select.val();
						make = $make_select.val();
						model = $model_select.val();
						submodel = $submodel_select.val();
						url = '/fitments/'
						next_el = null;
						switch(id) {
						case 'vehicle_year':
								url += 'makes/'+year;
								next_el = $make_select;
								break;
						case 'vehicle_make':
								url += 'models/'+year+'/'+make;
								next_el = $model_select;
								break;
						case 'vehicle_model':
								url += 'submodels/'+year+'/'+make+'/'+model;
								next_el = $submodel_select;
								break;
						}
						if(next_el != null)
								populate_select(next_el.get(0), url);
				}
    });
    
    if($select_container.parent().parent().hasClass('top-app-search')) { //init dropdown app_search
				$('li.application-search > a').click(function() {
						$(this).parent().toggleClass('clicked');
				});
				
				$('li.application-search a.search').click(function() {
						year = $year_select.val();
						make = $make_select.val();
						model = $model_select.val();
						submodel = $submodel_select.val();
						if(year == "[none]" || make == "[none]" || model == "[none]") {
								alert('Please select your application')
						} else { //Do app search
								if(submodel == "[none]")
										submodel = 1;
								
								if(isPage('application_search')) {
										url = '/fitments/fitments/'+year+'/'+make+'/'+model+'/'+submodel;
										ajax.loadData(url, $('table#product-table').empty());
								} else {
										url = '/products/application_search/#'+year+'/'+make+'/'+model+'/'+submodel;
										window.location = url;
								}
						}
				});

				//recommendation engine search
				$('li.application-search a.recSearch').click(function() {
						year = $year_select.val();
						make = $make_select.val();
						model = $model_select.val();
						submodel = $submodel_select.val();
						if(year == "[none]" || make == "[none]" || model == "[none]") {
								alert('Please select your application')
						} else { //Do app search
								//get current product_id from url to use in our end filter 					
								product_id = window.location.pathname.split('/')[4];
								
								url = '/products/recommend/4/'+product_id+'/7/fitment:true/yr:'+year+'/make:'+make+'/model:'+model+'/submodel:'+submodel;
								parent.window.location = url;
						}
				});


    } else { //init normal search
				$('a.find-your-application').click(function() {
						year = $year_select.val();
						make = $make_select.val();
						model = $model_select.val();
						submodel = $submodel_select.val();
						if(year == "[none]" || make == "[none]" || model == "[none]") {
								alert('Please select your application')
						} else { //Do app search
								if(submodel == "[none]")
										submodel = 1;

								url = '/fitments/fitments/'+year+'/'+make+'/'+model+'/'+submodel;
								ajax.loadData(url, $('table#product-table').empty());
						}
				});

				if(getHash() != "") { //load from hash
						hash = getHash();
						array = hash.split('/');
						url = '/fitments/fitments/'+array[0]+'/'+array[1]+'/'+array[2]+'/'+array[3];
						ajax.loadData(url, $('table#product-table').empty());
				}

    }
    
    //Load years
    populate_select($year_select.get(0), '/fitments/years/');
    
}

GrantModules.ShoppingBar = function() {
    var total = 0.00;
    
    cart = new Array();
    
    var updateTotal = function(newTotal) {
				total = newTotal;
				$('.shopping-bar #subtotal-cart').html(total.toFixed(2));
    }
    
    var addToCart = function(id, img, price, addToArray, category_id) {
				index = $('div#product_'+id).size();
				/*        if($('div#product_'+id).size() != 0) {
									quantity = $('div#product_'+id+' span.quantity').html();
									quantity = parseInt(quantity) + 1;
									$('div#product_'+id+' span.quantity').html(quantity);
									} else {*/
				html = '<div id="product_'+id+'" class="product index'+index+'">\
<a href="/products/view/'+id+'/"><img class="product-image" src="'+img+'" height="21px" /></a>\
<div class="remove">\
<a href="javascript:PageElements.ShoppingBar.removeFromCart(\''+id+'\',\''+index+'\');">Remove</a>\
</div>\
<iframe scrolling="no" frameborder="0" src="/products/quick_view/'+id+'/?addtocart=false" hspace="0"></iframe>\
</div>';
				$('.shopping-bar .products').append(html);
				updateTotal(total+price);
				
				if(addToArray != undefined) {
						if(cart.length == 0)
								$('.shopping-bar').slideDown().addClass('shown');
						cart.push({id:id, img:img, price:price});
						setCookie('shopping_cart', JSON.stringify(cart));
						$.get('/set_cookie/', function(data) {
								
						});
						
						//Kick off the Recommendation engine for Installation Kits
						//as long as the product has been sucessfully added to the cart
						if(category_id == 1) {	//only run for Steering wheels				
								rec_engine = '/products/recommend/1/'+id;
								parent.$.fancybox(rec_engine, 	{
										'width': 450,
										'height': 310,
										'autoScale': false,
										'type': 'iframe',
										'onClosed': PageElements.ShoppingBar.flashBar
								});
						} else {
								//if we don't need the recommendation engine, then scroll window and close fancybox
								parent.$.fancybox.close();
								flashBar();
						}
				}
    }

    var flashBar = function() {
				window.scroll(0, 0);
				$('.shopping-bar').css({'background-color':'#ffffff'});
				$('.shopping-bar').animate({'background-color':'#4e0000'}, 2500);
    }

    var removeFromCart = function(id, index) {
				var hasBeenRemoved = false;
				$(cart).each(function(i, el) {
						if(el.id == id && !hasBeenRemoved) {
								updateTotal(total - el.price);
								cart.splice(i,1);
								$('.shopping-bar .products #product_'+id).remove(".index"+index);
								hasBeenRemoved = true;
						}
				});
				if(cart.length == 0)
						$('.shopping-bar').slideUp().removeClass('shown');
				setCookie('shopping_cart', JSON.stringify(cart));
    }

    cookie_cart = getCookie('shopping_cart');
    if(cookie_cart == "") {
				//setCookie('shopping_cart', '[{id:"1", img:"/images/product-images/temp-dark.jpg", price:176.80}, {id:"10", img:"/images/product-images/temp-dark.jpg", price:47.12}]');
    } else {
				cart = eval(cookie_cart);
    }

    $(cart).each(function(i, el) {
				addToCart(el.id, el.img, el.price);
    });

    if(cart.length != 0)
				$('.shopping-bar').show().addClass('shown');

    $('.shopping-bar .product').live('mouseenter mouseleave', 
																		 function(event) {
																				 if(event.type == 'mouseover') {
																						 $(this).find('iframe').stop().animate({
																								 width: ['450px', 'swing'],
																								 height: ['260px', 'swing'],
																								 opacity: '1'
																						 }, 500);
																						 $(this).find('.remove').stop().show().animate({ width:"55px" }, 500);
																				 } else {
																						 $(this).find('iframe').stop().animate({
																								 width: ['0px', 'swing'],
																								 height: ['0px', 'swing'],
																								 opacity: '0'
																						 }, 500);
																						 $(this).find('.remove').stop().animate({ width:"1px" }, { duration: 500, complete: function() { $(this).hide(); }});
																				 }
																		 }
																		);

    updateTotal(total);

    return {
				addToCart: addToCart,
				flashBar: flashBar,
				removeFromCart: removeFromCart
    }
}


GrantModules.Recommended = function() {
    var scrollElement = window;
    var refElement = $("div#content");
    
    var ajax = {    
				loading: false,
				results: false,
				done: false,
				showLoadingNotification: function() {
						$("#ajax-loader").stop(true, true).fadeIn('fast');
						ajax.loading = true;
				},
				hideLoadingNotification: function() {
						$("#ajax-loader").stop(true, true).fadeOut('fast');
						ajax.loading = false;
				},
				loadData: function(url, container, totop) {
						if(!ajax.loading && !ajax.done) {
								$.ajax({
                    url: url,
                    data: {},
                    beforeSend: ajax.showLoadingNotification,
                    success: function(data) { ajax.results = ajax._loadDataCallback(data, container, totop) }
								});
						}
						return ajax.results;
				},
				_loadDataCallback: function(data, container, totop) {
						if(data != "none") {
								ajax.done = false;
								var $mod_data = $(data);
								$(container).find('td').removeClass('new');
								$mod_data.find('td').css('opacity', 0).addClass('new');                
								var $mod_container = $(container).append($mod_data);
								
								$mod_container.find('td').hover(function (){
										$(this).addClass('selected');
								}, function() { $(this).removeClass('selected'); });
								
								$mod_container.find('a.quick-view').fancybox({
										'width': 450,
										'height': 310,
										'autoScale': false,
										'type': 'iframe'
								});
								
								//$mod_container.find('td.new').animate({ opacity: 1 }, 800);
								(function fadenext(jq){
										jq.eq(0).animate({ opacity: 1 }, 100, function(){
												(jq=jq.slice(1)).length && fadenext(jq);
										});
								})($mod_container.find('td.new')); //Fade in each td
								ajax.hideLoadingNotification();
								if(totop != undefined)
										window.scrollTo(0,0);
								return true;
						}
						ajax.done = true;
						ajax.hideLoadingNotification();
						return false;
				}
    }
    
    

    var url = window.location.pathname.replace("recommend", "recommend_list");	

    var container = $('table#product-table');

    ajax.loadData(url, container);      

    
    return {
				ajax: ajax
    }
}


GrantModules.CompanyHistory = function(){

    var $tabs = $('#tabs').tabs();

    $(".ui-tabs-panel").each(function(i){

				var totalSize = $(".ui-tabs-panel").size() - 1;

				if (i != totalSize) {
						next = i + 2;
						$(this).append("<a href='#' class='next-tab mover' rel='" + next + "'>Next Page &#187;</a>");
				}

				if (i != 0) {
						prev = i;
						$(this).append("<a href='#' class='prev-tab mover' rel='" + prev + "'>&#171; Prev Page</a>");
				}

    });

    $('.next-tab, .prev-tab').click(function() { 
				$tabs.tabs('select', $(this).attr("rel"));
				return false;
    });

};

function GeocodeCallback(result) {
    PageElements.DealerLocator.geocodeCallback(result);
}

GrantModules.DealerLocator = function() {
    InfoBoxSet = function() {
				var set = {}
				var currentlyVisible = false; 

				function asKey(latitude, longitude) {
						return "(" + latitude + "," + longitude + ")";
				}

				function getInfoBoxAt(latitude, longitude) {
						return set[asKey(latitude, longitude)];
				}

				function setInfoBoxAt(infobox, latitude, longitude) {
						set[asKey(latitude, longitude)] = infobox;
				}

				function unsetCurrentlyVisible() {
						if (currentlyVisible) {
								set[currentlyVisible].setOptions({visible:false});
						}
						currentlyVisible = false;
				}

				function setCurrentlyVisible(latitude, longitude) {
						unsetCurrentlyVisible();
						getInfoBoxAt(latitude, longitude).setOptions({visible:true});
						currentlyVisible = asKey(latitude, longitude);
				}	
				
				function add(infobox, latitude, longitude) {
						setInfoBoxAt(infobox, latitude, longitude);
				}

				function clear() {
						unsetCurrentlyVisible();
						set = {};
				}

				function showInfoBoxAt(latitude, longitude) {
						setCurrentlyVisible(latitude, longitude);
				}

				function showCallback(evt) {
						if (evt.targetType == "pushpin") {
								var pinLoc = evt.target.getLocation();
								setCurrentlyVisible(pinLoc.latitude, pinLoc.longitude);
						}
				}

				function hideCallback(evt) {
						if (evt.targetType == 'pushpin') {
								var pinLoc = evt.target.getLocation();
								unsetCurrentlyVisible();
						}
				}

				function hideAll() {
						unsetCurrentlyVisible();
				}
				
				return {
						add: add,
						clear: clear,
						showInfoBoxAt: showInfoBoxAt,
						showCallback: showCallback,
						hideCallback: hideCallback,
						hideAll: hideAll
				};
    }

    var bingMapsKey = "AsZzbOP8OAu22q2kBxOsP7F8jO6DPGCJCW2GYzAyz5LMJ6I2l_erx51V_swP2ayw";
    var infoBoxes = InfoBoxSet();
    var shownInfobox = false;
    var mapWidth = 730;
    var mapHeight = 480;
    var buffer = 2;

    function initMap() {
				map = new Microsoft.Maps.Map(document.getElementById("mapDiv"),
																		 {credentials: bingMapsKey});
    }

    /*function centerOnZip(zip) {
      var request = "http://dev.virtualearth.net/REST/v1/Locations/";
      request += $(".search-box").val() + "?output=json&jsonp=GeocodeCallback&key=" + bingMapsKey;
      var script = document.createElement("script");
      script.setAttribute("type", "text/javascript");
      script.setAttribute("src", request);
      document.body.appendChild(script);
      }*/

    function calculateBestMapView(points) {
				var minLat = points[0].Latitude;
				var maxLat = points[0].Latitude;
				var minLon = points[0].Longitude;
				var maxLon = points[0].Longitude;
				
				var zoomLevel = 0;

				var zoomWidth = 0;
				var zoomHeight = 0;
				
				var result = {center: 0, zoom: 0}

				for (i = 1; i < points.length; i++) {
						if (points[i].Latitude < minLat) {
								minLat = points[i].Latitude;
						}
						else if (points[i].Latitude > maxLat) {
								maxlat = points[i].Latitude;
						}
						if (points[i].Longitude < minLon) {
								minLon = points[i].Longitude;
						}
						else if (points[i].Longitude > maxLon) {
								maxLon = points[i].Longitude;
						}
				}
				
				result.center = new Microsoft.Maps.Location((maxLat + minLat) / 2.0,
																										(maxLon + minLon) / 2.0);

				if (maxLon != minLon && maxLat != minLat) {
						zoomWidth = Math.log(360.0 / 256.0 * (mapWidth - 2 * buffer) / (maxLon - minLon));
						zoomWidth /= Math.log(2);
						zoomHeight = Math.log(180.0 / 256.0 * (mapHeight - 2 * buffer) / (maxLat - minLat));
						zoomHeight /= Math.log(2);
				}

				if (zoomWidth < zoomHeight) {
						zoomLevel = zoomWidth;
				} else {
						zoomLevel = zoomHeight;
				}

				result.zoom = Math.floor(zoomLevel);
				return result;
    }

    function getLocationDescription(res) {	
				return res.AddressLine + ", " + res.Locality + ", "  + res.AdminDistrict + " " + res.PostalCode;
    }

    function addLocationToList(loc, uid) {
				html  = "<li>";
				html += '<a href="javascript:PageElements.DealerLocator.showInfoboxAt(\'' + loc.Latitude + '\',\'' + loc.Longitude + '\')">';
				html += loc.StoreName
				html += "</a><br/>";
				html += '<span id="desc_' + uid + '">' + getLocationDescription(loc);
				html += "</span><br/>";
				if (loc.PhoneNo) {
						html += '<b>Phone:</b> ' + loc.PhoneNo;
				}
				if (loc.FaxNo) {
						html += '<br/><b>Fax:</b> ' + loc.FaxNo;
				}
				if (loc.PhoneNo || loc.FaxNo) {
						html += "<br/>";
				}
				html += '<a href="javascript:PageElements.DealerLocator.showDirectionsFor(' + uid + ');" style="font-size: 11px">Get Directions</a>';
				if (loc.Website) {
						html += ' | <a target="_blank" style="font-size: 11px;" href="';
						var httpPattern = /https?:\/\//;
						if (!loc.Website.match(httpPattern)) {
								html += "http://";
						}
						html += loc.Website + '">Visit Website</a>';
				}
				if (loc.Email) {
						html += ' | <a style="font-size: 11px;" href="mailto:' + loc.Email + '">Email</a>';
				}
				html += "</li>";
				$("#locations-list").append(html);
    }

    function addItineraryItemToList(item) {
				html  = "<li>";
				html += item.instruction.text;
				html += "</li>";
				$("#locations-list").append(html);
    }

    function addResults(res) {
				// Clear the locations list
				$("#locations-list").html("");

				if (res.d.results &&
						res.d.results.length > 0) {
						var dealers = res.d.results;
						for (var i = 0; i < dealers.length && i < 20; i = i + 1) {
								// Create a new pushpin
								var location = new Microsoft.Maps.Location(dealers[i].Latitude,
																													 dealers[i].Longitude);
								var pushpin = new Microsoft.Maps.Pushpin(location);
								
								desc = getLocationDescription(dealers[i]);
								addLocationToList(dealers[i], i);

								// Create an infobox for the pushpin

								var px = map.tryLocationToPixel(pushpin.getLocation());

								var html = '<div class="infobox">';
								html += '<a href="javascript:PageElements.DealerLocator.onCloseInfobox();" class="close">X</a><div class="title">' + dealers[i].StoreName + '</div>';
								html += '<div class="infobox-inner"><div class="description">';
								html += desc + "<br/>";
								if (dealers[i].PhoneNo) {
										html += '<b>Phone:</b> ' + dealers[i].PhoneNo;
								}
								if (dealers[i].FaxNo) {
										html += '<br/><b>Fax:</b> ' + dealers[i].FaxNo;
								}
								html += "<br/>";
								html += '<div id="infobox-links">';
								html += '<a href="javascript:PageElements.DealerLocator.showDirectionsFor(';
								html += i + ');">Get Directions</a>';
								if (dealers[i].Website) {
										html += ' | <a target="_blank" href="';
										var httpPattern = '/https?:\\\\/';
										if (!dealers[i].Website.match(httpPattern)) {
												html += "http://";
										}
										html += dealers[i].Website + '">Visit Website</a>';
								}
								if (dealers[i].Email) {
										html += ' | <a href="mailto:' + dealers[i].Email + '">Email</a>';
								}
								html += '</div></div></div></div>';
								html += '<div style="width: 33px; height: 38px; overflow: hidden; position: absolute; z-index: 1; left: -13px; top: -37px;"><img src="/img/location_pointer.png"></div>';

								pinInfobox = new Microsoft.Maps.Infobox(pushpin.getLocation(),
																												{
																														htmlContent: html,
																														visible: false,
																														offset: new Microsoft.Maps.Point(0, 15)
																												});

								pinInfobox.setHtmlContent(html);

								infoBoxes.add(pinInfobox, location.latitude, location.longitude);
								map.entities.push(pushpin);
								map.entities.push(pinInfobox);

								Microsoft.Maps.Events.addHandler(pushpin, 'click', infoBoxes.showCallback);
								Microsoft.Maps.Events.addHandler(map, 'viewchange', infoBoxes.hideCallback);
						}

						map.setView(calculateBestMapView(res.d.results));
				} else {
						alert("Error, no results were returned for that zipcode");
				}
    }

    function addDirections(res) {
				// Clear the locations (directions) list
				$("#locations-list").html("");

				if (res &&
						res.resourceSets &&
						res.resourceSets.length > 0 &&
						res.resourceSets[0].resources &&
						res.resourceSets[0].resources.length > 0) {
						// Create start and end location markers
						var startLoc = res.resourceSets[0].resources[0].routeLegs[0].startLocation;
						var endLoc = res.resourceSets[0].resources[0].routeLegs[0].endLocation;

						var locs = new  Array(startLoc, endLoc);
						for (var i = 0; i < locs.length; i = i + 1) {
								var location = new Microsoft.Maps.Location(locs[i].point.coordinates[0],
																													 locs[i].point.coordinates[1]);
								var pushpin = new Microsoft.Maps.Pushpin(location);

								var name = locs[i].name;
								if (i == 0) {
										name = "Depart " + name;
								} else {
										name = "Arrive " + name;
								}

								pinInfobox = new Microsoft.Maps.Infobox(pushpin.getLocation(),
																												{
																														title: name,
																														visible: true,
																														height: 45,
																														offset: new Microsoft.Maps.Point(0, 15)
																												});

								infoBoxes.add(pinInfobox, location.latitude, location.longitude);
								map.entities.push(pushpin);
								map.entities.push(pinInfobox);
						}

						// Create the route line
						var itinerary = res.resourceSets[0].resources[0].routeLegs[0].itineraryItems;
						var routepoints = new Array();

						for (var i = 0; i < itinerary.length; i++) {
								routepoints[i] = new Microsoft.Maps.Location(itinerary[i].maneuverPoint.coordinates[0],
																														 itinerary[i].maneuverPoint.coordinates[1]);
								addItineraryItemToList(itinerary[i]);
						}


						// Draw the route on the map
						var routeshape = new Microsoft.Maps.Polyline(routepoints, {strokeColor:new Microsoft.Maps.Color(200,0,0,200)});
						map.entities.push(routeshape);

						var bbox = res.resourceSets[0].resources[0].bbox;
						var viewBoundaries = Microsoft.Maps.LocationRect.fromLocations(new Microsoft.Maps.Location(bbox[0], bbox[1]), new Microsoft.Maps.Location(bbox[2], bbox[3]));
						map.setView({bounds: viewBoundaries});
				}				
    }

    function showInfoboxAt(latitude, longitude) {
				infoBoxes.showInfoBoxAt(latitude, longitude);
    }

    function geocodeCallback(result) {
				if (result &&
						result.resourceSets &&
						result.resourceSets.length > 0 &&
						result.resourceSets[0].resources &&
						result.resourceSets[0].resources.length > 0) 
				{
						bestView = calculateBestMapView(result.resourceSets[0].resources);
						map.setView(bestView);
				}
    }

    function showDirectionsFor(id) {
				$("#end").val($("#desc_" + id).html());
				$("#directions").slideDown('slow');
    }

    $("#distance-picker ul li").each(function(i) {
				$(this).click(function() {
						if ($(this).attr("id") != "selected") {
								$("#distance-picker ul li#selected").attr("id", "");
								$(this).attr("id", "selected");
						}
				});
    });

    $(".search-box-submit").click(function() {
				var zip_re = /\d{5}/;
				var distance = $("#distance-picker ul li#selected a").html();
				var zipcode = $(".search-box").val();
				if (!zip_re.test(zipcode)) {
						alert("Zip code is invalid");
						return false;
				}
				$(".search-box-submit").attr("src", "/img/ajax-loader.gif");
				$.ajax({
						url: "/dealer_locator/query",
						type: "POST",
						data: {query: zipcode, dist: distance},
						dataType: "json",
						success: function(data) {
								infoBoxes.clear();
								map.entities.clear();
								addResults(data);
								$("#store-locations").slideDown('slow');
						},
						error: function(res) {
								var obj = $.parseJSON(res.responseText);
								alert("Error, " + obj.msg);
						}
				});
				$(".search-box-submit").attr("src", "/img/maps_search_btn.jpg");
				return false; // Don't submit
    });

    $(".get-directions-submit").click(function() {
				var start = $("#start").val();
				var end   = $("#end").val();
				$.ajax({
						url: "/dealer_locator/directions",
						type: "POST",
						data: {start: start, end: end},
						dataType: "json",
						success: function(data) {
								infoBoxes.clear();
								map.entities.clear();
								addDirections(data);
								$("#store-locations").slideDown('slow');
						},
						error: function(res) {
								var obj = $.parseJSON(res.responseText);
								alert("Error, " + obj.msg);
						}
				});
    });

    $("#dealer-list-hider").click(function() {
				if ($("#dealer-list-hider").hasClass("minus")) {
						$("#locations-list").slideUp('fast');
						$("#dealer-list-hider").removeClass("minus");
						$("#dealer-list-hider").addClass("plus");
						$("#dealer-list-hider").html("Show List");
				} else {
						$("#locations-list").slideDown('fast');
						$("#dealer-list-hider").removeClass("plus");
						$("#dealer-list-hider").addClass("minus");
						$("#dealer-list-hider").html("Hide List");
				}
    });

    var initialValue = $("#start").val();
    $("#start").focus(function() {
				if ($("#start").val() == initialValue) {
						$("#start").val("");
				}
    });
    $("#start").blur(function() {
				if ($("#start").val() == "") {
						$("#start").val(initialValue);
				}
    });

    $("#switch").click(function() {
				var tmp = $("#start").val();
				$("#start").val($("#end").val())
				$("#end").val(tmp);
    });

    $("#close-directions").click(function() {
				$("#directions").slideUp('slow');
    });

    function onCloseInfobox() {
				infoBoxes.hideAll();
    }

    initMap();

    return {
				geocodeCallback: geocodeCallback,
				showInfoboxAt: showInfoboxAt,
				showDirectionsFor: showDirectionsFor,
				onCloseInfobox: onCloseInfobox
    }
};

/*****************************/
/* Fix IE JS *****************/
/*****************************/

var addIEClass = function() {
    if($.browser.isIE) {
				$('html').addClass('ie');
				if($.browser.lessthanIE6) { $('html').addClass('ie5'); }
				if($.browser.lessthanIE7) { $('html').addClass('ie6'); }
				if($.browser.lessthanIE8) { $('html').addClass('ie7'); }
				else { $('html').addClass('ie8'); }
    }
}

GrantModules.WhereToBuy = function() {
    $("#top_nav li.where-to-buy > a").click(function() {
				if ($("#top_nav li.where-to-buy").hasClass("clicked")) {
						$("#top_nav li.where-to-buy").removeClass("clicked");
				} else {
						$("#top_nav li.where-to-buy").addClass("clicked");
				}
    });
}

addLoadEvent(addIEClass);

var addLastChild = function() {
    if($.browser.isIE) {
				$(':last-child').addClass('last-child');
    }
}

addLoadEvent(addLastChild);

/*****************************/
/*****************************/
/*****************************/

/*
 *   Runs when document is ready.
 */
$(document).ready(function() {
    //logger.on(); //Turn on debugging

    //All Pages
    PageElements.SearchBox = GrantModules.BlurBox('input#search_box', 'part #, product name');
    PageElements.MenuAnimations = GrantModules.MenuAnimations();
    PageElements.ShoppingBar = GrantModules.ShoppingBar();
    PageElements.ApplicationSearch = GrantModules.ApplicationSearch('.top-app-search .selects');
    PageElements.WhereToBuy = GrantModules.WhereToBuy();

    //Home Page
    if(isPage('home')) {
				PageElements.Rotator = GrantModules.Rotator($('#rotator'), { overlay_duration: 500 });
    }
    if(isPage('products_browse') && !isPage('application_search')) {
				PageElements.ProductList = GrantModules.ProductList();
    }
    if(isPage('application_search')) {
				PageElements.ApplicationSearch = GrantModules.ApplicationSearch('.app-search .selects');
    }
    if(isPage('products_recommend') && !isPage('application_search')) {
				PageElements.Recommended = GrantModules.Recommended();
    }
    if(isPage('about-us')) {
				PageElements.CompanyHistory = GrantModules.CompanyHistory();
    }
    if(isPage('dealer_locator')) {
				PageElements.DealerLocator = GrantModules.DealerLocator();
    }

    PageElements.InstructionManualSearch = GrantModules.InstructionManualSearch();

    if ($('#search-results')) {
				$('#search-results a.quick-view').fancybox({
						'width': 450,
						'height': 310,
						'autoScale': false,
						'type': 'iframe'
				});
    }

    //Run load events
    for(i = 0; i < onLoadFunctions.length; i++) {
				onLoadFunctions[i]();
    }
});

/*****************************/
