/**

 * When I noticed the growing popularity of JS-Slide and JS-Fade effects I have

 * decide to develop a plugin for jQuery. This plugin will help you to add thise

 * effects to the site in more simple way.

 * Note: If the mousewheel plugin has been included on the page then the slider will

 * also respond to the mouse wheel.

 *

 * @name jQuery ulSlide plugin

 * @license GPL

 * @version 1.4.8

 * @date January 31, 2011

 * @category jQuery plugin

 * @author Kotelnitskiy Evgeniy (evgennniy@gmail.com)

 * @copyright (c) 2011 Kotelnitskiy Evgeniy (http://4coder.info/en/)

 * @example Visit http://4coder.info/en/code/jquery-plugins/ulslide/ for more informations about this jQuery plugin

 */

(function($) {

    ulslide_last_id = 0;



    $.fn.ulslide = function(settings) {

        var thisObj = this;

        if (thisObj.length == 0) return false;

        var thisEl = thisObj[0];

        if (! $(thisEl).attr('id')) {

            ulslide_last_id ++;

            $(thisEl).attr('id', 'ulslide-' + ulslide_last_id);

        }

        var id = $(thisEl).attr('id');



        // Settings

        settings = $.extend({

            effect: {

                type: 'slide', // slide, fade or carousel (use showCount for carousel)

                axis: 'x',     // x, y

                distance: 20   // Distance between frames

            },

            duration: 600,     // Changing duration

            direction: 'f',    // f, b

            autoslide: false,  // Autoscrolling interval (ms)

            current: 0,



            width: thisObj.width(),

            height: 'auto',    // pixels or 'auto'



            statusbar: true,

            lazyload: false,   // testing

            ajax: false,



            mousewheel: false, // Scroll on "mousewheel"



            // Selectors:

            pager: false,

            nextButton: false,

            prevButton: false,

            printCurrentTo: false,



            //framesOnPage: 2,

            onAnimateStart: function(settings, thisEl){},

            onAnimate: function(settings, thisEl){},

            onAjaxStart: function(settings, thisEl){},

            onAjaxStop: function(settings, thisEl){}

        },settings);



        // Deprecated Options

        if (typeof settings['affect']        != 'undefined') settings['effect']['type']     = settings['affect'];

        if (typeof settings['axis']          != 'undefined') settings['effect']['axis']     = settings['axis'];

        if (typeof settings['padding']       != 'undefined') settings['effect']['distance'] = settings['padding'];

        if (typeof settings['navigator']     != 'undefined') settings['pager']              = settings['navigator'];

        if (typeof settings['print_current'] != 'undefined') settings['printCurrentTo']     = settings['print_current'];

        if (typeof settings['bnext']         != 'undefined') settings['nextButton']         = settings['bnext'];

        if (typeof settings['bprev']         != 'undefined') settings['prevButton']         = settings['bprev'];

        // end Deprecated Options



        if (typeof settings['effect']['distance'] == 'undefined') settings['effect']['distance'] = 20;

        settings['fwidth'] = settings['width'] + settings['effect']['distance'];

        settings['prev'] = settings['current'];

        settings['count'] = $('> *', thisObj).length;



        if (settings['lazyload']) {

            $('img', thisObj).each(function(i){

                var img = $(this);

                img.attr('rel', img.attr('src'));

                if (i > 0) {

                    img.removeAttr("src");

                }

            });

            /*settings['_lazyloaded'][0] = true;*/

        }





                function carouselGetFramePos(i, current){

                        if (i >= settings['effect']['showCount'] - current) {

                                var l = settings['count'] - settings['effect']['showCount'];

                                var ci = (i + current - settings['effect']['showCount']) - l;

                                return ci;

                        }

                        else return i + current;

                }



                // CSS for elements

        $('> *', thisObj).each(function(i){

            var liel = $(this);

            liel.addClass('slide-node slide-node-'+i);

            liel.css("position", 'absolute');

            liel.css("margin", '0');

            liel.css("distance", '0');

            liel.css("width", settings['width']);

            liel.css("overflow", "hidden");



                        if (settings['effect']['type'] == 'carousel') {

                                var ci = carouselGetFramePos(i, settings['current']);



                                liel.css("top", '0');

                                liel.css("left", (ci * settings['fwidth']));

                        }

                        else {

                                if (i == settings['current']){

                                        liel.css("top", '0');

                                        liel.css("left", '0');

                                }

                                else{

                                        liel.css("top", '0');

                                        liel.css("left", -(settings['width'] + settings['effect']['distance']));

                                }

                        }

        });



                // CSS for container

        thisObj.css("list-style", "none");

        thisObj.css("distance", "0");

        thisObj.css("position", "relative");

        thisObj.css("overflow", "hidden");

        thisObj.css("padding", 0);



                if (settings['effect']['type'] == 'carousel') {

                        thisObj.css("width", settings['fwidth'] * settings['effect']['showCount'] - settings['effect']['distance']);

                }

                else {

                        thisObj.css("width", settings['width']);

                }





        if (settings['height'] == 'auto'){

            thisObj.css("height", $('> *:eq('+settings['current']+')', thisObj).height());

        }

        else thisObj.css("height", settings['height']);

        settings['prevHeight'] = settings['height'];



        thisEl.getSlide = function getSlide(num) {

            return $('> *:eq('+num+')', thisEl);

        };



        function next() {

            var c = thisEl.uslCurrent();

            settings['direction'] = 'f';

            if (c + 1 < settings['count']) {

                thisEl.uslRefresh(c + 1);

            } else {



                thisEl.uslRefresh(0);

            }

        }



        function prev() {

            var c = thisEl.uslCurrent();

            settings['direction'] = 'b';

            if (c > 0) {

                thisEl.uslRefresh(c - 1);

            } else {

                thisEl.uslRefresh(settings['count'] - 1);

            }

        }



        if (settings['height'] == 'auto')

            thisEl.currentHeight = thisEl.getSlide(settings['current']).height();

        else thisEl.currentHeight = settings['height'];



        thisEl.uslCurrent = function(new_value){

            if (new_value == undefined){

                return settings['current'];

            }

            else {

                var old = thisEl.uslCurrent();

                var c = new_value;



                settings['current'] = new_value;

                return new_value;

            }

        };



        thisEl.autoslideNext = function(){

                        if (settings['direction'] == 'f') next();

            else prev();

        };



        thisEl.initAutoslide = function(){

            if (settings['TimeoutID']) clearTimeout(settings['TimeoutID']);

            settings['TimeoutID'] = setTimeout("jQuery('#"+$(thisEl).attr('id')+"')[0].autoslideNext()", settings['autoslide']);

        };



        thisEl.clearAutoslide = function(){

            if (settings['TimeoutID']) {

                clearTimeout(settings['TimeoutID']);

            }

        };



        thisEl.uslRefresh = function(slide_index, fast, callback){

            if (! thisEl.ready) {

                //console.log(settings['id'] + ': ! thisEl.ready');

                setTimeout("$('#"+$(thisEl).attr('id')+"')[0].uslRefresh()", 400);

                return;

            }

            thisEl.ready = false;



            if (typeof(slide_index) != 'undefined') {

                thisEl.uslCurrent(slide_index);

            }



            thisEl.clearAutoslide();

            var prev = thisEl.getSlide(settings['prev']);

            var current = thisEl.getSlide(settings['current']);

            current.css('display', 'block');



            function doRefresh() {

                settings['onAnimateStart'](settings, thisEl); // notification

                //console.log(settings['id'] + ': doRefresh');



                if (settings['height'] == 'auto') {

                    thisEl.currentHeight = thisEl.getSlide(settings['current']).height();

                    settings['prevHeight'] = thisEl.getSlide(settings['prev']).height();

                }



                function finish_animate() {

                    if (settings['printCurrentTo']) {

                        $(settings['printCurrentTo']).html(settings['current'] + 1);

                    }



                    if ((settings['prev'] != settings['current']) && (settings['effect']['type'] != 'carousel') ) {

                        prev.css('display', 'none');

                    }



                    thisObj.animate({

                        'height': thisEl.currentHeight

                    }, 250/*, function() { alert(settings['id'] + ': finish_animate()' + thisEl.currentHeight); }*/);



                    //settings['prev'] = settings['current'];

                    if (settings['autoslide']) thisEl.initAutoslide();

                    settings['onAnimate'](settings, thisEl); // notification

                    settings['prev'] = settings['current'];

                    thisEl.uslRefreshClasses();

                    thisEl.ready = true;



                    if (typeof callback != 'undefined') callback();

                }



                if (settings['prev'] == settings['current']) {

                    finish_animate();

                    return;

                }



                if (settings['effect']['type'] == 'slide') {

                    if (settings['effect']['axis'] == 'x'){

                                                if (settings['prev'] != settings['current']){

                                                        if (settings['direction'] == 'f'){

                                                                prev.animate({

                                                                        'left': -(settings['width'] + settings['effect']['distance'])

                                                                }, settings['duration']);

                                                                current.css('left', settings['width'] + settings['effect']['distance']);

                                                        }

                                                        else{

                                                                prev.animate({

                                                                        'left': settings['width'] + settings['effect']['distance']

                                                                }, settings['duration']);

                                                                current.css('left', -(settings['width'] + settings['effect']['distance']));

                                                        }

                                                }

                                                current.animate({

                                                        'left': 0

                                                }, settings['duration'], function(){

                                                        finish_animate();

                                                });

                    }

                    else {

                        if (settings['prev'] != settings['current']){

                            if (settings['direction'] == 'f'){

                                prev.animate({

                                    'top': thisEl.currentHeight + settings['effect']['distance']

                                }, settings['duration'], function(){

                                    prev.css('left', -(settings['width'] + settings['effect']['distance']));

                                });

                                current.css('top', -(settings['prevHeight'] + settings['effect']['distance']));

                            }

                            else{

                                prev.animate({

                                    'top': -(thisEl.currentHeight + settings['effect']['distance'])

                                }, settings['duration'], function(){

                                    prev.css('left', -(settings['width'] + settings['effect']['distance']));

                                });

                                current.css('top', settings['prevHeight'] + settings['effect']['distance']);

                            }

                        }

                        current.css('left', 0);

                        current.animate({

                            'top': 0

                        }, settings['duration'], function(){

                            finish_animate();

                        });

                    }

                }

                else if (settings['effect']['type'] == 'fade') {

                    current.css('display', 'none');

                    //current.css('z-index', 2);

                    current.css('left', 0);

                    current.css('top', 0);

                    //prev.css('z-index', 1);

                    var duration = settings['duration'];

                    if (typeof fast != 'undefined') duration = 0;



                    prev.fadeOut(duration, function(){

                        prev.css('display', 'none');

                        current.fadeIn(duration, function(){

                            finish_animate();

                        });

                    });

                }

                                else if (settings['effect']['type'] == 'carousel') {

                                        $('> *', thisObj).each(function(i){

                                                liel = $(this);

                                                var ci = carouselGetFramePos(i, settings['current']);

                                                if (settings['direction'] == 'f')

                                                         var pi = carouselGetFramePos(i, settings['current'] - 1);

                                                else var pi = carouselGetFramePos(i, settings['current'] + 1);



                                                if ((settings['direction'] == 'f') && (ci == 0)) {

                                                        liel.css('left', (-1 * settings['fwidth']));

                                                        liel.animate({'left': ci * settings['fwidth']}, settings['duration']);

                                                }

                                                else if ((settings['direction'] == 'f') && (pi + 1 == settings['effect']['showCount'])) {

                                                        liel.animate({'left': (settings['effect']['showCount']) * settings['fwidth']}, settings['duration']);

                                                }

                                                else if ((settings['direction'] == 'b') && (pi == 0)) {

                                                        liel.animate({'left': -1 * settings['fwidth']}, settings['duration']);

                                                }

                                                else if ((settings['direction'] == 'b') && (ci + 1 == settings['effect']['showCount'])) {

                                                        liel.css('left', (ci + 1) * settings['fwidth']);

                                                        liel.animate({'left': ci * settings['fwidth']}, settings['duration']);

                                                }

                                                else {

                                                        if ((ci < settings['effect']['showCount']) && (ci >= 0)) {

                                                                liel.animate({'left': ci * settings['fwidth']}, settings['duration']);

                                                        }

                                                        else {

                                                                liel.css('left', (ci * settings['fwidth']));

                                                        }

                                                }



                                                setTimeout(function(){

                                                                finish_animate();

                                                }, settings['duration'] + 100);

                                        });

                                }

            }



            if (settings['ajax']) {

                settings['onAjaxStart'](settings, thisEl); // notification

                var statusbar_loaded = thisEl.getSlide(settings['current'])[0].usl_ajax_loaded;



                thisEl.uslAjaxLoadSlide(settings['current'], function() {

                                        settings['onAjaxStop'](settings, thisEl); // notification

                                        doRefresh();

                })

            }

            else {

                if (settings['lazyload']) {

                    var $imgToLoad = $('img', current[0]);



                    $imgToLoad.each(function(i){

                        var img = $(this);

                        img.attr('src', img.attr('rel'));

                    });



                    settings['z_img_count'] = $imgToLoad.length;

                    settings['z_img_loaded'] = 0;

                    $imgToLoad.each(function(){

                        if (this.complete) {

                            settings['z_img_loaded'] ++;

                        }

                        else {

                            $(this).load(function(){

                                settings['z_img_loaded'] ++;

                                if (settings['z_img_loaded'] == settings['z_img_count']){

                                    doRefresh();

                                }

                            });

                        }

                    });



                    if (settings['z_img_loaded'] == settings['z_img_count']){

                        doRefresh();

                    }

                    return;

                }



                doRefresh();

            }

        };



        thisEl.uslAjaxLoadSlide = function(slide_num, callback) {

            var current = thisEl.getSlide(slide_num);



            if (current[0].usl_ajax_loaded) {

                callback();

            }

            else {

                var url = $(settings['pager']).eq(slide_num).attr('href');

                current[0].usl_ajax_loaded = true;

                current.load(url + '?ajax=1', false, callback);

            }

        };



        thisEl.uslRefreshClasses = function(){

            if (settings['count'] > 1){

                if (settings['nextButton']) $(settings['nextButton']).addClass('active');

                if (settings['prevButton']) $(settings['prevButton']).addClass('active');

            }

            if (settings['pager']){

                $(settings['pager']).removeClass('usl-current');

                $(settings['pager'] + '.usl-pager-'+thisEl.uslCurrent()).addClass('usl-current');

                $(settings['pager']).parent().removeClass('usl-current-parent');

                $(settings['pager'] + '.usl-pager-'+thisEl.uslCurrent()).parent().addClass('usl-current-parent');

            }

        };



        if (settings['nextButton']){

            $(settings['nextButton']).click(function(){

                next();

                return false;

            });

        }



        if (settings['prevButton']){

            $(settings['prevButton']).click(function(){

                prev();

                return false;

            });

        }



        function setNavigator(s_navigator) {

            var pager = $(s_navigator);

            pager.each(function(index){

                this.usl_navigator_index = index;

                $(this).addClass('usl-pager-' + index);

            });



            pager.click(function(){

                var c = this.usl_navigator_index;

                if ((c < settings['count']) && (c != thisEl.uslCurrent())) {

                    //thisEl.uslCurrent(c);

                    if (c > thisEl.uslCurrent()) settings['direction'] = 'f';

                    else settings['direction'] = 'b';

                    thisEl.uslRefresh(c);

                }

                return false;

            });

        }



        if (settings['pager']){

            setNavigator(settings['pager']);

        }

        if (settings['navigator2']){

            setNavigator(settings['navigator2']);

        }



        function loadingStatus(loading) {

            if (loading) {

                thisObj.addClass('usl-loading');

            }

            else {

                thisObj.removeClass('usl-loading');

            }

        }



        thisEl.uslStatusbar = function() {



            if (settings['lazyload']) {

                var $imgToLoad = $('>li:eq('+settings['current']+') img', thisEl);

            }

            else {

                var $imgToLoad = $('img', thisEl);

            }



            settings['img_count'] = $imgToLoad.length;

            if (settings['img_count']) {

                loadingStatus(true);

            }



            settings['img_loaded'] = 0;

            $imgToLoad.each(function(){

                if (this.complete) {

                    settings['img_loaded'] ++;

                }

                else {

                    $(this).load(function(){

                        settings['img_loaded'] ++;

                        //alert(settings['img_loaded'] + ' of ' + settings['img_count']);

                        if (settings['img_loaded'] == settings['img_count']){

                            loadingStatus(false);

                            thisEl.ready = true;

                            thisEl.uslRefresh();

                        }

                    });

                }

            });



            if (settings['img_loaded'] == settings['img_count']){

                loadingStatus(false);

                thisEl.ready = true;

                thisEl.uslRefresh();

            }

        };



        // statusbar

        if (settings['statusbar'] && !settings['ajax']){

            thisEl.uslStatusbar();

        }



        /*

         * If the mousewheel plugin has been included on the page then

         * the slider will also respond to the mouse wheel.

         */

        if (settings['mousewheel']) {

            thisObj.bind(

                'mousewheel',

                function (event, delta) {

                    if (thisEl.ready) {

                        if (delta < 0) {

                            next();

                        }

                        else {

                            prev();

                        }

                    }

                    return false;

                });

        }



        if (! settings['statusbar'] || settings['ajax']) {

            thisEl.ready = true;

            thisEl.uslRefresh();

        }

    };

})(jQuery);
