/*!
 * moodblender - simple "mood-image"-changer
 * http://blog.deam.org/tag/moodblender/
 * Requires jQuery library: http://jquery.com/
 *   tested with 1.3.2 and 1.4.2
 *
 * Version 0.2, 2010-03-17
 * Copyright (c) 2009/2010 Klaus M. Brantl, http://www.deam.org
 *
 * MIT License: http://www.opensource.org/licenses/mit-license.php
 */
/*
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

(function($) {
	$.fn.moodblender = function(options) {
		/* ***************************************************************************************** */
		var i = 0,
			slices = 0,
			curIndex = 10,
			clearTimer = '',
			blendInTimer = '',
			blendOutTimer = '',
			nextloop = 0;
		var elements = new Object();
		var wrapperDiv = this;
		var slicesPrefix = $(wrapperDiv).attr('id');
		var imageCount = 0;
		var imageCountCur = 0;

		/* ***************************************************************************************** */
		var settings = {
			animOffset: 30,
			splitparts: 5,
			blendOut: true,
			loop: true,
			maxloop: 23,
			animSpeed: 500,
			animSpeedGap: 300,
			dwellTime: 2000
		};
		settings = $.extend({}, settings, options || {});
		var maxloop = settings.maxloop;

		/* ***************************************************************************************** */
		var clearloop = function() {
			clearTimeout(clearTimer);
			if(settings.loop == true)
			{
				maxloop--;
				if(maxloop > 0)
				{
					loop(nextloop);
				}
			}
		}
		var loop = function(start) {
			var last = '';
			var call = '';
			var thisDwellTime = 0;
			for(i=start; i<start+settings.splitparts; i++)
			{
				if(last != '' && last != elements[i+'file'])
				{
					thisDwellTime += settings.dwellTime;
				}

				curIndex++;
				call = "$('#" + slicesPrefix + "moodblender"+i+"').css('opacity', 0).css('left', '"+elements[i+'left']+"px').css('z-index', "+curIndex+").animate({";
				call += "opacity:1.0,";
				call += "left:'" + (elements[i+'left']-settings.animOffset) + "px'";
				call += "}, "+settings.animSpeed+");";
				setTimeout(call, (i*settings.animSpeedGap+thisDwellTime) );

				if(settings.blendOut == true && i > 0)
				{
					call = "$('#" + slicesPrefix + "moodblender"+(i-1)+"').animate({";
					call += "opacity:0,";
					call += "left:'" + (elements[(i-1)+'left']-(4*settings.animOffset)) + "px'";
					call += "}, "+settings.animSpeed+");";
					setTimeout(call, ((i+settings.splitparts-1)*settings.animSpeedGap+thisDwellTime+settings.dwellTime) );
				}

				last = elements[i+'file'];
			}
			if(settings.blendOut == true && i > 0)
			{
				call = "$('#" + slicesPrefix + "moodblender"+(i-1)+"').animate({";
				call += "opacity:0,";
				call += "left:'" + (elements[(i-1)+'left']-(4*settings.animOffset)) + "px'";
				call += "}, "+settings.animSpeed+");";
				setTimeout(call, ((i+settings.splitparts-1)*settings.animSpeedGap+thisDwellTime+settings.dwellTime) );
			}

			thisDwellTime += settings.dwellTime;
			if(i >= slices)
			{
				nextloop = 0;
			}
			else
			{
				nextloop = i;
			}
			clearTimer = setTimeout(clearloop, ((i+2)*settings.animSpeedGap+thisDwellTime) );
		}

		/* ***************************************************************************************** */
		var init = function() {
			i = 0;
			$('img', wrapperDiv).each(function() {
				var currentPos = 0;
				var partsWidth = Math.floor( this.width/settings.splitparts );
				while(currentPos < this.width)
				{
					elements[i+'left'] = currentPos + settings.animOffset;
					elements[i+'file'] = this.src;

					// includes switch between opacity:0 and alpha(opacity=0) for IE
					$(wrapperDiv).append('<div style="height:'+this.height+'px; width:'+partsWidth+'px; overflow:hidden; position:absolute; top:0; left:'+elements[i+'left']+'px; z-index:'+curIndex+'; ' + ($.support.opacity == true ? 'opacity:0;' : 'filter:alpha(opacity=0);') + 'background:transparent url('+this.src+') no-repeat scroll -'+currentPos+'px 0px" id="' + slicesPrefix + 'moodblender'+i+'">&nbsp;</div>');
					currentPos += partsWidth;

					i++;
				}
				$(this).hide();
				slices = i - 1;
			});
			loop(0);
		}

		/* ***************************************************************************************** */
		var checkPreload = function() {
			imageCountCur++;
			if(imageCountCur == imageCount)
			{
				init();
			}
		}

		/* ***************************************************************************************** */
		// workaround  was done initially for safari - images need to be loaded for sure there ...
		// but after some testing it seemed to be more stable to have this kind of process for all browsers
		if($.browser.msie && parseInt($.browser.version) < 7)
		{
			// do nothing - maybe later I'll take care of IE6
		}
		else
		{
			imageCount = $(wrapperDiv).find('img').length;
			$(wrapperDiv).find('img').each(function() {
				// image from cache: binding the onload-event here is useless
				if(this.complete)
				{
					checkPreload();
				}
				else
				{
					$(this).load(function() {
						checkPreload();
					});
				}
			});
		}

		/* ***************************************************************************************** */
		return this;
	};
})(jQuery);

