(function($){
	// defaultOptions follow this object definition
	
	$.TourSlideshow = function(options){
		var showing_main  = false,
				first_showing = true,
				hash_loaded   = false,
				base				  = this,
				options				= $.extend({}, $.TourSlideshow.defaultOptions, options);
				
		var init = function(){
			
			// Add the em's for the "plus" tags
			$('a.image_wrapper').append('<em></em>');
			
			
			// Cache selectors
			base.$content    = $(options.content);
			base.$tour_image = $(options.tour_image);
			base.$free_trial = $(options.free_trial);
			base.$begin_tour = $(options.begin_tour);
			base.$tour_items = $(options.tour_items);
			base.$next       = $(options.next);
			base.$prev       = $(options.prev);
			base.$tour_nav   = $(options.tour_nav);
			
			base.keys = {};
			base.nav  = {};
			
			base.$begin_tour.find('a').click(function(e){
				$(this).blur(); // Lets the button go back to a waiting state vs. remaining "pressed"
				e.preventDefault();
				
				$.History.go('collect'); // Go to the first item
			});
			
			// If there is no hash, then trigger the 
			if(window.location.hash == ""){
				window.setTimeout(function(){
					$.History.go('overview');
				}, 500);
			}
			
			// Grabs the current hash, and if it is included
			// in the keys array, it switches to that page.
			// Otherwise go to the overview page
			$.History.bind(function(state){
				var index = base.keys[state];
				if(index >= 0){
					base.switchToIndex(index);
				} else {
					$.History.go('overview');
				}
			});
			
			// No need to cache. Only accessed once.
			$("#feature .tour_header h2, #signup_large div").click(function(e){
				$.History.go('overview');
			});
			
			// Button should move to the next item unless it has the 'disabled' class
			base.$next.find("a").click(function(e){
				e.preventDefault();
				if(!$(this).parent().hasClass('disabled')){
					$.History.go(base.find_key_by_index(base.keys[$.History.getHash()] + 1));
				}
			});
			
			// Button should move to the previous item unless it has the 'disabled' class
			base.$prev.find("a").click(function(e){
				e.preventDefault();
				if(!$(this).parent().hasClass('disabled')){
					$.History.go(base.find_key_by_index(base.keys[$.History.getHash()] - 1));
				}
			});
			
			base.$tour_nav.each(function(i, el){
				$(this).append("<em></em>"); // Down arrows for navigation
				
				var num    = i, // Scoped cache of index
				    $a     = $(this).find('a'),
						target = $a.attr('href').replace('#','');
						
				base.keys[target] = num; // Store in keys for easy lookup
				base.nav[target]  = $a; // Store in keys for easy lookup
				
				$(this).find('a').click(function(e){
					e.preventDefault();
					$.History.setHash(target);
				});
				
			});
			
			// Adapted from original tour_slideshow.js
			$('body').addClass('js');
			
			// Adapted from original tour_slideshow.js
			$(options.tour_items).cycle({
          fx: options.fx,
          timeout: 0,
          speed: options.speed,
          fastOnEvent: options.fastOnEvent,
          before: base.activateTab,
          pauseOnPagerHover: true,
					nowrap: true,
          pause: true
      });
			
		};
		
		// This looks up the index in the key array
		// by the index value
		base.find_key_by_index = function(index){
			for(var prop in base.keys){
				if(base.keys[prop] == index) return prop;
			}
		}
		
		// Pass in an index to switch to that item
		// Also determines if it should show or hide the 
		// header images/animations
		base.switchToIndex = function(index){
			base.activateDeactivatePrevNext(index);
			
			if(index > 0 && showing_main) {
				base.startTour(function(){
					base.$tour_items.cycle(index);
				});
			} else if(index == 0 && !showing_main){
				base.resetTour(!first_showing, function(){
					base.$tour_items.cycle(index);
					if(first_showing) first_showing = !first_showing;
				});
				
			} else {
				if(!showing_main && first_showing){
					base.showFreeTrial();
					first_showing = false;
				}
				base.$tour_items.cycle(index);
			}
		}
		
		// Activates the tab based on the selected slide.
		// Used as a callback by the cycle plugin.
		base.activateTab = function(currentSlide, nextSlide) {
				var id = nextSlide.id.replace('slide_','');
        base.$tour_nav.removeClass('active');
				base.nav[id].parent().addClass('active');
    }
		
		// This gets called to see if the prev or next buttons should 
		// be clickable or not (and visual state)
		base.activateDeactivatePrevNext = function(index){
			var length = $('li', $(options.tour_items)).length;
			if(index == 0){
				base.$prev.addClass('disabled');
				base.$next.removeClass('disabled');
			} else if (index > 0 && index < length - 1){
				base.$next.removeClass('disabled');
				base.$prev.removeClass('disabled');
			} else {
				base.$next.addClass('disabled');
				base.$prev.removeClass('disabled');
			}

			if(index > 0 && showing_main) base.startTour();
			if(index == 0 && !showing_main) base.resetTour(true);
		}
		
		// If callback is present, it is called at the end
		base.startTour = function( callback ){
			base.$tour_image.animate( { top: 100, opacity: 0.0 }, 400, "easeInBack"  );
			base.$begin_tour.animate( { opacity: 0.0 },           300, "easeOutExpo" );
			
			window.setTimeout(function(){
				showing_main = false;
				base.showFreeTrial();
				if(callback) callback();
				
			}, 300);
			
			base.$content.animate({ height: 160 }, 500, "easeInExpo");
		};
		
		base.showFreeTrial = function(){
			base.$free_trial.css( { opacity: 0.0, left: 700 } ).animate( { opacity: 1.0, left: 670 }, 300, "easeInExpo");
		}
		
		// Full should be used once the $free_trial button has been shown once
		// callback is called once function has finished
		base.resetTour = function(full, callback ){
			var reset = function(){
				 showing_main = true;
				base.$begin_tour.animate( { opacity: 1.0 },          300, "easeInExpo"  , function(){
					this.style.filter = "";
				});
				base.$tour_image.animate( { top: 30, opacity: 1.0 }, 400, "easeOutBack" );
				base.$content.animate(    { height: 240 },           500, "easeOutExpo" );
				
				if(callback) callback();
			}
			
			if(full){
				base.$free_trial.animate( { opacity: 0.0, left: 700 }, 300, "easeOutExpo");
				window.setTimeout(function(){
					reset();
				}, 150)
			} else {
				reset();
			}
			
		};
		
		init();
	};
	
	$.TourSlideshow.defaultOptions = {
		content    : "#feature .tour_header .content", // The header container for animation
		tour_image : '#tour_image',                    // The tour image for animation
		free_trial : '#signup_large',                  // The Free Trial animated button
		begin_tour : '#begin_tour',                    // The begin tour button
		tour_items : "div.items > ul",                 // The slider container
		next       : ".tour_next",                     // The next selector
		prev       : ".tour_prev",                     // The previous selector
		tour_nav   : $('#tour_navigation li').not(".tour_prev, .tour_next"), // The navigation elements
		fx         : 'fade',                           // Transition animation 
    speed      : 1000,                             // Unused variable
    fastOnEvent: 300                               // Transition time
	}
	
	$(function(){
		// If more control is ever needed, move this declaration to the pages that need it
		// and pass in custom selectors as needed
		$.TourSlideshow();
	})
})(jQuery)