(function($){

	/**
	 * jQuery function to load in fullscreen backdrop image.
	 *
	 * @author   Alan Roemen <alan@44interactive.com>
	 * @version  0.1 - Aug 29, 2011 - Initial Build
	 * @options
	 *   start:    Image to show first. Accepts int or string 'random' for a random start. A set cookie value overrides setting. Default: random
	 *   drops:    An array of backdrops available to cycle through. A nested array will load a stylesheet along with the backdrop. Default: []
	 *   cookie:   The name of the cookie to set. Overrides the start option if set. Default: 'backdrop'
	 *   fade:     The duration of the fade effect in milliseconds. Default: 250
	 *   before:   Function to trigger before initial backdrop load. Default: null
	 *   after:    Function to trigger after initial backdrop load. Default: null
	 *   before_change:  Function to trigger before backdrop changed. Default: null
	 *   after_change:   Function to trigger after backdrop changed. Default: null
	 */
	$.backdrop = function(options){
		options = $.extend({
			start:  'random',
			drops:  [],
			cookie: 'backdrop',
			fade:   250,
			before: null,
			after:  null,
			before_change: null,
			after_change:  null
		}, options || {});

		var active, holder, bckgrd, browser, drop, style, step = 0, setting = false;

		/**
		 * Initial construct for function. Loads in steps.
		 * Step 1: Loads the backdrop element and initial backdrop image
		 * Step 2: Resizes backdrop image and brings it into view
		 * @author  Alan Roemen <alan@44interactive.com>
		 * @since   v0.1 - Initial Build
		 */
		function initialize(){
			if ( options.drops.length <= 0 ) return;
			switch ( ++step ) {
				case 1:
					holder = $('<div id="backdrop">').hide();
					$(document).ready(function(){ $('body').prepend(holder); });

					if ( options.start == 'random' ) {
						options.start = Math.floor( Math.random() * options.drops.length );
					}

					active = cookie();
					if ( active === null ) active = options.start;

					if ( $.isArray(options.drops[active]) ) {
						drop = options.drops[active][0];
						style = options.drops[active][1];
					} else {
						drop = options.drops[active];
						style = null;
					}

					bckgrd = $('<img/>').attr('src', drop) .appendTo(holder);
					if (style !== null) {
						$('<link type="text/css" rel="stylesheet" href="' + style + '" id="backdrop-style" />').appendTo('head');
					}
					$(window).load(initialize);
					break;
				case 2:
					if ( options.before !== null ) options.before();
					resize();
					holder.show();
					$(window).resize(resize);
					holder.mousedown(function(){
						return false;
					});
					if ( options.after !== null ) options.after();
					break;
			}
		}

		/**
		 * Sets / Gets cookie values. Based of jQuery Cookie plugin: https://github.com/carhartl/jquery-cookie
		 * @author  Alan Roemen <alan@44interactive.com>
		 * @since   v0.1 - Initial Build
		 */
		function cookie(value){
			var key = options.cookie;
			// set cookie
			if (arguments.length > 0 && String(value) !== "[object Object]") {
				var expires;

				if (value === null || value === undefined) {  // remove cookie
					expires = new Date();
					expires.setDate(expires.getDate() - 1);
				}

				value = String(value);  // cast to string
				return (document.cookie = [
						encodeURIComponent(key), '=',
						encodeURIComponent(value),
						expires ? '; expires=' + expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
						'; path=/',
					].join(''));
			}

			// fetch cookie
			var result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie);
			return result ? decodeURIComponent(result[1]) : null;
		}

		/**
		 * Resizes holder and bckgrd elements to the size of the window
		 * @author  Alan Roemen <alan@44interactive.com>
		 * @since   v0.1 - Initial Build
		 */
		function resize(){
			browser = {
				'width': $(window).width(),
				'height': $(window).height()
			};
			holder.css({
				'position': 'fixed',
				'top': '0',
				'left': '0',
				'width': browser.width,
				'height': browser.height
			});

			bckgrd.css({
				'position': 'absolute',
				'top': '0',
				'left': '0',
				'z-index': '0'
			})

			if ( bckgrd.width() > browser.width ) {
				bckgrd.css({'width': browser.width, 'height': 'auto'});
			}

			if ( bckgrd.height() > browser.height ) {
				bckgrd.css({'width': 'auto', 'height': browser.height});
			}

			if ( bckgrd.width() < browser.width ) {
				bckgrd.css({'width': browser.width, 'height': 'auto'});
			} else if ( bckgrd.height() < browser.height ) {
				bckgrd.css({'width': 'auto', 'height': browser.height});
			}
		}

		/**
		 * API function for changing the backdrop image
		 * @author  Alan Roemen <alan@44interactive.com>
		 * @since   v0.1 - Initial Build
		 */
		function set( index ){
			if ( setting ) return;
			cookie( index );

			if ( active == index ) return;
			active = index;
			setting = true;

			if ( options.before_change !== null ) options.before_change();
			holder.fadeOut(options.fade);
			if (style !== null) {
				$('#backdrop-style').remove();
			}

			if ( $.isArray(options.drops[active]) ) {
				drop = options.drops[active][0];
				style = options.drops[active][1];
			} else {
				drop = options.drops[active];
				style = null;
			}
			bckgrd = $('<img/>')
				.load(function(){
					resize();
					holder.find('img:eq(0)').remove();
					holder.fadeIn(options.fade);
					if (style !== null) {
						$('<link type="text/css" rel="stylesheet" href="' + style + '" id="backdrop-style" />').appendTo('head');
					}
					if ( options.before_change !== null ) options.after_change();
					setting = false;
				})
				.appendTo(holder)
				.attr('src', drop);
		}



		/* PROGRAM START */
		initialize();

		/* Return API */
		return {
			'active': active,
			'drops': options.drops,
			'resize': resize,
			'set': set
		};
	}
})(jQuery);
