/*--------------------------------------------------------------------------------------------------//
// AbsoCaroussel -----------------------------------------------------------------------------------//
//--------------------------------------------------------------------------------------------------//
// Date   	    : février 2011
// Auteur	    : Jean-Baptiste Landry
// Requirements : jQuery 1.5.0
//--------------------------------------------------------------------------------------------------*/
(function(w, $, undefined) {


    var DEBUG = false;

    var all = {};
    var AC = {};

    AC.version = '0.5.2';
    AC.toString = function() { return '[ Abso.Caroussel v' + AC.version + ' ]'; };

    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.startId = (Number(options.startId)) ? Number(options.startId) : 1;
        /*
        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.$Main = $('#' + c.id);
        if (!c.$Main.length) { return false; }

        c.$MainItems = c.$Main.find('> li');
        c.$MainFirstItem = c.$Main.find('> li:first-child');
        c.total = c.$MainItems.length;

        // 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-"]');
        c.$play = $('.AbsoCaroussel-' + c.id + '-Play');
        c.$pause = $('.AbsoCaroussel-' + c.id + '-Pause');

        // position
        c.$position = $('.AbsoCaroussel-' + c.id + '-Position');
        c.$total = $('.AbsoCaroussel-' + c.id + '-Total');
        c.$status = $('.AbsoCaroussel-' + c.id + '-Status');
        c.$statusNum = $('.AbsoCaroussel-' + c.id + '-StatusNum');

        // 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');
            c.$statusNum.addClass('AbsoCaroussel-Aucun');

            // sinon préparer caroussel
        } else {

            // initial
            c.curr = c.startId - 1;
            c.switching = false;

            // general events				
            c.debutClick = function(e) {
                e.preventDefault();
                Switch(c, 0);
            };

            c.precedentClick = function(e) {
                e.preventDefault();
                Switch(c, 'prev');
            };

            c.suivantClick = function(e) {
                e.preventDefault();
                Switch(c, 'next');
            };

            c.finClick = function(e) {
                e.preventDefault();
                Switch(c, c.total - 1);
            };

            c.itemSimpleClick = function(e) {
                e.preventDefault();
                Switch(c, new RegExp('AbsoCaroussel-' + c.id + '-Item-([0-9]+)').exec($(this).attr('class'))[1] - 1);
            };

            c.playClick = function(e) {
                e.preventDefault();
                c.AutoRunning = true;
                c.slideStartAuto();
            };

            c.pauseClick = function(e) {
                e.preventDefault();
                c.AutoRunning = false;
                c.slideStopAuto();
            };

            c.slideStartAuto = function() {
                if (c.AutoRunning) {
                    c.Timeout = setTimeout(function() { Switch(c, 'next', true); }, c.autointerval);
                }
            };

            c.slideStopAuto = function() {
                clearTimeout(c.Timeout);
                c.Timeout = undefined;
            };




            // 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(e) {
                    e.preventDefault();
                    Switch(c, i);
                });
            });

            c.$play.click(c.playClick)
            c.$pause.click(c.pauseClick);

            c.$MainItems
			.mouseenter(c.slideStopAuto)
			.mouseleave(c.slideStartAuto)
		;




            // intialiser look
            c.$total.html(c.total);
            Refresh(c);

            c.$MainItems.hide();
            c.$Main.find('> li:nth-child(' + c.startId + ')').show();

            switch (c.transition) {
                // fade 
                case 'fade':
                    break;


                // move vertical 
                case 'slideUp':
                case 'slideDown':
                    c.$MainItems.css({
                        left: '0px'
                    });
                    c.$MainFirstItem.css('top', '0px');
                    break;

                // move horizontal 
                case 'slideLeft':
                case 'slideRight':
                default:
                    c.$MainItems.css({
                        top: '0px'
                    });
                    c.$MainFirstItem.css('left', '0px');
                    break;
            }


            // autostart	
            if (c.autointerval != undefined) {
                c.AutoRunning = true;
                c.slideStartAuto();
            }


            // 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;
        c.slideStopAuto();

        var callbackData = {
            action: (Number(target) == target) ? 'item' : target,
            source: {
                position: c.curr + 1
            },
            target: {}
        };

        var way;

        // current li
        var $liCurr = c.$Main.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.$Main.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.$Main.height() + 'px';
            var width = c.$Main.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.$Main.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.$Main.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);
        }

        c.slideStartAuto();
    }



    /* 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('');
        c.$statusNum.html('');
        for (var i = 0; i < c.total; ++i) {
            if (i == c.curr) {
                c.$status.append('<strong>' + c.statusBullet + '</strong>');
                c.$statusNum.append('<span><strong>' + (i + 1) + '</strong></span>');
            } else {
                if (c.statusLink) {
                    c.$status.append(
					$("<a>")
						.attr("href", "#")
						.addClass('AbsoCaroussel-' + c.id + '-Item-' + (i + 1))
						.click(c.itemSimpleClick)
						.html(c.statusBullet)
				    );
                    c.$statusNum.append(
					$("<a>")
						.attr("href", "#")
						.addClass('AbsoCaroussel-' + c.id + '-Item-' + (i + 1))
						.click(c.itemSimpleClick)
						.html(i + 1)
				    );
                } else {
                    c.$status.append(c.statusBullet);
                    //c.$statusNum.append(i+1);
                    c.$statusNum.append('<span>' + (i + 1) + '</span>');
                }
            }
        }
    }









    /* 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.Abso = w.Abso || {};
    w.Abso.Caroussel = AC;

})(window, jQuery);
