/*
 * 
 * jbgallery 1.0
 * @requires jQuery v1.3.2
 * 
 * Copyright (c) 2009 Massimiliano Balestrieri
 * Examples and docs at: http://maxb.net/blog/
 * Licensed GPL licenses:
 * http://www.gnu.org/licenses/gpl.html
 *
 * Inspired by http://www.ringvemedia.com/introduction
 */

//jQuery.noConflict();

;(function($){


jBGallery = {};

jBGallery.Init = function(options, data){
	if(typeof options == "string"){
		if(jBGallery.Api.enabled(this) || options === 'enable' || options === 'destroy')
			return jBGallery.Api[options](this, data);
	}else{
		return this.each(function(nr){
			new jBGallery.Core(this, options, nr);
		});
	}
};

jBGallery.Api = {
	enabled : function(el){
		return $(el).data("enabled");
	},
	current : function(el){
		return $(el).data("current");
	},
	go : function(el, nr){
		return $(el).trigger("go", [nr]);
	},
	left : function(el){
		return $(el).trigger("left");
	},
	right : function(el){
		return $(el).trigger("right");
	},
	play : function(el, interval){
		return $(el).trigger("play", [interval]);
	},
	stop : function(el){
		return $(el).trigger("stop");
	},
	disable : function(el){
		return $(el).trigger("disable");
	},
	enable : function(el){
		return $(el).trigger("enable");
	},
	destroy : function(el){
		return $(el).trigger("destroy");
	}
}; 



jBGallery.Core = function(el, options, nr){
	var _metadata = {};
	if($.metadata)
		_metadata = $(el).metadata();
	
	var _options = $.extend({
        style       : "zoom",//centered, zoom
		slideshow   : false,
		interval    : 7000,
		fade_time	: 2400,
		fade		: true,
		menu 	    : 'false', //false, numbers, simple
        shortcuts   : [37,39],
		after       : function(ev){},
		before	    : function(){},
        load        : function(ev){},
        close		: function(){},
        popup       : false,
        labels      : {},
        log         : function(){}//_log//
	},_metadata,options);

	if(!_options.fade)
		_options.fade_time = 0;

    var that = el;
    var _id = nr;

    $("html, body").addClass("jbg");
    $("#jbgallery-css").removeAttr("disabled");
    
    
    //nascondo l'ul - x ie
    $(that).find("ul").hide();
    
	var _imgs = $.map($(that).find("ul > li > a"), function(a, i){
		//fix numbers
        if(_options.menu == "numbers")
            $(a).text((i+1));
            
        return {href : a.href, title: a.title};
	});
    
	var _current_url = _imgs[0].href;//(_current - 1)//$(that).find("a").eq(0).attr("href");
    var _current_title = _imgs[0].title;//(_current - 1)//$(that).find("a").eq(0).attr("href");

	$(that).prepend('<div id="jbg"><table cellpadding="0" cellspacing="0"><tr><td><img class="'+_options.style+'" id="jbgallery_target" alt="'+_current_title+'" src="'+_current_url+'" /></td></tr></table></div>');
	
    var _target = $("#jbgallery_target", that);
    
    //centered
    if(_options.style == "centered"){
        $("#jbg").css({"top":"auto", height : "100%"});
        $("#jbg").height("100%");
    }
    
    jBGallery.OnLoadImage(that, _options, _target);
    
    if(_imgs.length > 1)
        new jBGallery.Engine(that, _options, _target,_id, _imgs);
    
    
    function _log(arg){
        if(window.console)
            console.log(arg);
        else
            alert(arg);
    }
    
};

//NEW
jBGallery.slideshow = false;
jBGallery.interval = false;
jBGallery.timeout = false;

jBGallery.OnLoadImage = function(that, _options, _target){
    
    var _is_webkit = navigator.userAgent.toLowerCase().search(/webkit/) != -1;
    var _is_ie6 = /MSIE 6/i.test(navigator.userAgent);//navigator.userAgent.toLowerCase().search(/msie/) != -1;
	
	_target.bind("load",function(ev){
        _options.log("jBGallery.OnLoadImage : load");
        _onload(ev);
        _options.load(ev);
        _options.after(ev);
		
		//TEST
		if(jBGallery.slideshow){
			clearTimeout(jBGallery.timeout);
			jBGallery.timeout = setTimeout(function(){
				$(that).trigger("right", [jBGallery.interval]);
			}, jBGallery.interval);
		}
    });
    
    if(_is_webkit || _is_ie6 || _options.style == "centered"){
        jBGallery.Fix(that, _options, _target, _is_ie6, _options.style == "centered");
    }
    
    function _onload(ev){
        _options.log("ev: _onload");
        $("#jbg-loading").hide();
        _appear(ev);
    }
    
    function _appear(ev){      
    	_options.log("ev: _appear");
        _target.fadeIn(_options.fade_time);
    }
    
    
};


jBGallery.Fix = function(that, _options, _target, _is_ie6, _centered){
    //alert("fix?");
    var _resize_timer = null;
    var _el = _target.get(0);
    
    $(window).bind('resize', function(ev) {
        if (_resize_timer) clearTimeout(_resize_timer);
        _resize_timer = setTimeout(function(){
            _options.log("resize: _fix_dimensions");
                _fix(ev);
        }, 100);
    });
    
    _target.bind('load',function(ev){
        _fix(ev);
    });
    
    
    function _fix(ev){
        if(_centered)
            _fix_bigimage(ev);
        else if(_is_ie6){
            _target.height("auto").width("auto");
            setTimeout(_fix_dimensions,10);
        }else{
            _fix_dimensions(ev);
        }
    }
    
    function _fix_bigimage(ev){
        _options.log("jBGallery.Fix: load/fix_bigimage");
        $(_target).width("auto").height("auto");
        var _dim = _get_dimensions();
        if(_dim.h > _dim.bh || _dim.w > _dim.bw){
            if(_dim.p <=  1){//immagine alta -> larghezza
                $(_target).width(_dim.bw);                        
            }else if(_dim.p > 1){//immagine larga -> altezza
                $(_target).height(_dim.bh);    
            }      
        }
    }
    
    function _fix_dimensions(ev){
        _options.log("jBGallery.Fix: load/fix_dimensions");
		//TODO
        if($("#jbgallery-css").size() == 0){
            alert("load css");
            return;
        }
        var _dim = _get_dimensions();
        if(_is_ie6){        
            if(_dim.h < _dim.bh || _dim.w < _dim.bw){
                if(_dim.p == 1){//immagine 1x1 -> monitor
                    if(_dim.pm > 1){
                        $(_target).width(_dim.bw);    
                    }else{
                        $(_target).height(_dim.bh);  
                    }
                }else if(_dim.p < 1){//immagine alta -> larghezza
                    $(_target).width("100%");                        
                }else if(_dim.p > 1){//immagine larga -> altezza
                    $(_target).height("100%");    
                }      
            }
        }else{//webkit
                if(_dim.h < _dim.bh)
                    $(_target).height(_dim.bh);
        }
        
    }
    
    
    function _get_dimensions(){
        var bw = $("body").width();
        var bh = $("body").height();
        var pm = bw / bh;
        var p = _el.width / _el.height;
        return {bw : bw, bh : bh, pm : pm, p : p, h : _el.height, w : _el.width};
    }
};

jBGallery.Engine = function(that, _options, _target, _id, _imgs){
    
    var _current = 1;//start 1 not 0
	var _enabled = true;
    
    //TODO: var _slideshow = false;
	jBGallery.interval = _options.interval;
		
    //public attr
	jBGallery.Data(that, "current", _current);
	jBGallery.Data(that, "enabled", true);
    
    //events
	$(that)
    .bind("play", _play)
	.bind("stop", _stop)
	.bind("right", _right)
	.bind("left", _left)
	.bind("go", _go)
	.bind("enable", _enable)
	.bind("disable", _disable)
	.bind("destroy", _destroy);
	
	
	_menu();
	_keys();
    _unload();
    _loading();
    
	if(_options.slideshow)
		_play();
    
    function _menu(){
		//console.log(_options.menu);
		if(_options.menu){
            new jBGallery.SimpleMenu(that, _options, _id);
		}else{
			$(that).find("ul").hide();//mmmh or remove
		}
	}
	
    function _keys(){
        new jBGallery.Keyboard(that, _options);
    }
    
    //by _go()
    function _load(nr){
        _preload();
        _current = jBGallery.Data(that, "current", nr);
        _target.fadeOut(_options.fade_time, function(){
        	$(this).hide().attr({"src" : _imgs[(_current - 1)].href, "alt" : _imgs[(_current - 1)].title});//.trigger("appear");	
        });

    }
    
    // ------------ EVENTS -------------------------
    
	var _timestamp = 0;
	var _timer_go = 1;

    function _play(ev, interval){
		_options.log("jBGallery.Engine: _play");
		
		if(jBGallery.slideshow)
            return;

		jBGallery.slideshow = true;
		
		if(interval)
			jBGallery.interval = interval;

		if(ev)
			$(that).trigger("right", [jBGallery.interval]);

		/*
		if(_slideshow)
            return;
        var _interval = interval || _options.interval;
        _slideshow = setInterval(function(){
            _right(ev, _interval);
        }, _interval);*/
	}
    
	function _stop(ev){
		_options.log("jBGallery.Engine: _stop");
		jBGallery.slideshow = false;
		clearTimeout(jBGallery.timeout);
		/*
		clearInterval(_slideshow);
		_slideshow = false;
        _options.log(_slideshow);*/
	}

    function _right(ev,_interval){
        _options.log("jBGallery.Engine: _right");
        if(_current < _imgs.length){
			var _goto = _current + 1;
		}else{
			var _goto = 1;
		}
		//console.log(_goto);
		$(that).trigger("go", [_goto, _interval]);
        
	}
    
	function _left(ev){
		_options.log("jBGallery.Engine: _left");
        if(_current > 1){
			var _goto = _current - 1;
		}else{
			var _goto = _imgs.length;
		}
		$(that).trigger("go", [_goto]);
	}
    
	function _go(ev, nr, _interval){
        /*if(_slideshow){
            _timer_go = _timestamp ? ev.timeStamp - _timestamp : _interval;
            _timestamp = ev.timeStamp;
            if(_interval && ((_interval - 100) > _timer_go)){
                _options.log("Skip go elapsed only : " + _timer_go + " Interval: " + _interval);
                return false;
            }
        }*/
		if(jBGallery.slideshow){
            _timer_go = _timestamp ? ev.timeStamp - _timestamp : _interval;//_interval;
            _timestamp = ev.timeStamp;
            if(_interval && ((_interval - 100) > _timer_go)){
                _options.log("Skip go elapsed only : " + _timer_go + " Interval: " + _interval);
				clearTimeout(jBGallery.timeout);
                jBGallery.timeout = setTimeout(_do, _interval);
            }else{
				_options.log("Elapsed : " + _timer_go + " Interval: " + _interval);
				_do();
			}
        }else{
			_do();
		}
        
		function _do(){
			_options.log("jBGallery.Engine: _go " + nr);
			_options.before();
			_load(nr);
		}
	}
    
    
	function _enable(ev){
		_options.log("jBGallery.Engine: _enable");
        _enabled = jBgSlide.Data(that, "enabled", true);
	}
    
	function _disable(ev){
		_options.log("jBGallery.Engine:_disable");
        _enabled = jBgSlide.Data(that, "enabled", false);
		if(_slideshow)
			_stop();
	}
    
	function _destroy(ev){

		jBGallery.slideshow = false;
		clearTimeout(jBGallery.timeout);

        _options.log("jBGallery.Engine:_destroy");
        
        $("#jbgallery-css").attr("disabled","disabled");//remove();
        $("#jbg-loading").remove();
        $("html, body").removeClass("jbg");
        
        _target.unbind();
        _target.remove();
        
        var _menu = $("body").find("ul#jbg-menu-" + _id);
        _menu.find("a").unbind();
        _menu.remove();
		
        $.removeData(that);
		$(that).unbind();
		$("#jbg",that).remove();
        
        $(document).unbind('keydown.jbgallery');
	}
    
    
    function _unload(){
        $(window).unload(function(){
            $(that).trigger("destroy");
        });
    }
    
    function _loading(){
        $(that).before('<div id="jbg-loading"><span class="jbg-loading"></span></div>');
    }
    
    function _preload(){
        $("#jbg-loading").show();
    }    

};


jBGallery.Keyboard = function(that, _options){

    $(document).bind("keydown.jbgallery", _onkey2);
	
	function _onkey2(e){
        _options.log("ev: _onkey");
		
		if (e == null) { // ie
            keycode = e.keyCode;
        } else { // mozilla
            keycode = e.which;
        }

        var _sc = _options.shortcuts;

        switch(keycode){
			case _sc[0]:
				$(that).trigger("left");
				return false;
			break;
			case _sc[1]:
               $(that).trigger("right");
			   return false;
			break;
            case 37:
            case 38:
            case 39:
            case 40:
                return false;
            break;
        }

    }
};

jBGallery.SimpleMenu = function(el, _options, _id){
    
    var that = el;
    
    var _target = $(that).find("ul").clone();
    
    _options.labels = $.extend({
        play : "play",
        next : "next",
        prev : "prev",
        stop : "stop",
        close: "close"
    }, _options.labels);
    
    if(_options.menu == 'numbers'){
    	_target.find("a:eq(0)").addClass("selected").addClass("visited");
        _target.click(_delegation);
    }

    if(_options.menu == 'simple'){
        //$(that)
        _target
        //.find("ul")
        .empty()
        .append(_menu_play())
        .append(_menu_stop());
    }
    
    _target
    .append(_menu_next())
    .prepend(_menu_prev())
    .addClass("jbg-menu")
    .attr("id", "jbg-menu-" + _id)
    .appendTo("body")//("#jbg-content")
    .show();
    
    
    if(_options.popup){
        _target
        .append(_menu_close());
    }
    
    if(_options.menu == 'numbers')
    	$("#jbgallery_target", that).bind("load", _update_classes);
    
    function _update_classes(ev){
        var _nr = $(that).jbgallery("current");
        _target.find("a.selected").removeClass("selected");
		_target.find("a:eq("+_nr+")").addClass("visited").addClass("selected");
    }

    function _menu_play(){
		var _el = $('<a href="#" class="jbg-play">'+_options.labels.play+'</a>').click(function(){
			$(that).trigger("play");
			return false;
		});
		return $("<li></li>").append(_el);
	}
	
	function _menu_stop(){
		var _el = $('<a href="#" class="jbg-stop">'+_options.labels.stop+'</a>').click(function(){
			$(that).trigger("stop");
			return false;
		});
		return $("<li></li>").append(_el);
	}
	
	function _menu_next(){
		var _el = $('<a href="#" class="jbg-next">'+_options.labels.next+'</a>').click(function(){
			$(that).trigger("right");
			return false;
		});
		return $("<li></li>").append(_el);
	}
	
	function _menu_prev(){
		var _el = $('<a href="#" class="jbg-prev">'+_options.labels.prev+'</a>').click(function(){
			$(that).trigger("left");
			return false;
		});
		return $("<li></li>").append(_el);
	}
    
    function _menu_close(){
		var _el = $('<a href="#" class="jbg-close">'+_options.labels.close+'</a>').click(function(){
			$(that).trigger("destroy");
			_options.close();
            return false;
		});
		return $("<li></li>").append(_el);
	}
	
	function _delegation(ev){
		var _el = ev.target || ev.srcElement;
		if(_el.tagName.toString().toLowerCase() === 'a'){
			var _num = parseInt($(_el).text());
			$(that).trigger("go",[_num]);
		}
		return false;
	}
	
};

jBGallery.Data = function(that, key, val){
    if(typeof val !== 'undefined'){
        $(that).data(key,val);
        return val;
    }else{
        return $(that).data(key);
    } 
};

jBGallery.Css = function(href){
	$(document.getElementsByTagName("head")[0]).append('<link rel="stylesheet" type="text/css" id="jbgallery-css" media="screen" href="'+href+'" />');
};

$.fn.jbgallery = jBGallery.Init;
$.fn.jbgcss = jBGallery.Css;

})(jQuery);