/**
 * image_transition plugin: permite a criação de transições de banners com controles embutidos.
 *
 * Copyright (C) Tiki Web Inteligente 2010.
 * $Id: jquery.image_transition.js 74 2011-01-28 19:17:38Z tikiweb $
 */
jQuery.fn.image_transition = (function(options) {

    return this.each(function() {

        var $ = jQuery;

        if (!options) options = {};

        options = $.extend({
            // quanto tempo cada imagem fica visível
            duration: 5000,
            // o seletor para o stage (onde a imagem atual é apresentada)
            stageSelector: null,
            // o seletor para os itens (os elementos que guardam as urls de imagens e urls dos alvos das imagens)
            itemsSelector: null,
            // como encontrar a url da imagem a ser apresentada
            itemImageSelector: '.image_url',
            // como encontrar a url do alvo da imagem a ser apresentada
            itemTargetSelector: '.target_url',
            // invocado para redefinir o html do stage
            onStageUpdate: function(html) {
                $(this).html(html);
            }
        }, options);

        var currentIndex = 0, // item atual
            $currentItem = null, // item atual (objeto jQuery)
            items = [], // para cada item: url da imagem, url do alvo e estado de carregamento da imagem (objeto puro)
            $items = $(this).find(options.itemsSelector), // todos os itens (objeto jQuery)
            $loading = $(this).find('.loading'), // o elemento que aparece sobre a imagem enquanto a próxima ainda não foi carregada
            $stage = $(this).find(options.stageSelector), // o stage (objeto jQuery)
            totalItems = $(this).find(options.itemsSelector).length, // quantidade total de itens que serão apresentadas durante a transição
            transitions = null, // (objeto criado a partir de setInterval)
            transitionsStarted = false, // indica se ao menos 1 imagem já foi exibida no stage
            userWaiting = false; // indica se o usuário clicou em um item e está esperando pelo seu carregamento

        // inicializa os itens
        items = buildItems();

        // inicia o preload de imagens e a transição de banners
        preloadImages();

        // permite ao usuário mudar a imagem atual dentro do stage
        $items.click(function() {

            // impede que a primeira imagem seja colocada no stage
            // ao terminar de ser carregada
            transitionsStarted = true;

            clearInterval(transitions);

            currentIndex = ($(this).index() % totalItems);
            $currentItem = $items.eq(currentIndex);

            $items.filter('.current').removeClass('current');
            $currentItem.addClass('current');

            if (!items[currentIndex].ready) {
                $loading.show();
                userWaiting = true;
            }

            else {
                options.onStageUpdate.call($stage, items[currentIndex].html);
                $loading.hide();

                clearInterval(transitions);
                transitions = setInterval(singleTransition, options.duration);
            }
        });

        function singleTransition() {

            currentIndex = ((currentIndex + 1) % totalItems);
            $currentItem = $items.eq(currentIndex);

            if (!items[currentIndex].ready) {
                $loading.show();
                currentIndex--;
            }

            else {
                $items.filter('.current').removeClass('current');
                $currentItem.addClass('current');

                options.onStageUpdate.call($stage, items[currentIndex].html);
                $loading.hide();
            }
        }

        function preloadImages() {

            // realiza o preloading das imagens
            for (var i in items) {

                var preloader = new Image();
                preloader.itemIndex = i;

                preloader.onload = function(e) {

                    items[this.itemIndex].ready = true;

                    // se o usuário não clicou em nenhum item e a transição de banners
                    // ainda não foi iniciada, deve ser iniciada agora que
                    // temos a primeira imagem carregada
                    if (!transitionsStarted && this.itemIndex == 0) {
                        currentIndex = 0;
                        options.onStageUpdate.call($stage, items[0].html);

                        $loading.hide();

                        clearInterval(transitions);
                        transitions = setInterval(singleTransition, options.duration);
                    }

                    // se o usuário clicou em uma imagem, está esperando
                    // seu carregamento, e ela acabou de ser carregada
                    else if (userWaiting && this.itemIndex == currentIndex) {
                        currentIndex = this.itemIndex;
                        options.onStageUpdate.call($stage, items[currentIndex].html);

                        $loading.hide();
                        userWaiting = false;

                        clearInterval(transitions);
                        transitions = setInterval(singleTransition, options.duration);
                    }
                }

                // inicia o preloading
                preloader.src = items[i].imageUrl;
            }
        }

        function buildItems() {

            var items = [];

            $items.each(function() {

                var targetUrl = $(this).find(options.itemTargetSelector).html();
                var imageUrl = $(this).find(options.itemImageSelector).html();

                var $img = $('<img/>', { src: imageUrl });
                var $dummyParent;

                // conteúdo do item é uma imagem envolvida por um link
                if (targetUrl) {
                    $a = $('<a/>', { href: targetUrl, target: 'external' });
                    $a.html($img);
                    $dummyParent = $('<div/>').html($a);
                }

                // conteúdo do item é apenas uma imagem
                else {
                    $dummyParent = $('<div/>').html($img);
                }

                var item = {
                    "ready": false,
                    "imageUrl": imageUrl,
                    "targetUrl": targetUrl,
                    "html": $dummyParent.html()
                };

                items.push(item);
            });

            return items;
        }
    });
});

