/*!
 * gridSlider Library v0.1
 * http://codecanyon.net/user/Alexandra1710/portfolio
 *
 * Copyright 2011, Andrei Dinca
 *
 * Date: 14.02.2011
 */

(function ($) {
    $.fn.gridSlider = function (options) {
        var defaults = {
            content: ".sliderContent", // container where sliding contents
            children: "li", // children items (default: li)
            transition: "grid", // transition effect (defaut: grid)
            zoomSize: 0, // for grid, zoom size in px (default: 10)
            animationSpeed: 300, // transition speed
            easing: '', // easing of animation (default. '' - no easing)
            autoplay: false, // autoplay easing
            autoplaySpeed: 3000, // autoplay interval speed
            pauseOnHover: false, // if autoplay on mouse over make pause (true|false - default false)
            thumbs: {
                show: true,
                nbPerRow: 3,
                width: 50,
                height: 50,
                phpProcessor : ''
            }, // show thumbs (default: true)
            arrows: true, // show arrows (default: true)
            arrowsHide: true, // hide arrow on mouse out (default: true)
            keyBrowse: true, // allow key browsing (default: true)
            mouseWheel: true, // allow mouse wheel browsing (default: true)
            preloadImages: true, // allow preload images browsing (default: true)
            itemSize: {
                width: 720, // item width in px
                height: 300 // item width in px
            },
            prev: "prev", // prev btn item
            next: "next", // next btn item
            item_position: [], // autoindent
            running: false, // static usage
			uri: '',
            animationStart: function () {},
            animationComplete: function () {}
        };
        var option = $.extend({}, defaults, options);
        return this.each(function () {
            var $t = $(this),
            item = $t.find(option.content).find(option.children),
            item_img = item.find('img'),
            maskImage = $t.find('.gs-main-images-mask'),
            sliderContent = $t.find(option.content),
            l = item.length - 1,
            w = item.width(),
            h = item.height(),
            allImage = [],
            step = 0,            
            play, front_item, moveLeft, next_item, sign, moveTop, thumbs, arrows, z, on, thumb, evt, thumbs_ul;
				
            var slider = {
                init: function () {
					
                    // slide init to 0 with 0
                    maskImage
                    .scrollLeft(0)
                    .scrollTop(0);
                    
                    // sliderContent
                    sliderContent.width(w * option.thumbs.nbPerRow);
					
                    if(option.preloadImages){
                        $(".prealoadImages").remove();
                        $t.append('<img src="' + option.uri + 'images/ajax-loader.gif" class="prealoadImages" />');
                        item_img.hide();
                        item_img.each(function(i){
                            allImage[i] =  $(this).attr('src');
                        });
                        
                        slider.preLoadImages(allImage, function(){
                            item_img.show();
                            $("img.prealoadImages").hide();
                            slider.load_slider();

                        });
                    }else{
                        slider.load_slider();
                    }
                },

                load_slider: function(){
                    slider.data();

                    if (option.thumbs.show === true) {
                        slider.thumbs.create();
                    }
                    if (option.arrows === true) {
                        slider.arrows.create();
                    }
                    if (option.autoplay === true) {
                        slider.autoplay();
                    }
                    slider.triggers();
                },
				
                data: function () {
                    item.each(function (i) {
                        var $this = $(this);
                        var position = $this.position();
						
                        option.item_position["item-" + i] = {
                            'left' : position.left,
                            'top' : position.top
                        };
                    });
                },

                preLoadImages: function(imageList, callback) {    
                    var pic = [], i, total, loaded = 0;
                    if (typeof imageList !== 'undefined') {
                        if ($.isArray(imageList)) {
                            total = imageList.length; // used later
                            for (i=0; i < total; i++) {
                                pic[i] = new Image();
                                pic[i].onload = function() {
                                    loaded++; // should never hit a race condition due to JS's non-threaded nature
                                    if (loaded === total) {
                                        if ($.isFunction(callback)) {
                                            callback();
                                        }
                                    }
                                }
                                pic[i].src = imageList[i];
                            }
                        }
                        else {
                            pic[0] = new Image();
                            pic[0].onload = function() {
                                if ($.isFunction(callback)) {
                                    callback();
                                }
                            };
                            pic[0].src = imageList;
                        }
                    }
                    pic = undefined;
                },
				
                slide: { 
                    grid: function () {
                        option.animationStart.call(this);

                        next_item  = item.eq(step);
						
                        // do animation
                        maskImage.animate({
                            scrollLeft : option.item_position['item-' + step].left,
                            scrollTop  : option.item_position['item-' + step].top
                        }, option.animationSpeed, option.easing, function(){
							
                            // release running
                            option.running = false;
							
                            if (option.thumbs.show === true) {
                                slider.thumbs.update();
                            }
							
                            option.animationComplete.call(this);
                        });    
                    }
                },
				
                animation: {
                    previous: function () {
                        if(step === 0){
                            step = l;
                        } else {
                            step--;
                        }
                        z = -1;
                        switch (option.transition) {
                            case "grid":
                                slider.slide.grid();
                                break;
                        }
                    },
                    next_item: function () {
                        if(step === l){
                            step = 0;
                        }else{
                            step++;
                        }
                        z = 1;
                        switch (option.transition) {
                            case "grid":
                                slider.slide.grid();
                                break;
                        }
                    }
                },
				
                keyBrowse: function () {	
                    $(document).keyup(function(e) {
                       
                        
                        if (e.keyCode === 37){
                            // exit if animations still running
                            if(option.running){
                                return false;
                            }

                            // set up true running script
                            option.running = true;

                            slider.animation.previous();
                        }
                        if (e.keyCode === 39){
                            // exit if animations still running
                            if(option.running){
                                return false;
                            }

                            // set up true running script
                            option.running = true;

                            slider.animation.next_item();
                        }
                        return false;
                    });
                },

                mouseWheel: function () {
                    $t.mousewheel(function(event, delta) {
                       
                        // exit if animations still running
                        if(option.running){
                            return false;
                        }

                        // set up true running script
                        option.running = true;

                        var dir = delta > 0 ? 'up' : 'down',
                        vel = Math.abs(delta);
                        if(dir === 'down'){
                            slider.animation.next_item();
                        }else{
                            slider.animation.previous();
                        }
                        return false;
                    });
                },
				
                autoplay: function () {
                    if (option.autoplay === true) {
                        play = setInterval(function () {
                            slider.animation.next_item();
                            if (option.thumbs === true) {
                                setTimeout(function () {
                                    slider.thumbs.update();
                                }, option.animationSpeed + 200);
                            }
                        }, option.autoplaySpeed);
                    }
                },
				
                pause: function () {
                    clearInterval(play);
                },
				
                thumbs: {
                    create: function () {
                        $(".gs-thumbs").remove();
                        $t.append($("<div />").addClass("gs-thumbs"));
						
                        var thumbsTotalWidth = (option.thumbs.width + 8 + 2 + 5) * option.thumbs.nbPerRow; // where 8 = total margin or image in block, 2 = image border & 5 = margin between li blocks
                        thumbs = $t.find(".gs-thumbs");
                        thumbs.width(thumbsTotalWidth);
                        thumbs.append($("<ul />"));
                        thumbs_ul = $t.find(".gs-thumbs").find('ul');
                        for (i = 0; i <= l; i++) {
							var n_img_src = item_img.eq(i).attr('src').split("?src=");
							if(n_img_src[1] != ""){
								n_img_src = n_img_src[1];
							}
                            thumbs_ul.append($("<li style='width: " + (option.thumbs.width + 8) + "px; height: " + (option.thumbs.height + 8) + "px;'><a href='#' rel='" + i + "'><img src='" + option.thumbs.phpProcessor + "?src=" + n_img_src + "&w=" + option.thumbs.width + "&h=" + option.thumbs.width + "&zc=1' style='margin-left: -" + ((option.thumbs.width + 2) / 2) + "px;margin-top: -" + ((option.thumbs.height + 2) / 2) + "px;' /></a></li>"));
                        }
                    },
                    
                    trigger: function () {
                        thumb = thumbs.find("a");
                        thumb.eq(0).addClass("on");
						
                        thumb.click(function () {
                            
                            var b = $(this),
                            rel = b.attr("rel");
                            on = thumb.filter(".on").attr("rel");
                            step = rel;
                            sign = rel > on ? "+" : "-";
                            z = 0;
                            if (!b.hasClass("on")) {
                                switch (option.transition) {
                                    case "grid":

                                        // exit if animations still running
                                        if(option.running){
                                            return false;
                                        }

                                        // set up true running script
                                        option.running = true;

                                        slider.slide.grid();

                                        thumb.removeClass("on");
                                        b.addClass("on");
                                        return false;
                                        
                                        break;
                                }
                            }                            
                        });
                    },
                    
                    update: function () {
                        thumb.removeClass("on").eq(step).addClass("on");
                    }
                },
				
                arrows: {
                    create: function () {
                        $(".nextBackControllers").remove();
                        $t.append($("<div />").addClass("nextBackControllers"));
                        arrows = $t.find(".nextBackControllers");
                        arrows.append($("<a />").attr("href", "#").addClass(option.prev).text("Previous"));
                        arrows.append($("<a />").attr("href", "#").addClass(option.next).text("Next"));
                    },
                    
                    trigger: function () {
                        arrows.find("." + option.prev).click(function () {
                            // exit if animations still running
                            if(option.running){
                                return false;
                            }

                            // set up true running script
                            option.running = true;
                        
                            slider.animation.previous();
                            if (option.thumbs === true) {
                                slider.thumbs.update();
                            }
                            return false;
                        });
                        arrows.find("." + option.next).click(function () {
                            // exit if animations still running
                            if(option.running){
                                return false;
                            }

                            // set up true running script
                            option.running = true;
                            
                            slider.animation.next_item();
                            if (option.thumbs === true) {
                                slider.thumbs.update();
                            }
                            return false;
                        });
                        if (option.arrowsHide === true) {
                            arrows.find('a').hide();
                            $t.hover(function () {
                                $t.mousemove(function(e) {
                                    var offset = $(this).offset();
                                    var x = e.pageX - (offset.left);
									
                                    if(x < w / 2){
                                        // left side (prev)
                                        arrows.find("." + option.next).hide();
                                        arrows.find("." + option.prev).fadeIn(150);
                                    }else{
                                        // right side (next)
                                        arrows.find("." + option.prev).hide();
                                        arrows.find("." + option.next).fadeIn(150);
                                    }
                                });
                            }, function () {
                                arrows.find('a').hide();
                            });
                        }
                    }
                },
				
                triggers: function () {
                    if (option.arrows === true) {
                        slider.arrows.trigger();
                    }
                    if (option.thumbs.show === true) {
                        slider.thumbs.trigger();
                    }
                    if (option.mouseWheel === true) {
                        slider.mouseWheel();
                    }
                    if (option.keyBrowse === true) {
                        slider.keyBrowse();
                    }
                    if (option.pauseOnHover === true) {
                        $t.hover(function () {
                            slider.pause();
                        }, function () {
                            slider.autoplay();
                        });
                    }
                }
            };
			
            slider.init();
        });
    };
}(jQuery));


/*! Copyright (c) 2009 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * Version: 3.0.2
 *
 * Requires: 1.2.2+
 */
(function($) {

    var types = ['DOMMouseScroll', 'mousewheel'];

    $.event.special.mousewheel = {
        setup: function() {
            var i;
            if ( this.addEventListener ){
                for ( i=types.length; i; ){
                    this.addEventListener( types[--i], handler, false );
                }
            }else{
                this.onmousewheel = handler;
            }
        },

        teardown: function() {
            var i;
            if ( this.removeEventListener ){
                for (i=types.length; i; ) {
                    this.removeEventListener( types[--i], handler, false );
                }
            }else{
                this.onmousewheel = null;
            }
        }
    };

    $.fn.extend({
        mousewheel: function(fn) {
            return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
        },

        unmousewheel: function(fn) {
            return this.unbind("mousewheel", fn);
        }
    });


    function handler(event) {
        var args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true;

        event = $.event.fix(event || window.event);
        event.type = "mousewheel";

        if ( event.wheelDelta ) {
            delta = event.wheelDelta/120;
        }
        if ( event.detail     ) {
            delta = -event.detail/3;
        }

        // Add events and delta to the front of the arguments
        args.unshift(event, delta);

        return $.event.handle.apply(this, args);
    }

}(jQuery));
