/*--------------------------------------------------------------------------------------------------//
// AbsoCaroussel -----------------------------------------------------------------------------------//
//--------------------------------------------------------------------------------------------------//
// Version      : 0.4.1
// Date   	    : juillet 2010
// Auteur	    : Jean-Baptiste Landry
// Requirements : jQuery 1.4
//--------------------------------------------------------------------------------------------------*/
(function(w,$,undefined){



var DEBUG = false;

var all = {};
var AC   = {};

AC.init = function() {
	var c = {};
	
	var options  = (arguments) ? arguments[0] : {};
	c.id         = options.id;
	c.wrap       = (options.wrap) ? true : false;
	c.transition = (options.transition) ? options.transition : 'slideLeft';
	c.speed      = (Number(options.speed)) ? Number(options.speed) : 500;
	/*
	c.autostart  = 
		(options.autostart) ? (
			(Number(options.autostart.start)) ? 
				Number(options.autostart.start)
				: 3000)
			: undefined
	;*/
	c.autointerval = 
		(options.autostart) ? (
			(Number(options.autostart.interval)) ? 
				Number(options.autostart.interval) 
				: 3000)
			: undefined
	;
	c.preSwitchCallback  = (typeof(options.preSwitchCallback)  == 'function') ? options.preSwitchCallback  : undefined;
	c.postSwitchCallback = (typeof(options.postSwitchCallback) == 'function') ? options.postSwitchCallback : undefined;
	c.statusLink         = (options.statusLink) ? true : false;
	c.statusBullet       = (options.statusBullet) ? options.statusBullet : '&bull;';

	/* Liste
	------------------------------------------------------- */
	c.$liste = $('#'+c.id);
	if (!c.$liste.length) { return false; }

	// nav
	c.$nav        = $('.AbsoCaroussel-'+c.id+'-Nav');
	c.$debut      = $('.AbsoCaroussel-'+c.id+'-Debut');
	c.$precedent  = $('.AbsoCaroussel-'+c.id+'-Precedent');
	c.$suivant    = $('.AbsoCaroussel-'+c.id+'-Suivant');
	c.$fin        = $('.AbsoCaroussel-'+c.id+'-Fin');
	c.$items      = $('.AbsoCaroussel-'+c.id+'-Items');
	c.$itemsimple = $('[class*="AbsoCaroussel-'+c.id+'-Item-"]');
	
	// position
	c.$position = $('.AbsoCaroussel-'+c.id+'-Position');
	c.$total    = $('.AbsoCaroussel-'+c.id+'-Total');
	c.$status   = $('.AbsoCaroussel-'+c.id+'-Status');
	
	// total items
	c.total = c.$liste.find('> li').length;

	// désactiver tout si un seul item
	if (c.total == 1) {
		c.$nav.addClass('AbsoCaroussel-Aucun');
		c.$precedent.addClass('AbsoCaroussel-Aucun');
		c.$suivant.addClass('AbsoCaroussel-Aucun');
		c.$items.addClass('AbsoCaroussel-Aucun');
		c.$itemsimple.addClass('AbsoCaroussel-Aucun');
		c.$position.addClass('AbsoCaroussel-Aucun');
		c.$total.addClass('AbsoCaroussel-Aucun');
		c.$status.addClass('AbsoCaroussel-Aucun');
	
	
	// sinon préparer caroussel
	} else {
		
		// initial
		c.curr      = 0;
		c.switching = false;
				
		// general events				
		c.debutClick = function(){ 
			return Switch(c, 0);
		};
		c.precedentClick = function(){ 
			return Switch(c, 'prev');
		};
		c.suivantClick = function(){ 
			return Switch(c, 'next');
		};
		c.finClick = function(){ 
			return Switch(c, c.total-1);
		};
		c.itemSimpleClick = function(){ 
			return Switch(c, new RegExp('AbsoCaroussel-'+c.id+'-Item-([0-9]+)').exec($(this).attr('class'))[1] - 1);
		};

		// bind events				
		c.$debut.click(c.debutClick)
		c.$precedent.click(c.precedentClick)
		c.$suivant.click(c.suivantClick)
		c.$fin.click(c.finClick)
		c.$itemsimple.click(c.itemSimpleClick);

		c.$items.find('> li').each(function(i){ 
			$(this).click(function(){
				return Switch(c, i);
			});
		});
		
		
		
		// intialiser look
		c.$total.html(c.total);
		Refresh(c);

		c.$liste.find('> li').hide();
		c.$liste.find('> li:first-child').show();

		switch (c.transition) {
			// fade
			case 'fade': 
			break;
	
			
			// move vertical
			case 'slideUp': 
			case 'slideDown': 
				c.$liste.find('> li').css({
					left: '0px'
				});
				c.$liste.find('> li:first-child').css('top','0px');
			break;
	
			// move horizontal
			case 'slideLeft': 
			case 'slideRight': 
			default:
				c.$liste.find('> li').css({
					top: '0px'
				});
				c.$liste.find('> li:first-child').css('left','0px');
			break;
		}


		// autostart	
		if (c.autointerval != undefined) {
			c.Interval = setInterval(function(){ Switch(c, 'next'); }, c.autointerval);
		}

		// Ajouter à la liste
		all[c.id] = c;
	}
}; 

function none() {
	return false;
}


/* Switch
------------------------------------------------------- */
function Switch(c, target) {
	if (c.switching) {
		return false;
	}
	if (target == c.curr) {
		return false;
	}	
	c.switching = true;
	


	var callbackData = {
		action: (Number(target) == target) ? 'item' : target,
		source: {
			position: c.curr+1
		},
		target: {}
	};

	var way;

	// current li
	var $liCurr = c.$liste.find('> li:nth-child('+(c.curr+1)+')')
	
	// prev/next
	if (target == 'prev' || target == 'next') {
		
		way = (target == 'prev') ? -1 : 1;
		
		c.curr = 
			(c.wrap) ? 
				(c.curr == 0 && way == -1) ? 
					(c.total-1)
					: ((c.curr + way) % c.total)
				: (c.curr + way)
		;
	
	// item
	} else {
		target == Number(target);
		
		way = (target < c.curr) ? -1 : 1;
		c.curr = target;
	}
	
	// new li
	var $liNew = c.$liste.find('> li:nth-child('+(c.curr+1)+')')


	// add callback data
	callbackData.source.obj      = $liCurr.get(0);
	callbackData.target.position = c.curr+1;
	callbackData.target.obj      = $liNew.get(0);

	if (c.preSwitchCallback) {
		c.preSwitchCallback(callbackData);
	}
	


	/* transitions
	------------------------------------------------------- */
	switch (c.transition) {
		
		// fade
		case 'fade': 
			$liCurr.css('z-index',1);
			
			$liNew
				.css('z-index',2)
				.fadeIn(c.speed, function(){
					$liCurr.hide();
					c.switching = false;
				})
			;
		break;

		
		// move right-bottom > top-left
		/*
		case 'slideTopLeft': 
			var height = c.$liste.height() + 'px';
			var width = c.$liste.width() + 'px';

			$liCurr.animate({
				top:  (way == 1) ? '-'+height : height,
				left: (way == 1) ? '-'+width  : width
			});
			
			$liNew
				.css('top',  (way == 1) ? height : '-'+height)
				.css('left', (way == 1) ? width  : '-'+width)
				.animate({
					top:  '0px',
					left: '0px'
				})
			;
		break;
		*/
		
		// slide horizontal
		case 'slideUp': 
		case 'slideDown': 
			way = (c.transition == 'slideDown') ? -way : way;
			
			var height = c.$liste.height() + 'px';

			$liCurr.animate(
				{ top: (way == 1) ? '-'+height : height},
				c.speed,
				function() { $(this).hide(); c.switching = false; }
			);
			
			$liNew
				.css({
					top:     (way == 1) ? height : '-'+height,
					display: 'block'	
				})
				.animate({
					top: '0px'
				},c.speed)
			;
		break;

		// slide vertical
		case 'slideLeft': 
		case 'slideRight': 
		default: 
			way = (c.transition == 'slideRight') ? -way : way;

			var width = c.$liste.width() + 'px';

			$liCurr.animate(
				{ left: (way == 1) ? '-'+width : width },
				c.speed,
				function() { $(this).hide(); c.switching = false; }
			);
			
			$liNew
				.css({
					left:     (way == 1) ? width : '-'+width,
					display: 'block'	
				})
				.animate({
					left: '0px'
				},c.speed)
			;
		break;
	}

	Refresh(c);

	// éventuellement positionner dans le animate callback
	if (c.postSwitchCallback) {
		c.postSwitchCallback(callbackData);
	}

	return false;
}



/* Refresh
------------------------------------------------------- */
function Refresh(c) {
	
	if (!c.wrap) {
	
		// précédent
		if (c.curr == 0) {
			c.$debut
				.addClass('AbsoCaroussel-Inactif')
				.unbind('click', c.debutClick)
				.bind('click',   none)
			;
			c.$precedent
				.addClass('AbsoCaroussel-Inactif')
				.unbind('click', c.precedentClick)
				.bind('click',   none)
			;
		} else {
			c.$debut
				.removeClass('AbsoCaroussel-Inactif')
				.unbind('click', c.debutClick)
				.bind('click',   c.debutClick)
			;
			c.$precedent
				.removeClass('AbsoCaroussel-Inactif')
				.unbind('click', c.precedentClick)
				.bind('click',   c.precedentClick)
			;
		}
		
		// suivant
		if (c.curr == (c.total-1)) {
			c.$suivant
				.addClass('AbsoCaroussel-Inactif')
				.unbind('click', c.suivantClick)
				.bind('click',   none)
			;
			c.$fin
				.addClass('AbsoCaroussel-Inactif')
				.unbind('click', c.finClick)
				.bind('click',   none)
			;
		} else {
			c.$suivant
				.removeClass('AbsoCaroussel-Inactif')
				.unbind('click', c.suivantClick)
				.bind('click',   c.suivantClick)
			;
			c.$fin
				.removeClass('AbsoCaroussel-Inactif')
				.unbind('click', c.finClick)
				.bind('click',   c.finClick)
			;
		}
	}
				

	// position
	c.$position.html(c.curr+1);

	// status
	c.$status.html('');
	for (var i=0; i<c.total; ++i) {
		if (i == c.curr) {
			c.$status.append('<strong>'+c.statusBullet+'</strong>');
		} else {
			if(c.statusLink) {
				c.$status.append(
					$("<a>")
						.attr("href","#")
						.addClass('AbsoCaroussel-'+c.id+'-Item-'+(i+1))
						.click(c.itemSimpleClick)
						.html(c.statusBullet)
				);
			} else {
				c.$status.append(c.statusBullet);
			}
		}
	}
}









/* PUBLIC
------------------------------------------------------- */

/* Manuel Switch
------------------------------------------------------- */
AC.Switch = function(id, target) {
	return Switch(all[id], (Number(target) == target) ? target-1 : target);
};


// debug only
if (DEBUG) {
	AC.caroussels = all;
}
	





// Afficher publiquement
w.AbsoCaroussel = AC;

})(window,jQuery);
