/*
 * Headline Image Rotator v1.0 - Jordy Boezaard - http://www.bitterzoetmedia.nl/
 *
 * Fades background images with linked headline information
 *
 * TERMS OF USE
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2011 Jordy Boezaard
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/
function HeadlineImageData()
{
	this.headline = null;
	this.content = null;
	this.imageUrl = null;
	this.imageLoaded = false;
}


function HeadlineImageRotator () {
	this.fadeInDuration = 1500;
	this.fadeOutDuration = 1500;
	this.sleepDuration = 6000;
	this.retryTimeoutDuration = 100;
	this.currentPos = 0;
	this.lastAnimationStartTime = null;
	this.headlineImageData = null;
	this.isFirst = true;
};

HeadlineImageRotator.prototype.Init = function ()
{
	// Get elements	
	var listChildren = $('dl#headerBalloon').children();
	
	var headlineImageDataArray = new Array();

	$.each(listChildren, function()
	{
		if (this.tagName.toLowerCase() == 'dt')
		{
			var headlineImageData = new HeadlineImageData();
			headlineImageData.headline = this.innerHTML;
			
			headlineImageDataArray.push(headlineImageData);
		}
		else if(this.tagName.toLowerCase() == 'dd')
		{
			var headlineImageData = headlineImageDataArray[headlineImageDataArray.length - 1];
			
			if ($(this).hasClass('content') == true)
			{
				headlineImageData.content = this.innerHTML;
			}
			else if ($(this).hasClass('image') == true)
			{
				headlineImageData.imageUrl = this.innerHTML;
			}
		}
	}); 
	
	this.headlineImageData = headlineImageDataArray;
	
	if (this.headlineImageData.length == 0)
	{
		return;
	}
	
	// Clear current innerHtml
	$('dl#headerBalloon').html('<dt></dt><dd></dd>');

	// Create div background
	$('<div/>', {
		id:	'headlineImageRotator'
	}).appendTo($('body'));
	
	// Fade elements out
	$('div#headlineImageRotator').fadeOut(0);
	$('dl#headerBalloon').fadeOut(0);
	
	// Preload images
	this.PreloadImages();

	// Start fadein/out sequence
	this.Animate();
}

HeadlineImageRotator.prototype.PreloadImages = function ()
{	
	var onloadFunction = function ()
	{
		this.headlineImageData.imageLoaded = true;
	}
		
	jQuery.each(this.headlineImageData, function ()
	{
		var pic = new Image();
		pic.headlineImageData = this;
		pic.onload = onloadFunction;
		pic.src = this.imageUrl;
	});
}

HeadlineImageRotator.prototype.FadeOut = function ()
{
	// Create callback
	var selfObj = this;
	var callBack = function(){
		selfObj.FadeIn();
	};
	
	// Fade-out balloon
	$('dl#headerBalloon').fadeOut(this.fadeOutDuration);
	
	// Fade-out current image
	$('div#headlineImageRotator').fadeOut(this.fadeOutDuration, callBack);
}

HeadlineImageRotator.prototype.FadeIn = function ()
{
	// Create callback
	var selfObj = this;
	var callBack = function(){
		selfObj.Animate();
	};
	
	// Set header balloon text and links
	$('dl#headerBalloon > dt').html(this.headlineImageData[this.currentPos].headline);
	$('dl#headerBalloon > dd').html(this.headlineImageData[this.currentPos].content);

	// Refresh cufon
	Cufon.refresh('dl#headerBalloon > dt');
	
	// Fade-in balloon
	$('dl#headerBalloon')	.fadeIn(this.fadeInDuration);
	
	// Fade-in next image
	$('div#headlineImageRotator')	.css('backgroundImage', 'url(' + this.headlineImageData[this.currentPos].imageUrl + ')')
									.fadeIn(this.fadeInDuration, callBack);
	
	// Set current position to next index
	this.currentPos++;
	
	if (this.currentPos >= this.headlineImageData.length)
	{
		this.currentPos = 0;
	}
}

HeadlineImageRotator.prototype.Animate = function (selfObj)
{
	if (selfObj == undefined)
	{
		selfObj = this;
	}
	
	if (selfObj.lastAnimationStartTime == null)
	{
		selfObj.lastAnimationStartTime = new Date().getTime();
	}

	if (selfObj.headlineImageData[selfObj.currentPos].imageLoaded == false)
	{
		// Wait until image is preloaded
		var callBackAnimate = function(){
			selfObj.Animate(selfObj);
		};
				
		setTimeout(callBackAnimate, selfObj.retryTimeoutDuration);
		
		return;
	}

	// Calculate passed time
	var timeTaken = new Date().getTime() - selfObj.lastAnimationStartTime;

	// Reset animation start time
	selfObj.lastAnimationStartTime = null;
	
	// Check if it's the first image
	if (selfObj.isFirst == true)
	{
		selfObj.isFirst = false;
		selfObj.FadeIn();
	}
	else
	{
		// Loading took at least as long as sleep duration?
		if (timeTaken >= selfObj.sleepDuration)
		{
			// Go to next image
			selfObj.FadeOut();
		}
		else
		{
			// Wait for remaining time
				
			// Create callback fade out
			var callBackFadeOut = function(){
				selfObj.FadeOut();
			};
			
			setTimeout(callBackFadeOut, selfObj.sleepDuration - timeTaken);
		}
	}
}
