
jQuery.cookie = function (key, value, options) {
    
    // key and at least value given, set cookie...
    if (arguments.length > 1 && String(value) !== "[object Object]") {
        options = jQuery.extend({}, options);

        if (value === null || value === undefined) {
            options.expires = -1;
        }

        if (typeof options.expires === 'number') {
            var days = options.expires, t = options.expires = new Date();
            t.setDate(t.getDate() + days);
        }
        
        value = String(value);
        
        return (document.cookie = [
            encodeURIComponent(key), '=',
            options.raw ? value : encodeURIComponent(value),
            options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
            options.path ? '; path=' + options.path : '',
            options.domain ? '; domain=' + options.domain : '',
            options.secure ? '; secure' : ''
        ].join(''));
    }

    // key and possibly options given, get cookie...
    options = value || {};
    var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
    return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
};


window.preloadedImages = [];
window.preload = function (images) {
	for (var i in images) {
		var elem = document.createElement('img');
		elem.src = images[i];
		window.preloadedImages.push(elem);
	}
};

/*
 * Full screen background plugin
 * 
 * Copyright 2011 ThemeCatcher.net
 * All rights reserved
 * 
 */
;(function ($, window) {
	// Full screen background default settings
	var defaults = {
		speedIn: 3000,			// Speed of the "fade in" transition between background images, in milliseconds 1000 = 1 second
		speedOut: 3000,			// Speed of the "fade out" transition between background images
		sync: true,			    // If true, both fade animations occur simultaneously, otherwise "fade in" waits for "fade out" to complete
		minimiseSpeedIn: 1000,	// Speed that the website fades in, in full screen mode, in milliseconds
		minimiseSpeedOut: 1000, // Speed that the website fades out, in full screen mode, in milliseconds
		controlSpeedIn: 500,	// Speed that the controls fades in, in full screen mode, in milliseconds
		fadeIE: false,			// Whether or not to fade the website in IE 7,8
		preload: true,			// Whether or not to preload images
		save: true,				// Whether or not to save the current background across pages
		slideshow: true,		// Whether or not to use the slideshow functionality
		slideshowAuto: true,	// Whether or not to start the slideshow automatically
		slideshowSpeed: 7000,   // How long the slideshow stays on one image, in milliseconds
		random: false,			// Whether the images should be displayed in random order, forces save = false
		keyboard: true,			// Whether or not to use the keyboard controls, left arrow, right arrow and esc key
		onLoad: false,			// Callback when the current image starts loading
		onComplete: false		// Callback when the current image has completely loaded
	},
	
	// Wrappers & overlay
	$outer,
	$overlay,
	$stage,
	
	// Full screen controls
	$controlsWrap,
	$controls,
	$prev,
	$play,
	$next,
	$loadingWrap,
	$loading,
	$closeWrap,
	$close,
	
	// Storm footer controls
	$stormControls,
	$stormLoading,
	$stormPrev,
	$stormPlay,
	$stormNext,
	
	// Current image & window
	$image,
	$window = $(window),
	
	// Misc
	isIE = $.browser.msie && !$.support.opacity,
	backgrounds,
	total,
	imageCache = [],
	imageRatio,
	bodyOverflow,
	index = 0,
	active = false,
	settings,
	fullscreen;
	
	// Cache the images with given indices
	function cache()
	{
		$.each(arguments, function (i, cacheIndex) {
			if (typeof imageCache[cacheIndex] === 'undefined') {
				imageCache[cacheIndex] = document.createElement('img');
				imageCache[cacheIndex].src = backgrounds[cacheIndex];
			}
		});
	}
	
	// Randomly shuffle a given array
    function shuffle(array) {
        var tmp, current, top = array.length;

        if(top) while(--top) {
        	current = Math.floor(Math.random() * (top + 1));
        	tmp = array[current];
        	array[current] = array[top];
        	array[top] = tmp;
        }

        return array;
    }
    
    function trigger(event, callback) {
    	if (callback && typeof callback === 'function') {
    		callback.call();
    	}
    	
    	$.event.trigger(event);
    }
	
	// Initialisation
	function init() {
		// Create the div structure
		$outer = $('<div class="fullscreen-outer"></div>').append(
			$overlay = $('<div class="fullscreen-overlay"></div>'),
			$stage = $('<div class="fullscreen-stage"></div>')
		);
		
		$controlsWrap = $('<div class="fullscreen-controls-outer"></div>').append(
			$controls = $('<div class="fullscreen-controls"></div>').append(
				$prev = $('<div class="fullscreen-prev"></div>'),
				$play = $('<div class="fullscreen-play"></div>'),
				$next = $('<div class="fullscreen-next"></div>')
			),
			$loadingWrap = $('<div class="fullscreen-loading-wrap"></div>').append(
				$loading = $('<div class="fullscreen-loading"></div>')
			),
			$closeWrap = $('<div class="fullscreen-close-wrap"></div>').append(
				$close = $('<div class="fullscreen-close"></div>')
			)
		);
		
		$stormControls = $('<div class="storm-controls"></div>').append(
			$stormLoading = $('<div class="storm-loading"></div>'),
			$stormPrev = $('<div class="storm-prev"></div>'),
			$stormPlay = $('<div class="storm-play"></div>'),
			$stormNext = $('<div class="storm-next"></div>')
		);
		
		// Put the controls on the page
		$('.FullScreenControl').after($stormControls);
		$('body').prepend($outer).append($controlsWrap);
		
		if (total > 1) {
			$controls.add($stormPrev).add($stormNext).show();
			fullscreen.bindKeyboard();
			
			if (settings.slideshow) {
				// Slideshow functionality
				
				var timeout,
				start,
				stop;
				
				start = function () {
					$.cookie('stormSlideshow', 'start');
					$play
						.bind('fullscreenComplete', function () {
							timeout = setTimeout(fullscreen.next, settings.slideshowSpeed);
						})
						.bind('fullscreenLoad', function () {						 
							clearTimeout(timeout);
						})
						.removeClass('fullscreen-play')
						.addClass('fullscreen-pause')
						.add($stormPlay)
						.unbind('click')
						.one('click', stop);
					$stormPlay
					 	.removeClass('storm-play')
					    .addClass('storm-pause');
					
					timeout = setTimeout(fullscreen.next, settings.slideshowSpeed);
				};
				
				stop = function () {
					$.cookie('stormSlideshow', 'stop');
					clearTimeout(timeout);
					$play
						.unbind('fullscreenLoad fullscreenComplete')
						.removeClass('fullscreen-pause')
						.addClass('fullscreen-play')
						.add($stormPlay)
						.unbind('click')
						.one('click', start);
					$stormPlay
					 	.removeClass('storm-pause')
					 	.addClass('storm-play');
				};
				
				if ($.cookie('stormSlideshow') === 'start') {
					start();
				} else if ($.cookie('stormSlideshow') === 'stop') {
					stop();
				} else {
					if (settings.slideshowAuto) {
						start();
					} else {
						stop();
					}
				}
				
				$play.add($stormPlay).show();
			}
		}
		
		// Bind the next button to load the next image
		$prev.add($stormPrev).click(function () {
			if (!active) {
				fullscreen.prev();
			} else {
				return false;
			}
		});
		
		// Bind the next button to load the next image
		$next.add($stormNext).click(function () {
			if (!active) {
				fullscreen.next();
			} else {
				return false;
			}
		});
		
		// Bind the close button to close it
		$closeWrap.click(fullscreen.close);
		
		// Save the current body overflow value
		bodyOverflow = $('body').css('overflow');
		
		$('#minimise-button').click(function (e) {
			e.preventDefault();
			$('body').css('overflow', 'hidden');			
			$('div.outside').fadeOut(settings.minimiseSpeedOut).hide(0, function () {
				$controlsWrap.fadeIn(settings.controlSpeedIn).show(0, function () {
					if (settings.keyboard) {
						$(document).bind('keydown.fullscreen', function (e) {
							if (e.keyCode === 27) {
								e.preventDefault();
								fullscreen.close();
							}
						});
					}
				});
			});
			$window.resize();
		});
		
		$window.resize(windowResize);
		
		if (settings.save) {
			// Check for the saved background cookie to override the default
			var savedBackground = $.cookie('stormSavedBackground');		
			for(var i = 0; i < total; i++) {
				if (i == savedBackground) {
					index = i;
					break;
				}
			}
		}
						
		// Fade in the first image, then cache one next image and one previous image
		load(function () {
			if (settings.preload) {
				cache((index == (total - 1)) ? 0 : index + 1, (index == 0) ? total - 1 : index - 1);
			}
		});
	};
	
	// Load the current image
	function load(callback) {
		var image = document.createElement('img'),
		loadingTimeout;
		$image = $(image).css('position', 'fixed');
		$image.load(function () {
			$image.unbind('load');
			setTimeout(function () { // Chrome will sometimes report a 0 by 0 size if there isn't pause in execution
				imageRatio = image.height / image.width;
				var $current = $stage.find('img');
				$stage.append($image);
				windowResize(function () {
					clearTimeout(loadingTimeout);
					$loadingWrap.add($stormLoading).hide();
					var fn = function () {
						$image.animate({ opacity: 'show' }, {
							duration: settings.speedIn,
							complete: function () {
								active = false;
								
								trigger('fullscreenComplete', settings.onComplete);
								
								if (typeof callback === 'function') {
									callback.call();
								}
							}
						});
					};
					
					if ($current.length) {
						$current.animate({ opacity: 'hide' }, {
							duration: settings.speedOut,
							complete: function () {
								if (!settings.sync) {
									fn();
								}
								$current.remove();
							}
						});
						
						if (settings.sync) {
							fn();
						}
					} else {
						fn();
					}
				});
			}, 1);
		});
		
		loadingTimeout = setTimeout(function () { $loadingWrap.add($stormLoading).fadeIn(); }, 200);
		trigger('fullscreenLoad', settings.onLoad);
		active = true;
		setTimeout(function () { // Opera 10.6+ will sometimes load the src before the onload function is set, so wait 1ms
			$image.attr('src', backgrounds[index]);
		}, 1);
	}
	
	// Resize the current image to set dimensions on window resize
	function windowResize(callback)
	{
		if ($image) {
			var windowWidth = $window.width(),
			windowHeight = $window.height();
						
			if ((windowHeight / windowWidth) > imageRatio) {
				$image.height(windowHeight).width(windowHeight / imageRatio);
			} else {
				$image.width(windowWidth).height(windowWidth * imageRatio);
			}
			
			$image.css({
				left: ((windowWidth - $image.width()) / 2) + 'px',
				top: ((windowHeight - $image.height()) / 2) + 'px'
			});
			
			if (typeof callback === 'function') {
				callback.call();
			}
		}
	}
	
	
	fullscreen = $.fullscreen = function (options) {
		settings = $.extend({}, defaults, options || {});
		
		backgrounds = settings.backgrounds;
		total = backgrounds.length;
		
		if (settings.random) {
			backgrounds = shuffle(backgrounds);
			settings.save = false;
		}

		if (typeof settings.backgroundIndex === 'number') {
			index = settings.backgroundIndex;
			settings.save = false;
		}
		
		if (isIE && !settings.fadeIE) {
			settings.minimiseSpeedOut = 0;
			settings.minimiseSpeedIn = 0;
			settings.controlSpeedIn = 0;
		}
		
		init();
	};
	
	fullscreen.close = function () {
		$controlsWrap.hide();
		$('div.outside').fadeIn(settings.minimiseSpeedIn);
		$('body').css('overflow', bodyOverflow);
		$(window).resize();
		fullscreen.unbindKeyboard();
	};
	
	fullscreen.next = function () {
		index = (index == (total - 1)) ? 0 : index + 1;
		load(function () {
			if (settings.preload) {
				cache((index == (total - 1)) ? 0 : index + 1); // Cache the next next image
			}
			
			if (settings.save) {
				$.cookie('stormSavedBackground', index, {expires: 365});
			}
		});
	};
	
	fullscreen.prev = function () {
		index = (index == 0) ? total - 1 : index - 1;
		load(function () {
			if (settings.preload) {
				cache((index == 0) ? total - 1 : index - 1); // Cache the next previous image
			}
			
			if (settings.save) {
				$.cookie('stormSavedBackground', index, {expires: 365});
			}
		});
	};
	
	fullscreen.bindKeyboard = function () {
		if (settings.keyboard) {
			$(document).bind('keydown.fullscreen', function (e) {
				if (!active) {
					if (e.keyCode === 37) {
						e.preventDefault();
						$prev.click();
					} else if (e.keyCode === 39) {
						e.preventDefault();
						$next.click();
					}
				}
			});
		}
	};
	
	fullscreen.unbindKeyboard = function () {
		if (settings.keyboard) {
			$(document).unbind('keydown.fullscreen');
		}
	};
	
	window.preload([
	    'images/loading.gif',
	    'images/backward1.png',
	    'images/play.png',
	    'images/play1.png',
	    'images/pause.png',
	    'images/pause1.png',
	    'images/forward1.png',
	    'images/close.png',
	    'images/close1.png'
	]);
	
	$(window).load(function () {
		// Preload one next image and one previous image
		if (settings.preload) {
			var previousIndex = (index == 0) ? total - 1 : index - 1;
			var nextIndex = (index == (total - 1)) ? 0 : index + 1;
			cache(previousIndex, nextIndex);
		}
	});
})(jQuery, window);

