/*******************************************************************************
 jquery.mb.components
 Copyright (c) 2001-2010. Matteo Bicocchi (Pupunzi); Open lab srl, Firenze - Italy
 email: mbicocchi@open-lab.com
 site: http://pupunzi.com

 Licences: MIT, GPL
 http://www.opensource.org/licenses/mit-license.php
 http://www.gnu.org/licenses/gpl.html
 ******************************************************************************/

/*
 * Name:jquery.mb.bgndGallery
 * Version: 1.0
 *
 */

(function($){

    $.mbBgndGallery ={
        name:"mb.bgndGallery",
        author:"Matteo Bicocchi",
        version:"1.0",
        defaults:{
            containment:"body",
            images:[],
            controls:null,
            effect:{enter:{left:0,opacity:0},exit:{left:0,opacity:0}, enterTiming:"ease-in", exitTiming:"ease-in"},
            timer:4000,
            raster:false, //"inc/raster.png"
            effTimer:3000,
            folderPath:false,
            autoStart:true,
            grayScale:false,
            activateKeyboard:true,
            preserveTop:false,
            onStart:function(){},
            onChange:function(idx){}, //idx=the zero based index of the displayed photo
            onPause:function(){},
            onPlay:function(opt){},
            onNext:function(opt){},
            onPrev:function(opt){}
        },
        clear:false,

        buildGallery:function(options){
            var opt = {};
            $.extend(opt, $.mbBgndGallery.defaults,options);
            opt.galleryID= new Date().getTime();
            var el= $(opt.containment).get(0);
            el.opt= opt;

            if(el.opt.onStart)
                el.opt.onStart();

            opt.gallery= $("<div/>").attr({id:"bgndGallery_"+el.opt.galleryID}).addClass("mbBgndGallery");
            var pos= opt.containment=="body"?"fixed":"absolute";
            opt.gallery.css({position:pos,top:0,let:0,width:"100%",height:"100%",overflow:"hidden"});

            var containment = el.opt.containment;

            if(containment !="body"){
                var wrapper=$("<div/>").css({"position":"absolute",minHeight:"100%", minWidth:"100%", zIndex:3});
                $(containment).wrapInner(wrapper);
                if($(containment).css("position")=="static")
                    $(containment).css("position","relative");
            }

            if(opt.raster){
                var raster=$("<div/>").css({position:"absolute",top:0,left:0,width:"100%",height:"100%",background:"url("+opt.raster+")",zIndex:1});
                opt.gallery.append(raster);
            }

            $(containment).prepend(opt.gallery);

            if(el.opt.folderPath && el.opt.images.length==0)
                opt.images=jQuery.loadFromSystem(el.opt.folderPath);

            var images= opt.images;

            var totImg= images.length;

            var loadCounter=0;

            $.mbBgndGallery.preload(images[0],el);
            $(opt.gallery).bind("imageLoaded_"+opt.galleryID,function(){
                loadCounter++;
                if(loadCounter==totImg){
                    $(opt.gallery).unbind("imageLoaded_"+opt.galleryID);
                    return;
                }
                $.mbBgndGallery.preload(images[loadCounter],el);
            });

            opt.imageCounter=0;

            $.mbBgndGallery.changePhoto(images[opt.imageCounter],el);

            if (!opt.autoStart){
                opt.paused=true;
                $(opt.gallery).trigger("paused");
            }

            var counter=$(opt.controls).find(".counter");
            counter.html(opt.imageCounter+1+" / "+opt.images.length);

            $(opt.gallery).bind("imageReady_"+opt.galleryID,function(){
                if(opt.paused)
                    return;
                $.mbBgndGallery.play(el);
            });

            $(window).bind("resize",function(){
                var image=$("#bgndGallery_"+el.opt.galleryID+" img");
                $.mbBgndGallery.checkSize(image,el);
            });

            var controls = el.opt.controls;
            if(controls){
                $.mbBgndGallery.buildControls(controls,el);
            }

            $(opt.containment).bind("paused",function(){
                $(opt.controls).find(".play").show();
                $(opt.controls).find(".pause").hide();
            });
            $(opt.containment).bind("play",function(){
                $(opt.controls).find(".play").hide();
                $(opt.controls).find(".pause").show();
            });

        },

        preload:function(url,el){
            if($.mbBgndGallery.clear){
                $(el.opt.gallery).remove();
                return;
            }

            var img= $("<img/>").load(function(){
                $(el.opt.gallery).trigger("imageLoaded_"+el.opt.galleryID);
            }).attr("src",url);
        },

        checkSize:function(image,el){
            if($.mbBgndGallery.clear){
                $(el.opt.gallery).remove();
                return;
            }

            var w= image.attr("w");
            var h= image.attr("h");
            var containment = el.opt.containment == "body"? window : el.opt.containment;
            var aspectRatio= w/h;
            var wAspectRatio=$(containment).width()/$(containment).height();
            if(aspectRatio>=wAspectRatio){
                image.css("height","100%");
                image.css("width","");
            } else{
                image.css("width","100%");
                image.css("height","");
            }
            image.css("margin-left",(($(containment).width()-image.width())/2));

            if(!el.opt.preserveTop)
                image.css("margin-top",(($(containment).height()-image.height())/2));
        },

        changePhoto:function(url,el){
            if($.mbBgndGallery.clear){
                $(el.opt.gallery).remove();
                return;
            }

            if(el.opt.onChange)
                el.opt.onChange(el.opt.imageCounter);

            var image=$("<img/>").hide().load(function(){
                var image=$(this);

                var tmp=$("<div/>").css({position:"absolute",top:-5000});
                tmp.append(image);
                $("body").append(tmp);
                image.attr("w", image.width());
                image.attr("h", image.height());
                tmp.remove();

                $("#bgndGallery_"+el.opt.galleryID+" img").galleryAnimate(el.opt.effect.exit,el.opt.effTimer,el.opt.effect.exitTiming,function(){$("#bgndGallery_"+el.opt.galleryID+" img:first").remove()});
                image.css({position:"absolute", width:"100%"});
                $("#bgndGallery_"+el.opt.galleryID).append(image);

                $.mbBgndGallery.checkSize(image, el);

                image.css(el.opt.effect.enter).show().galleryAnimate({top:0,left:0,opacity:1},el.opt.effTimer,el.opt.effect.enterTiming,function(){
                    $(el.opt.gallery).trigger("imageReady_"+el.opt.galleryID);
                });
            }).attr("src",url);

            if(el.opt.grayScale){
                image.greyScale();

            }

            var counter=$(el.opt.controls).find(".counter");
            counter.html(el.opt.imageCounter+1+" / "+el.opt.images.length);

        },

        play:function(el){
            if($.mbBgndGallery.clear){
                $(el.opt.gallery).remove();
                return;
            }

            if(el.opt.onPlay)
                el.opt.onPlay(el.opt);

            el.opt.changing=setTimeout(function(){
                if(el.opt.paused)
                    return;
                if (el.opt.imageCounter>=el.opt.images.length-1)
                    el.opt.imageCounter=-1;

                el.opt.imageCounter++;

                $.mbBgndGallery.changePhoto(el.opt.images[el.opt.imageCounter],$(el.opt.containment).get(0));
            },el.opt.paused?0:el.opt.timer);

            $(el.opt.gallery).trigger("play");

        },

        pause:function(el){
            if($.mbBgndGallery.clear){
                $(el.opt.gallery).remove();
                return;
            }

            clearTimeout(el.opt.changing);
            el.opt.paused=true;
            $(el.opt.gallery).trigger("paused");

            if(el.opt.onPause)
                el.opt.onPause();
        },

        next:function(el){
            if($.mbBgndGallery.clear){
                $(el.opt.gallery).remove();
                return;
            }

            if(el.opt.onNext)
                el.opt.onNext(el.opt);
            $.mbBgndGallery.pause(el);
            clearTimeout(el.opt.changing);
            if (el.opt.imageCounter==el.opt.images.length-1)
                el.opt.imageCounter=-1;

            el.opt.imageCounter++;

            $.mbBgndGallery.changePhoto(el.opt.images[el.opt.imageCounter],el);
        },

        prev:function(el){
            if($.mbBgndGallery.clear){
                $(el.opt.gallery).remove();
                return;
            }

            if(el.opt.onPrev)
                el.opt.onPrev(el.opt);

            $.mbBgndGallery.pause(el);
            clearTimeout(el.opt.changing);
            if (el.opt.imageCounter==0)
                el.opt.imageCounter=el.opt.images.length;

            el.opt.imageCounter--;

            $.mbBgndGallery.changePhoto(el.opt.images[el.opt.imageCounter],el);
            el.opt.paused=true;
            $(el.opt.gallery).trigger("paused");

        },

        loader:{
            show:function(){},
            hide:function(){}
        },

        keyboard:function(el){
            $(document).bind("keydown.bgndGallery",function(e){
                switch(e.keyCode){
                    case 32:
                        if(el.opt.paused){
                            $.mbBgndGallery.play(el);
                            el.opt.paused=false;
                        }else{
                            el.opt.paused=true;
                            $.mbBgndGallery.pause(el);
                        }
                        break;
                    case 39:
                        $.mbBgndGallery.next(el);

                        break;
                    case 37:
                        $.mbBgndGallery.prev(el);

                        break;
                }
            })
        },

        buildControls:function(controls,el){
            var pause=$(controls).find(".pause");
            var play=$(controls).find(".play");
            var next=$(controls).find(".next");
            var prev=$(controls).find(".prev");
            if(el.opt.autoStart)
                play.hide();

            pause.bind("click",function(){
                $.mbBgndGallery.pause(el);
                $(this).hide();
                play.show();
            });

            play.bind("click",function(){
                if(!el.opt.paused) return;
                clearTimeout(el.opt.changing);
                $.mbBgndGallery.play(el);
                el.opt.paused=false;
            });

            next.bind("click",function(){
                $.mbBgndGallery.next(el);
                pause.hide();
                play.show();

            });

            prev.bind("click",function(){
                $.mbBgndGallery.prev(el);
                pause.hide();
                play.show();
            });

            if(el.opt.activateKeyboard)
                $.mbBgndGallery.keyboard(el);
        },

        changeGallery:function(el,array){

            $(el.gallery).fadeOut();

            $.mbBgndGallery.pause(el);

            el.opt.images=array;
            var images= el.opt.images;
            var totImg= images.length;
            var loadCounter=0;

            $.mbBgndGallery.preload(images[0],el);
            $(el.opt.gallery).bind("imageLoaded_"+el.opt.galleryID,function(){
                loadCounter++;
                if(loadCounter==totImg){
                    $(el.opt.gallery).unbind("imageLoaded_"+el.opt.galleryID);
                    $(el.gallery).fadeIn();
                    $.mbBgndGallery.play(el);
                    el.opt.paused=false;
                    return;
                }
                $.mbBgndGallery.preload(images[loadCounter],el);
            });
            el.opt.imageCounter=0;
            //$.mbBgndGallery.changePhoto(images[el.opt.imageCounter],el);

        }
    };

    $.fn.galleryAnimate=function(opt,duration, type, callback){
        if(!opt) return;
        if(typeof duration=="function"){
            callback=duration;
            duration=1000;
        }
        if(typeof type=="function"){
            callback=type;
            type="linear"; //   ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(<number>, <number>, <number>, <number>)
        }

        var el=this;

        if($.browser.msie){   //&& $.browser.version.indexOf("9")==-1
            el.animate(opt,duration,callback);
            return;
        }

        var sfx="";
        var transitionEnd = "TransitionEnd";
        if ($.browser.webkit) {
            sfx="-webkit-";
            transitionEnd = "webkitTransitionEnd";
        } else if ($.browser.mozilla) {
            sfx="-moz-";
            transitionEnd = "transitionend";
        } else if ($.browser.opera) {
            sfx="-0-";
            transitionEnd = "oTransitionEnd";
        }

        el.css(sfx+"transition-property","opacity, left, top, width, height");
        el.css(sfx+"transition-duration",duration+"ms");
        el.css(sfx+"transition-timing-function",type);
        el.css(opt).bind(transitionEnd,function(){
            callback();
            $(this).unbind(transitionEnd);
            el.css(sfx+"transition","");
        });
    };

    jQuery.loadFromSystem=function(folderPath, type){

        // if directory listing is enabled on the remote server.
        // if you run the page locally you need to run it under a local web server (Ex: http://localhost/yourPage)
        // otherwise the directory listing is unavailable.

        if(!folderPath)
            return;
        if(!type)
            type="jpg" || "jpeg";
        var arr=[];
        $.ajax({
            url:folderPath,
            async:false,
            success:function(response){
                var tmp=$(response);
                var els= tmp.find("[href*='."+type+"']");
                els.each(function(){
                    arr.push(folderPath+$(this).attr("href"));
                });
                tmp.remove();
            }
        });
        return arr;
    };

    $.fn.greyScale = function() {
        return this.each(function() {
            if ($.browser.msie && $.browser.version<9) {
                this.style.filter = "progid:DXImageTransform.Microsoft.BasicImage(grayScale=1)";
            } else {
                this.src = grayScaleImage(this);
            }
        })
    };

    function grayScaleImage(imgObj){
        var canvas = document.createElement('canvas');
        var canvasContext = canvas.getContext('2d');

        var imgW = imgObj.width;
        var imgH = imgObj.height;
        canvas.width = imgW;
        canvas.height = imgH;

        canvasContext.drawImage(imgObj, 0, 0);
        var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);

        for(var y = 0; y < imgPixels.height; y++){
            for(var x = 0; x < imgPixels.width; x++){
                var i = (y * 4) * imgPixels.width + x * 4;
                var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
                imgPixels.data[i] = avg;
                imgPixels.data[i + 1] = avg;
                imgPixels.data[i + 2] = avg;
            }
        }
        canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
        return canvas.toDataURL();
    }

})(jQuery);
