/*
    Componente para comportamento de carrossel, vertical / horizontal.
    @author Hudson Tavares <hudson.tavares@gmail.com>
    @created 2011-04-26 12:44
*/

if(!('fess' in window))window.fess = {};

fess.carroussel =
{
    init: function(params)
    {
        /* Configuração geral do slider */
        params = $.extend
        (
            {
                next        : null,     /* CSS expression para o botão de navegação "próximo" (move para a próxima página de itens) */
                previous    : null,     /* CSS expression para o botão de navegação "anterior" (move para a página anterior de itens) */
                slidable    : null,     /* CSS expression para o elemento que terá seu margin-left alterado */
                children    : null,     /* CSS expression para a coleção de filhos do elemento slidável */
                index       : 0,        /* Posição inicial */
                speed       : 'fast',   /* Velocidade de movimentação */
                walkBy      : 1,         /* Número de filhos a mover por clique em anterior / próximo */
                after       : function(params){} /* Função a executar após cada navegação (params é uma referência a esse objeto) */
            },
            params
        );
        
        params.next     = $(params.next);
        params.previous = $(params.previous);
        params.slidable = $(params.slidable);
        params.children = $(params.children);
        
        /*
        params.previous.hide()
        params.next.hide()
        */
        params.previous.show()
        params.next.show()
        
        params.slidable.width(params.children.length * params.children.width());
                
        if(params.slidable.length == 0)return false;
        
        /* Comportamentos de clique */
        if(params.previous.length != 0 && params.next.length != 0)
        $([params.previous[0], params.next[0]]).bind
        (
            'click',
            function(e)
            {
                var target = $(this), desiredIndex = null;
                
                switch(true)
                {
                    /* Anterior */
                    case this == params.previous[0]:

                        if(params.index <= 0)return false;

                        desiredIndex = params.index - params.walkBy;
                        if(desiredIndex < 0)desiredIndex = 0;
                    break;
                    /* Próximo */
                    case this == params.next[0]:

                        if(params.index >= params.children.length - 1)return false;
                        desiredIndex = params.index + params.walkBy;
                        
                        if((params.children.length - desiredIndex - 1) < params.walkBy)
                            desiredIndex = params.index + (params.children.length - desiredIndex);
                    break;
                }
                
                if(desiredIndex == null)return false;
                fess.carroussel.moveTo(params, desiredIndex);
                
                
                e.preventDefault();
                e.stopPropagation();
                return true;
            }
        );
        
        fess.carroussel.moveTo(params, params.index);
        return params;
    },
    reassignPositions: function(params)
    {
        /*
        params.index == 0 ? params.previous.fadeOut() : params.previous.fadeIn();
        params.index >= params.children.length - params.walkBy ? params.next.fadeOut(): params.next.fadeIn();
        */

        params.index == 0 ? params.previous.addClass('inativo') : params.previous.removeClass('inativo');
        params.index >= params.children.length - params.walkBy ? params.next.addClass('inativo') : params.next.removeClass('inativo');
        
        if(params.after.constructor == Function)params.after.apply(this, [params]);
        return true;
    },
    moveTo: function(params, index)
    {
        if(params.slidable.is(':animated') || params.children.eq(index).length == 0)return false;
        
        params.slidable.animate
        (
            {/*'margin-top' : -params.children.eq(index).position().top,*/
             'margin-left': -params.children.eq(index).position().left},
             params.speed,
            function()
            {
                params.index = index;
                fess.carroussel.reassignPositions(params);
            }
        );
        
        return true;
    },
    currentlyShown: function(params, index)
    {
        var returnData  = {start: index, end: 0},
            viewSize    = {width: params.slidable.parent().width(), height: params.slidable.parent().height()},
            lastMeasure = null;

        for(var counter = returnData.start, sizeContent = {width: 0, height: 0};counter < params.children.length;counter++)
        {
            if(lastMeasure == null)
            {
                lastMeasure     = {top : params.children.eq(counter).position().top,
                                   left: params.children.eq(counter).position().left};
                returnData.end  = counter;
                continue;
            }
            
            var currentPos = {top: params.children.eq(counter).position().top, left: params.children.eq(counter).position().left};
            
            if(lastMeasure.left != currentPos.left)sizeContent.width += (currentPos.left - lastMeasure.left);
            if(lastMeasure.top  != currentPos.top)sizeContent.height += (currentPos.top - lastMeasure.top);
            
            if(sizeContent.width >= viewSize.width)break;
            if(sizeContent.height >= viewSize.height)break;
            
            lastMeasure     = currentPos;
            returnData.end  = counter;
        }
        
        return returnData;
    },
    /* Remove bindings de um objeto */
    reset: function(params)
    {
        params.next.unbind('click');
        params.previous.unbind('click');
        
        params.index    = 0;        
        return true;
    }
};
