function HeroEngine_preload_slide(slide_num) {
	var data = document.HeroEngine_data;
	
	var slide = data.slides[slide_num];
	
	if (slide.preloaded == true) {
		//if (data.debug) console.log('preload_slide: Slide ' + slide_num + ' already loaded');
	}
	else {
		
		if (slide.loading == true) { 
			// No need to do anything as it's already been requested.
			//if (data.debug) console.log('preload_slide: Slide ' + slide_num + ' already being loaded');
			return;
		}
		//if (data.debug) console.log('preload_slide: Initiating preload of Slide ' + slide_num );
		
		// Create a div to place preloaded images into so the browser caches them
		if (data.preload_container_built == undefined) {
			$('body').append("<div id='image_preload_container'></div>");
			data.preload_container_built = true;
		}
		// create a new dom element for the slide image:
		$('<img />').attr('src', slide.slide_img_url)
						.load(function(){ 
									$('div#image_preload_container').append( $(this) );
									if (data.slideshow_type == 'homepage') {
										// additionally load the article headline image:
										$('<img />').attr('src', slide.headline_img.url).load(function(){
																$('div#image_preload_container').append( $(this) );
																slide.preloaded = true; 
																slide.loading = false;
																
																// If waiting for this slide to load, draw it now:
																if (data.slide_waited_for != null && data.slide_waited_for == slide_num) {
																	data.slide_waited_for = null;
																	HeroEngine_show_slide(slide_num);
																}
																
																});
									}
									else {
										slide.preloaded = true;
										slide.loading = false;
										// If waiting for this slide to load, draw it now:
										if (data.slide_waited_for != null && data.slide_waited_for == slide_num) {
											data.slide_waited_for = null;
											HeroEngine_show_slide(slide_num);
										}
									}
						});
	
	}
}



function HeroEngine_show_slide(slide_num) {
	var data = document.HeroEngine_data;

	if (data.debug)
		console.log('show_slide: slide num ' + slide_num + ' requested');
		
	var slide = data.slides[slide_num];

	// Has the slide been preloaded? If not, then ask it to be:
	if (slide.preloaded == false) {
		// Ensure that the slide is displayed when loading is complete:
		data.slide_waited_for = slide_num;

		if (data.debug)
			console.log('show_slide: slide ' + slide_num + ' not ready');

		// The slide may already be being loaded. If not, ask it to be:
		if (slide.loading == false) {
			if (data.debug)
				console.log('show_slide: initiating preload of slide ' + slide_num);
			
			HeroEngine_preload_slide(slide_num);
		}
		else {
			if (data.debug)
				console.log('show_slide: preload of needed slide ' + slide_num + ' already in progress - waiting');
		}
		// No need to continue - this function will be called again when loading is complete.
		return;
	}

	// If the slideshow is not running, then change the responsiveness of the transition
	// so it's snappier for the user if clicking through the slides.
	if (data.slideshow_running)
		slide_fade_ms = data.fade_ms;
	else
		slide_fade_ms = 200;

	// alter speeds depending on whether the slide change was automatic or selected by the user 	
	var headline_fade_down_ms = data.slideshow_running ? 1000 : 200;
	var copyright_fade_down_ms = data.slideshow_running? 1000 : 200 ;
	
	var headline_fade_up_ms 	=  headline_fade_down_ms;
	var copyright_fade_up_ms 	=  copyright_fade_down_ms;


	// At this point, the slide may not yet be loaded. If not, then don't display yet.
	// This function will be called again later when the slide is ready to show.
	
	if (data.slide_loaded == false)
		return;
		
		
	// This next bit assumes that the bottom canvas is the same image as the top canvas, OR
	// that we're displaying a slide for the first time.
	
	
	// If it's the first time this has been called, then no need to fade down the previous elements:
	if (data.slide_displayed == false) {
		data.slide_displayed = true;
		headline_fade_down_ms = 0;
	}
	
	// Hide the top canvas, change its picture to the new one, in preparation for fading up in a moment:
	$("div#hero div#bg_topcanvas").css('opacity', '0')
								  .css('background', 'url(' + slide.slide_img_url + ')')

	// 
	// Hide the current headline image if there is one, and replace with the new headline, ready to fade up in a moment
	if (data.slideshow_type == 'homepage') {
		// hide the title image, 
		$("div#hero div#headline_img")
			.animate({opacity: 0}, headline_fade_down_ms, function() {
										$("div#hero div#headline_img")
										.css('background', 'url(' + slide.headline_img.url + ')');
			});
	}
	
	// Hide the copyright notice and replace it with the new one, ready for showing a little later below
	$("div#hero span#copyright").animate({opacity: 0}, copyright_fade_down_ms, function() {
														var new_copyright = slide.copyright;
														if (new_copyright == null)
															new_copyright = "";
														$("div#hero span#copyright").html(new_copyright)
														.animate({opacity: 1}, copyright_fade_up_ms);													
											 });
	
	// Fade up the top canvas (which now has the new slide), then
	// copy the new image to the back canvas ready for the next slide transition
	$("div#hero div#bg_topcanvas").css('opacity', '0')
								  .css('background', 'url(' + slide.slide_img_url + ')')
								  .animate({opacity: 1}, slide_fade_ms ,function() {
											// copy slide to the background canvas ready for the next iteration:
											$("div#hero div#bg_botcanvas").css('background', 'url(' + slide.slide_img_url + ')');
											
											// Finally, set the timer going for the next slide
											if (data.slideshow_running == true) {
												// Start the preload now, so that when the timeout expires, the slide is probably ready to display
												HeroEngine_preload_slide(HeroEngine_next_slide_index(1));
												data.timeout = setTimeout(function(){HeroEngine_show_next_slide(1, false)}, data.interval_ms - slide_fade_ms);
											}
									});
	// Fade up the headline image
	if (data.slideshow_type == 'homepage') {
		$("div#hero div#headline_img").animate({opacity: 1}, headline_fade_up_ms);
	}
	// Set the action url (if the person clicks the screen
	data.action_url = slide.article_url;
}


/** 
 * @return the index of the next slide to be displayed, given the value
 * of data.next_slide.
 */ 
function HeroEngine_next_slide_index(increment) {
	var data = document.HeroEngine_data;
	var current_slide = data.next_slide;
	var num_slides = data.slides.length;
	var next_slide = (current_slide + increment) % data.slides.length;
	if (next_slide < 0)
		next_slide = num_slides + next_slide;
		
	if (data.debug)
		console.log('slide_index_calc: incr = ' + increment + ', current slide = ' + current_slide + ', num slides: ' + num_slides + ',  calculated next slide = ' + next_slide);

	return next_slide;
}

/**
 * @param	increment 			- if not set, defaults to 1
 */
function HeroEngine_show_next_slide(increment) {
	
	if (increment == null)
		increment = 1;	
		
	var data = document.HeroEngine_data;
	data.next_slide = HeroEngine_next_slide_index(increment);
	HeroEngine_show_slide(data.next_slide);
}


function HeroEngine_init_pager() {
	var data = document.HeroEngine_data;

	var fade_ms = data.button_fade_ms;

	if(data.slides.length > 1) {		
		// Display the buttons, make it solid if hovered over, and
		$('div#hero div.hero_nav_button')
		.css('opacity', data.default_button_opacity)
		.show()
		.mouseenter(function() {$(this).animate({'opacity': 1}, 100)})
		.mouseleave(function() {$(this).animate({'opacity': data.default_button_opacity}, fade_ms)});

		// Hero next/prev slide buttons::
		$('div#hero div.hero_prev_button')
		.click(function(event){
			HeroEngine_stop_slideshow();
			HeroEngine_show_next_slide(-1);
			// Immediately start the loading of the next slide we expect to have to load
			HeroEngine_preload_slide(HeroEngine_next_slide_index(-1));
			event.stopPropagation();
			return false;
		});

		$('div#hero div.hero_next_button')
		.click(function(event){
			HeroEngine_stop_slideshow();
			HeroEngine_show_next_slide(1);
			// Immediately start the loading of the next slide we expect to have to load
			HeroEngine_preload_slide(HeroEngine_next_slide_index(1));
			event.stopPropagation();
			return false;
		});

	}	
}

function HeroEngine_stop_slideshow() {
	var data = document.HeroEngine_data;
	// interrupt the next scheduled slide
	if (data.timeout != undefined) {
		clearTimeout(data.timeout);
	}
	data.slideshow_running = false;
	// Cancel slide waited for, so that if held up by a loading slide it
	// doesn't trigger a slide draw.
	data.slide_waited_for = null;
}


function HeroEngine_init() {

	// check if there is no hero to display:
	if (document.HeroEngine_data == undefined)
		return;
		
	var data = document.HeroEngine_data;
	
	data.slide_displayed = false;	// Is a slide currently displayed?
	data.slide_waited_for = null;	// Slide which is needed for display but is still loading.
	data.default_button_opacity = 0.5;
	data.button_fade_ms = 200;
	data.next_slide = 0;			// This will show the currently displayed slide index unless an increment in the displayed slide has been requested but not yet completed.
	data.debug = 0;
		
	// Loading default states for each slide
	for (var slide_index in data.slides) {
		data.slides[slide_index].preloaded = false;
		data.slides[slide_index].loading   = false;
	}
	if (data.debug)
		console.log(data);
	
	// initialise the first action url so that if someone clicks immediately, they are sure to make it to the first
	// article story.
	data.action_url = data.slides[0].article_url;
	
	// if the slide has a headline image, then setup headline image background:
	if (data.slides[data.next_slide].headline_img != undefined) {
		$('div#headline_bg').css('opacity', 0.65).show();
	}
	
	$('div#hero').click(function() {if (data.action_url != undefined) window.location.href = data.action_url;});
	
	// no need to animate if there's just one slide:
	data.slideshow_running = data.slides.length > 1;

	//set up the info panel background:
	$('div#hero div.info_container_bg').show()
									   .css('opacity', 0.65);

	if (data.slides.length > 1) {
		// Need the pager:
		HeroEngine_init_pager();	
	}
	
	// These actions only for product pages: need a better way to 
	// add this to the generic hero engine:
	$("div.product_hero div.hero_logo_bg").css('opacity', '0.6');
	$("div.product_hero div.main_product_logo").css('opacity', '0').css('margin-left', '40px');
	$("div.product_hero div.hero_img_info_bg").css('opacity', '0.6');
	$("div.main_product_logo").animate({ opacity: 1, marginLeft: "23px"}, 1500 );


	
	
	HeroEngine_show_next_slide(0);
}

