/**
 * Overlay Gallery plugin, version: 1.0.0
 * 
 * Copyright (c) 2009 Tero Piirainen
 * http://flowplayer.org/tools/overlay.html#gallery
 *
 * Dual licensed under MIT and GPL 2+ licenses
 * http://www.opensource.org/licenses
 *
 * Since  : July 2009
 * Date: ${date}
 * Revision: ${revision} 
 */
(function($) { 
        
    // TODO: next(), prev(), getIndex(), onChange event
    
    // version number
    var t = $.tools.overlay; 
    t.plugins = t.plugins || {};
    
    t.plugins.gallery = {
        version: '1.0.0', 
        conf: { 
            imgId: 'img',
            next: '.next',
            prev: '.prev',
            info: '.info',
            progress: '.progress',
            disabledClass: 'disabled',
            activeClass: 'active',
            opacity: 0.8,
            speed: 'slow',
            template: '<strong>${title}</strong> <span>Image ${index} of ${total}</span>',  
            autohide: true,
            preload: true,
            marginHeight: 50,
            marginWidth: 50,
            api: false
        }
    };          
    
    $.fn.gallery = function(opts) {
        
        var conf = $.extend({}, t.plugins.gallery.conf), api;
        $.extend(conf, opts);       

        // common variables for all gallery images
        api = this.overlay();
        
        var links = this,
             overlay = api.getOverlay(),
             next = overlay.find(conf.next),
             prev = overlay.find(conf.prev),
             info = overlay.find(conf.info),
             progress = overlay.find(conf.progress),
             els = prev.add(next).add(info).css({opacity: conf.opacity}),
             close = api.getClosers(),           
             index;
        
        
//{{{ load 

        function load(el) {
            
            progress.fadeIn();
            els.hide(); close.hide();
            
            var url = el.attr("href"); 
            
            // download the image 
            var image = new Image();
            
            image.onload = function() {
                
                progress.fadeOut();
                
                // find image inside overlay
                var img = $("#" + conf.imgId, overlay); 
                
                w = $(window);

                // or append it to the overlay 
                if (!img.length) { 
                    img = $("<img/>").attr("id", conf.imgId).css({"visibility":"hidden", "max-width":w.width()-conf.marginWidth, "max-height":w.height()-conf.marginHeight});
                    overlay.prepend(img);
                }
                
                // make initially invisible to get it's dimensions
                img.attr("src", url).css("visibility", "hidden");           
                    
                // animate overlay to fit the image dimensions
                var width = img.width();
                var left = Math.max((w.width() - width) / 2, conf.marginHeight/2);
                    
                // animate overlay to fit the image dimensions
                var height = img.height();
                var top = Math.max((w.height() - height) / 2, conf.marginHeight/2);

                if (!api.getConf().absolute)  {
                    top += w.scrollTop();
                    left += w.scrollLeft();
                }
                    
                // calculate index number
                index = links.index(links.filter("[href=" +url+ "]"));  
                
                // activate trigger
                links.removeClass(conf.activeClass).eq(index).addClass(conf.activeClass);
                
                // enable/disable next/prev links
                var cls = conf.disabledClass;
                els.removeClass(cls);

                if (index === 0) { prev.addClass(cls); }
                if (index == links.length -1) { next.addClass(cls); }
                
                
                // set info text & width
                var text = conf.template
                    .replace("${title}", el.attr("title") || el.data("title"))
                    .replace("${index}", index + 1)
                    .replace("${total}", links.length);
                    
                var padd = parseInt(info.css("paddingLeft"), 10) +  parseInt(info.css("paddingRight"), 10);
                info.html(text).css({width: width - padd});             
                
                overlay.animate({width: width, height: height, left: left, top: top}, conf.speed, function() {
                        
                    // gradually show the image
                    img.hide().css("visibility", "visible").fadeIn(function() {                     
                        if (!conf.autohide) { 
                            els.fadeIn(); close.show(); 
                        }                                                       
                    });                             

                }); 
            };
            
            image.onerror = function() {
                overlay.fadeIn().html("Cannot find image " + url); 
            };
            
            image.src = url;
            
            if (conf.preload) {
                links.filter(":eq(" +(index-1)+ "), :eq(" +(index+1)+ ")").each(function()  {
                    var img = new Image();
                    img.src = $(this).attr("href");                 
                });
            }
            
        }
        
//}}}


        // function to add click handlers to next/prev links     
        function addClick(el, isNext)  {
            
            el.click(function() {
                    
                if (el.hasClass(conf.disabledClass)) { return; }                
                
                // find the triggering link
                var trigger = links.eq(i = index + (isNext ? 1 : -1));          
                     
                // if found load it's href
                if (trigger.length) { load(trigger); }
                
            });             
        }

        // assign next/prev click handlers
        addClick(next, true);
        addClick(prev);

        
        // arrow keys
        $(document).keydown(function(evt) {
                
            if (!overlay.is(":visible") || evt.altKey || evt.ctrlKey) { return; }
            
            if (evt.keyCode == 37 || evt.keyCode == 39) {                   
                var btn = evt.keyCode == 37 ? prev : next;
                btn.click();
                return evt.preventDefault();
            }   
            return true;            
        });     
        
        function showEls() {
            if (!overlay.is(":animated")) {
                els.show(); close.show();       
            }   
        }
        
        // autohide functionality
        if (conf.autohide) { 
            overlay.hover(showEls, function() { els.fadeOut();  close.hide(); }).mousemove(showEls);
        }       
        
        // load a proper gallery image when overlay trigger is clicked
        var ret;
        
        this.each(function() {
                
            var el = $(this), api = $(this).overlay(), ret = api;
            
            api.onBeforeLoad(function() {
                load(el);
            });
            
            api.onClose(function() {
                links.removeClass(conf.activeClass);    
            });         
        });         
        
        return conf.api ? ret : this;
        
    };
    
})(jQuery); 
        
