/*
*	Name:			jquery.ryfader.2.1.js
    Purpose:        Rebuild of the fader plugin with proper create,update,destroy functions
*/

(function ($) {
    jQuery.fn.ryfader = function (options, i) {
        if (this.length > 1) {
            var a = new Array();
            this.each(
                function (i) {
                    a.push($(this).ryfader(options, i));
                });
            return a;
        }


        var opts = $.extend({}, $().ryfader.defaults, options);
        var slideWidth, slideHeight, frameCount, currentFrame, playInterval, playState;


        /* PUBLIC FUNCTIONS */
        this.Destroy = function (reInit) {
            var container = this, $wrapper = $(container).parent(), reInit = (reInit != undefined) ? reInit : false;
            var reInit = (reInit != undefined) ? reInit : false;
            if (opts.beforeDestroyFunction != null && $.isFunction(opts.beforeDestroyFunction))
                opts.beforeDestroyFunction($(container), opts);

            $(container).children().stop();

            if (opts.stateSelector == null)
                $wrapper.children('.' + opts.stateContainerClass).remove();
            else
                $(opts.stateSelector).children('.' + opts.stateContainerClass).remove();

            if (opts.pageSelector == null)
                $wrapper.children('.' + opts.pageContainerClass).remove();
            else
                $(opts.pageSelector).children('.' + opts.pageContainerClass).remove();

            if (opts.nextSelector == null)
                $wrapper.children('.' + opts.nextButtonClass).remove();
            else
                $(opts.nextSelector).unbind('click.ryFader.onNextClick').removeClass(opts.enabledClass + ' ' + opts.nextButtonClass);
            if (opts.prevSelector == null)
                $wrapper.children('.' + opts.prevButtonClass).remove();
            else
                $(opts.prevSelector).unbind('click.ryFader.onPrevClick').removeClass(opts.enabledClass + ' ' + opts.prevButtonClass);

            if (opts.playSelector == null)
                $wrapper.children('.' + opts.playButtonClass).remove();
            else
                $(opts.playSelector).unbind('click.ryFader.onPlayClick').removeClass(opts.enabledClass + ' ' + opts.playButtonClass);

            if (opts.stopSelector == null)
                $wrapper.children('.' + opts.stopButtonClass).remove();
            else
                $(opts.stopSelector).unbind('click.ryFader.onStopClick').removeClass(opts.enabledClass + ' ' + opts.stopButtonClass);

            $(container).children(opts.contentElement).each(function (index) {
                $(this).removeAttr('style').removeClass('frame-' + (index + 1) + ' ' + opts.contentClass + ' ' + opts.enabledClass);
            });
            slideWidth = null, slideHeight = null, frameCount = null, currentFrame = null, playInterval = null;

            $(container).removeData('rySlider').removeAttr('style').removeClass(opts.containerClass).unwrap();

            if (opts.afterDestroyFunction != null && $.isFunction(opts.afterDestroyFunction))
                opts.afterDestroyFunction($(container), opts);
        }; // END DESTROY

        this.Update = function (options) {
            opts = null;
            opts = $.extend({}, $().ryfader.defaults, options);
            this.Destroy(true);
            return this.Create();
        };

        this.Create = function (iteration) {
            var container = this;
            if ($(container).data('ryFader') == true)
                return this;

            if (opts.beforeCreateFunction != null && $.isFunction(opts.beforeCreateFunction))
                opts.beforeCreateFunction($(container), opts);

            var totalWidth = 0, actualSlideWidth = null;

            $(container).data('ryFader', true);

            slideWidth = $(container).width();
            slideHeight = $(container).outerHeight(true);
            frameCount = $(container).children(opts.contentElement).size();
            var $wrapper = $(container).wrap('<div class="' + opts.wrapperClass + '" />').parent();
            $(container).addClass(opts.containerClass);

            // catch stupidity
            if (opts.startItem <= 0 || opts.startItem == null)
                currentFrame = 1;
            else if (opts.startItem >= frameCount)
                currentFrame = frameCount;
            else
                currentFrame = 1;

            $(container).children(opts.contentElement).each(function (index) {
                var $frame = $(this), opacityValue = 0, zIndexValue = opts.zIndexBase;
                $frame.addClass('frame-' + (index + 1) + ' ' + opts.contentClass);
                if (slideWidth == null)
                    slideWidth = $frame.width();
                if (index + 1 == currentFrame) {
                    $frame.addClass(opts.enabledClass);
                    opacityValue = 1;
                    zIndexValue += frameCount;
                }

                $frame.css({ left: parseInt($frame.css('margin-left')), top: parseInt($frame.css('margin-top')), zIndex: zIndexValue });
                if (opacityValue != 1)
                    $frame.hide();
            });

            // create paging buttons and pager links
            if (frameCount > 1) {
                if (opts.renderNext) {
                    if (opts.nextSelector == null)
                        $('<a href="#" class="' + opts.nextButtonClass + '">Next</a>').appendTo($wrapper).bind('click.ryFader.onNextClick', function () { moveSlide(container, 1, true, true); return false; });
                    else
                        $(opts.nextSelector).addClass(opts.nextButtonClass).bind('click.ryFader.onNextClick', function () { moveSlide(container, 1, true, false); return false; });
                }

                if (opts.renderPrevious) {
                    if (opts.prevSelector == null)
                        $('<a href="#" class="' + opts.prevButtonClass + '">Previous</a>').appendTo($wrapper).bind('click.ryFader.onPrevClick', function () { moveSlide(container, 1, true, false); return false; });
                    else
                        $(opts.prevSelector).addClass(opts.prevButtonClass).bind('click.ryFader.onPrevClick', function () { moveSlide(container, 1, true, false); return false; });
                }

                if (opts.enablePlayStop) {
                    // Play Button

                    var play, stop;
                    if (opts.renderPlayButton) {
                        if (opts.playSelector == null)
                            play = $('<a href="#">Play</a>').appendTo($wrapper).addClass(opts.playButtonClass).bind('click.ryFader.onPlayClick', function () { playFader(container); return false; });
                        else
                            play = $(opts.playSelector).addClass(opts.playButtonClass).bind('click.ryFader.onPlayClick', function () { playFader(container); return false; });

                        if (opts.autoPlay)
                            play.addClass(opts.enabledClass);
                    }

                    // Stop Button
                    if (opts.renderStopButton) {
                        if (opts.stopSelector == null)
                            stop = $('<a href="#">Stop</a>').appendTo($wrapper).addClass(opts.stopButtonClass).bind('click.ryFader.onStopClick', function () { stopFader(container); return false; });
                        else
                            stop = $(opts.stopSelector).addClass(opts.stopButtonClass).bind('click.ryFader.onStopClick', function () { stopFader(container); return false; });

                        if (!opts.autoPlay)
                            stop.addClass(opts.enabledClass);
                    }
                }

                // create pager buttons
                if (opts.renderPageButtons) {
                    var pageContainer, pageButtons = '';
                    if (opts.pageSelector == null)
                        pageContainer = $('<ul class="' + opts.pageContainerClass + '"></ul>').appendTo($wrapper);
                    else
                        pageContainer = $('<ul class="' + opts.pageContainerClass + '"></ul>').appendTo(opts.pageSelector);

                    for (i = 1; i <= frameCount; i = i + 1) {
                        var handleText = (opts.handleNames != null && opts.handleNames[i - 1] != null && opts.handleNames[i - 1] != undefined) ? opts.handleNames[i - 1] : i;
                        pageButtons += '<li><a class="' + 'page-' + i + ' ' + opts.pageButtonClass + '" href="#" name="' + i + '">' + handleText + '</a></li>';
                    }
                    pageContainer.append(pageButtons);

                    pageContainer.delegate('a', 'click.ryFader.onPageButtonClick', function (event) {
                        gotoFrame(container, $(this).attr('name'), true);
                        return false;
                    });
                }

                if (opts.renderStateInfo) {
                    var stateContainer, tmpframeCount = frameCount;
                    if (opts.stateSelector == null)
                        stateContainer = $('<div class="' + opts.stateContainerClass + '"></div>').appendTo($wrapper);
                    else
                        stateContainer = $('<div class="' + opts.stateContainerClass + '"></div>').appendTo(opts.stateSelector);
                    $('<span class="currentFrameNumber">' + currentFrame + '</span>' + ' of ' + '<span class="totalframeCount">' + tmpframeCount + '</span>').appendTo(stateContainer);
                }

                if (opts.autoPlay)
                    playFader($(container));

                updateIcons($(container));

            }
            else
                $wrapper.addClass(opts.notEnoughChildrenClass);

            if (opts.afterCreateFunction != null && $.isFunction(opts.afterCreateFunction))
                opts.afterCreateFunction($(container), opts);
            return this;
        }; // END CREATE

        this.Next = function (goToAndStop) { moveSlide(this, 1, goToAndStop, true); };
        this.Previous = function (goToAndStop) { moveSlide(this, 1, goToAndStop, false); };
        this.Play = function () { playFader(this); };
        this.Stop = function () { stopFader(this); };
        this.GotoFrame = function (frameNumber, goToAndStop) { gotoFrame(this, frameNumber, goToAndStop); };
        this.CurrentFrame = function () { return currentFrame; };
        this.FrameCount = function () { return frameCount; };
        this.IsPlaying = function () { return playState; };

        /* PRIVATE FUNCTIONS */

        // worker function to turn on autoPlay
        function playFader(container) {
            if (!opts.enablePlayStop)
                return false;
            playInterval = setInterval(function () {
                moveSlide(container, 1, false, true);
            }, opts.autoPlayInterval);
            if (opts.playSelector == null)
                $(container).parent().find('.' + opts.playButtonClass).addClass(opts.enabledClass);
            else
                $(opts.playSelector).addClass(opts.enabledClass);
            if (opts.stopSelector == null)
                $(container).parent().find('.' + opts.stopButtonClass).removeClass(opts.enabledClass);
            else
                $(opts.stopSelector).removeClass(opts.enabledClass);
            playState = true;
        }

        // a worker function to turn off autoPlay
        function stopFader(container) {
            if (!opts.enablePlayStop)
                return false;
            clearInterval(playInterval);
            playInterval = null;
            if (opts.playSelector == null)
                $(container).parent().find('.' + opts.playButtonClass).removeClass(opts.enabledClass);
            else
                $(opts.playSelector).removeClass(opts.enabledClass);
            if (opts.stopSelector == null)
                $(container).parent().find('.' + opts.stopButtonClass).addClass(opts.enabledClass);
            else
                $(opts.stopSelector).addClass(opts.enabledClass);
            playState = false;
        }

        // Worker function to update the page icons
        function updateIcons(container) {
            var pageContainer, stateContainer;
            if (opts.pageSelector == null)
                pageContainer = $(container).parent().find('.' + opts.pageContainerClass);
            else
                pageContainer = $(opts.pageSelector);
            pageContainer.find('a.' + opts.pageButtonClass + ':not(:eq(' + (currentFrame - 1) + '))').removeClass(opts.enabledClass);
            pageContainer.find('a.' + opts.pageButtonClass + ':eq(' + (currentFrame - 1) + ')').addClass(opts.enabledClass);

            if (opts.stateSelector == null)
                stateContainer = $(container).parent().find('.' + opts.stateContainerClass);
            else
                stateContainer = $(opts.stateSelector);

            stateContainer.find('.currentFrameNumber').html(currentFrame);
            stateContainer.find('.totalframeCount').html(frameCount);
        }

        // Wrapper function to move by page
        function gotoFrame(container, page, stopAutoplay) {
            //should probably put this in a loop to stop crazy stuff.
            var difference = Math.abs(currentFrame - page);
            if (difference > 0) {
                if (currentFrame < page)
                    moveSlide(container, difference, stopAutoplay, true);
                else if (currentFrame > page)
                    moveSlide(container, difference, stopAutoplay, false);
            }
        }

        // fade the sider, move it to the right position
        function resetFader(container, frameNumber, stopAutoplay) {
            gotoFrame(container, opts.startItem, stopAutoplay);
        }

        // worker function for swapping out slides
        function moveSlide(container, itemsToMoveBy, stopAutoplay, goForwards) {
            if ($(container).find('.' + opts.contentClass + ':animated').size() > 0)
                return false;
            var direction = (goForwards != true) ? 'previous' : 'next', itemsToMoveBy = (itemsToMoveBy == null) ? opts.startItem : itemsToMoveBy, stopAutoplay = (stopAutoplay != true) ? false : true, $currentFrame = $(container).children('.' + opts.contentClass + ':nth-child(' + currentFrame + ')'), newFrameNumber = 0;

            if (opts.beforeFadeFunction != null && $.isFunction(opts.beforeFadeFunction))
                opts.beforeFadeFunction($(container), currentFrame, itemsToMoveBy, opts, direction);

            if (stopAutoplay)
                stopFader(container);

            if (goForwards) {
                newFrameNumber = (currentFrame + itemsToMoveBy > frameCount) ? itemsToMoveBy : currentFrame + itemsToMoveBy;
            }
            else
                newFrameNumber = (currentFrame - itemsToMoveBy < 1) ? frameCount : currentFrame - itemsToMoveBy;

            var $newPage = $(container).children('.' + opts.contentClass + ':nth-child(' + newFrameNumber + ')');

            if (!opts.waitToFinish) {
                $currentFrame.fadeOut(opts.speed, opts.easingMethod, function () {
                    $(this).removeClass(opts.enabledClass).css('z-index', opts.zIndexBase);
                });
                /*$currentFrame.animate({ opacity: '0' }, { duration: opts.speed, easing: opts.easingMethod, complete: function () {
                $(this).removeClass(opts.enabledClass).css('z-index', opts.zIndexBase);
                }
                });*/
                $newPage.fadeIn(opts.speed, opts.easingMethod, function () {
                    $(this).addClass(opts.enabledClass).css('z-index', opts.zIndexBase + frameCount);
                    currentFrame = ($newPage.index() + 1);
                    updateIcons(container);

                    /*if (stopAutoplay && opts.autoPlay == true)
                    playFader(container);

                    if (opts.afterFadeFunction != null && $.isFunction(opts.afterFadeFunction))
                    opts.afterFadeFunction($(container), newFrameNumber, itemsToMoveBy, opts, direction);*/
                });
                /* $newPage.animate({ opacity: '1' }, { duration: opts.speed, easing: opts.easingMethod, complete: function () {
                $(this).addClass(opts.enabledClass).css('z-index', opts.zIndexBase + frameCount);
                currentFrame = ($newPage.index() + 1);
                updateIcons(container);

                if (stopAutoplay && opts.autoPlay == true)
                playFader(container);

                if (opts.afterFadeFunction != null && $.isFunction(opts.afterFadeFunction))
                opts.afterFadeFunction($(container), newFrameNumber, itemsToMoveBy, opts, direction);
                }
                });*/
            }
            else {
                $currentFrame.fadeOut(opts.speed, opts.easingMethod, function () {
                    $(this).removeClass(opts.enabledClass).css('z-index', opts.zIndexBase);
                    $newPage.fadeIn(opts.speed, opts.easingMethod, function () {
                        $(this).addClass(opts.enabledClass).css('z-index', opts.zIndexBase + frameCount);
                        currentFrame = ($newPage.index() + 1);
                        updateIcons(container);

                        if (stopAutoplay && opts.autoPlay == true)
                            playFader(container);

                        if (opts.afterFadeFunction != null && $.isFunction(opts.afterFadeFunction))
                            opts.afterFadeFunction($(container), newFrameNumber, itemsToMoveBy, opts, direction);
                    });
                });
                /* $currentFrame.animate({ opacity: '0' }, { duration: opts.speed, easing: opts.easingMethod, complete: function () {
                $(this).removeClass(opts.enabledClass).css('z-index', opts.zIndexBase);
                $newPage.animate({ opacity: '1' }, { duration: opts.speed, easing: opts.easingMethod, complete: function () {
                $(this).addClass(opts.enabledClass).css('z-index', opts.zIndexBase + frameCount);
                currentFrame = ($newPage.index() + 1);
                updateIcons(container);

                if (stopAutoplay && opts.autoPlay == true)
                playFader(container);

                if (opts.afterFadeFunction != null && $.isFunction(opts.afterFadeFunction))
                opts.afterFadeFunction($(container), newFrameNumber, itemsToMoveBy, opts, direction);
                }
                });
                }
                });*/
            }
        }

        // Finally
        return this.Create(i);
    };

    jQuery.fn.ryfader.defaults = {
        speed: 500,
        startItem: 1,
        zIndexBase: 10,
        easingMethod: 'easeOutQuad',
        enablePlayStop: false,
        handleNames: null,
        waitToFinish: false,
        autoPlay: false,
        autoPlayInterval: 2000,
        renderNext: true,
        nextSelector: null,
        renderPrevious: true,
        prevSelector: null,
        renderPageButtons: true,
        pageSelector: null,
        renderPlayButton: true,
        playSelector: null,
        renderStopButton: true,
        stopSelector: null,
        renderStateInfo: true,
        stateSelector: null,
        contentElement: 'div',
        contentClass: 'fader_content',
        wrapperClass: 'fader_wrapper',
        containerClass: 'ryfader',
        nextButtonClass: 'next_button',
        prevButtonClass: 'previous_button',
        pageButtonClass: 'page_button',
        playButtonClass: 'play_button',
        stopButtonClass: 'stop_button',
        pageContainerClass: 'page_container',
        stateContainerClass: 'state_container',
        notEnoughChildrenClass: 'notEnoughChildren',
        enabledClass: 'active',
        beforeCreateFunction: null,
        afterCreateFunction: null,
        beforeFadeFunction: null,
        afterFadeFunction: null,
        beforeDestroyFunction: null,
        afterDestroyFunction: null
    };
})(jQuery);


