/**
 * OVERLAY v2!
**/
(function($) {
    $.fn.exists = function(){if(jQuery(this).length == 0){return false;}else{return true;}};
	$.overlay = function(content,settings) {
        var config;
        if (!settings) { settings = {}; }
		config = $.extend($.overlay.defaults, settings);
        var self = this;
		var $self = $('<div id="'+config.overlay_id+'" class="'+config.overlay_class+'"/>');
		var mask = $('<div id="overlayMask"/>');
		var overlay = $self;
        var start_grow_value = config.start_grow_value;
        var loaded = false;
        var images_loaded = false;
		var number_of_images_preloaded = 0;
		var total_img_to_load, left_offset, top_offset, left_offset_loader, top_offset_loader;
        var overlay_width, overlay_height;

        var size = viewport();


        // SET BINDING
        $self.bind('overlay.close',function(){
            self.close();
            return $self;
        });

        $self.bind('overlay.hide',function(){
            $self.css({"z-index":-1});
            mask.hide();
        });
		// public methods
		$.extend(self, {
            bind: function(name, fn) {
				$self.bind(name, fn);
				return self;
			},
			unbind: function(name) {
				$self.unbind(name);
				return self;
			},
			load: function() {
				if (loaded) {return self;}
				config.evt_BeforeLoad();
				self.set_variables();
				
				return self;
			},
			close: function() {
				config.evt_BeforeClose();

                if(config.effect == 'grow') {
                    self.close_grow();
                }
                else if(config.effect == 'fade') {
                    self.close_fade();
                }
                else if(config.effect == 'bounce') {
                    self.close_bounce();
                }
				
				mask.delay(300).fadeOut(300, function() {
					mask.remove();
					config.evt_AfterClose();
					loaded = false;
				});
				return self;
			},
			set_variables: function(){
				// SET MASK
                mask.css({position:'absolute', top:0, left:0, width:size[0], height:size[1], display: 'block', zIndex:9998});
				if(config.bool_mask_enabled){
				    mask.css({opacity:0, backgroundColor:config.mask_color});
                }
				else {
				    mask.css({opacity:1, 'visibility':'hidden',display:'none'});
                }
				$("body").prepend(mask);

				// SET OVERLAY
                overlay.css({position:'absolute', zIndex:9999, visibility:'hidden', top:0, left:0});
                $("body").prepend(overlay);

                // SET CLOSE BTN

				overlay.append('<div class="closeBtn"></div>');
                if(config.bool_close_btn_enabled){
                    $('.closeBtn',overlay).append('<a href="#">fermer</a>');
                    if(config.close_btn_content != ""){
                        $(".closeBtn a",overlay).html(config.close_btn_content);
                    }
                }
                $(".closeBtn a",overlay).css({display:'none'});

				// SET CONTENT
				overlay.append('<div class="contentOverlay"/>');
                $(".contentOverlay",overlay).css({position:'absolute',left:0,top:0,visibility:'hidden'});
                $(".contentOverlay",overlay).append(content);
                
                overlay_width = $(".contentOverlay",overlay).outerWidth();
                overlay_height = $(".contentOverlay",overlay).outerHeight();

                // FIND VAR
                total_img_to_load = $(".contentOverlay img",overlay).size();

                // SET EFFECT
                if(config.effect == 'grow') {
                    self.set_grow_variables();
                }
                else if(config.effect == 'fade') {
                    self.set_fade_variables();
                }
                else if(config.effect == 'bounce') {
                    self.set_bounce_variables();
                }
                else {
                    $.debug("your effect config must be right.");
                }

				return self;
			},
            set_events: function(){
				//SET ESC.KEYDOWN BTN HANDLER
                if(config.bool_esc_keydown_close_enabled){
				    $(document).bind("keydown.esc", function(evt){
                        if(evt.keyCode == 27){
                            self.close();
                        }
                    });
                }

				//SET MASK.CLICK HANDLER
				if(config.bool_mask_click_close_enabled){
                    mask.bind("click.mask", function(){
                        self.close();
                    });
                }

				//SET CLOSE BTN.CLICK HANDLER
                if(config.bool_close_btn_enabled){
				    $(".closeBtn a",overlay).bind('click.close_btn',function(e){
                        e.preventDefault();
                        self.close();
                    });
                }

				return self;
			},
            set_grow_variables : function(){
                // SET LOADER
                overlay.append('<div class="loader"></div>');
                left_offset_loader = start_grow_value/2;
                left_offset_loader -= $(".loader",overlay).width()/2;
                top_offset_loader = start_grow_value/2;
                top_offset_loader -=  $(".loader",overlay).height()/2;
                $(".loader",overlay).css({position:'absolute',top: top_offset_loader, left: left_offset_loader,display:'none'});
                self.begin_grow();
            },
			begin_grow: function() {
                //SHOW MASK
				if(config.bool_mask_enabled){
                    mask.fadeTo('normal', config.mask_opacity);
                }

                if($(".contentOverlay img",overlay).exists()){
                    //POSITION OVERLAY AND SHOW LOADER
                    left_offset = size[0]/2;
                    left_offset -= start_grow_value/2;
                    left_offset += $(window).scrollLeft();

                    top_offset = $(window).height()/2;
                    top_offset -= start_grow_value/2;
                    top_offset += $(window).scrollTop();
                    overlay.css({width:0,height:0,visibility:'visible'});
                    //CENTER OVERLAY
                    self.center();
                    overlay.animate({width:start_grow_value,height:start_grow_value,left:left_offset,top:top_offset},300,function(){
                        $(" > .loader",overlay).fadeIn(200,function(){
                            $(".contentOverlay img",overlay).each(function() {
                                var image = new Image();
                                image.src = $(this).attr('src');
                                if(image.complete){
                                    self.image_load(number_of_images_preloaded,total_img_to_load,images_loaded);
                                }
                                else {
                                    $(this).load(function() {
                                        self.image_load(number_of_images_preloaded,total_img_to_load,images_loaded);
                                    });
                                }
                            });
                        });
                    });
                }
                else {
                    overlay.css({width:0,height:0,visibility:'visible'});
                    self.center();
                    self.set_size();
                }
			},
			open_grow: function(){
                if($(".contentOverlay img",overlay).exists()) {
                    $(".loader",overlay).fadeOut(200,function(){
                        $(".loader",overlay).css({display:'block',visibility:'hidden'});
                        left_offset_loader = overlay_width/2;
                        left_offset_loader -= $(".loader",overlay).width()/2;
                        top_offset_loader = overlay_height/2;
                        top_offset_loader -=  $(".loader",overlay).height()/2;
                        $(".loader",overlay).css({position:'absolute',top: top_offset_loader, left: left_offset_loader,display:'none',visibility:'visible'});

                        left_offset = $(window).width()/2;
                        left_offset -= overlay_width/2;
                        left_offset += $(window).scrollLeft();

                        top_offset = $(window).height()/2;
                        top_offset -= overlay_height/2;
                        top_offset += $(window).scrollTop();

                        overlay.animate({'width':overlay_width,'height':overlay_height,'left':left_offset,'top':top_offset},100,function(){
                            $(".closeBtn a",overlay).show();
                            $(".contentOverlay",overlay).show();
                            loaded = true;
                            config.evt_AfterAppear();
                            self.evt_trigger_after_load();
                        });
                    });
                }
                else {
                    left_offset = $(window).width()/2;
                    left_offset -= overlay_width/2;
                    left_offset += $(window).scrollLeft();

                    top_offset = $(window).height()/2;
                    top_offset -= overlay_height/2;
                    top_offset += $(window).scrollTop();
                    
                    overlay.animate({'width':overlay_width,'height':overlay_height,'left':left_offset,'top':top_offset},100,function(){
                        $(".closeBtn a",overlay).show();
                        $(".contentOverlay",overlay).show();
                        loaded = true;
                        config.evt_AfterAppear();
                        self.evt_trigger_after_load();
                    });
                }
				return self;
			},
            close_grow: function(){
                $(".closeBtn a",overlay).hide();
				$(".contentOverlay",overlay).hide();
                left_offset = $(window).width()/2;
                left_offset -= 10/2;
                left_offset += $(window).scrollLeft();

                top_offset = $(window).height()/2;
                top_offset -= 10/2;
                top_offset += $(window).scrollTop();

                overlay.animate({'width':'10px','height':'10px','left':left_offset,top:top_offset},300,function(){overlay.remove();});
            },
            set_fade_variables : function(){
                self.begin_fade();
            },
			begin_fade: function() {
                //SHOW MASK
				if(config.bool_mask_enabled){
                    mask.fadeTo('normal', config.mask_opacity);
                }

                if($(".contentOverlay img",overlay).exists()){
                    $(".contentOverlay img",overlay).each(function() {
                        var image = new Image();
                        image.src = $(this).attr('src');
                        if(image.complete){
                            self.image_load(number_of_images_preloaded,total_img_to_load,images_loaded);
                        }
                        else {
                            $(this).load(function() {
                                self.image_load(number_of_images_preloaded,total_img_to_load,images_loaded);
                            });
                        }
                    });
                }
                else {
                    self.set_size();
                }
			},
			open_fade: function(){
                left_offset = $(window).width()/2;
                left_offset -= overlay_width/2;
                left_offset += $(window).scrollLeft();

                top_offset = $(window).height()/2;
                top_offset -= overlay_height/2;
                top_offset += $(window).scrollTop();

                overlay.css({'left':left_offset,'top':top_offset,visibility:'visible',display:'none'});
                $(".closeBtn a",overlay).show();
                $(".contentOverlay",overlay).show();
                if($.browser.msie){
                    overlay.show(); 
                }
                else {
                    overlay.fadeIn(300);
                }

                loaded = true;
                config.evt_AfterAppear();
                self.evt_trigger_after_load();
                
				return self;
			},
            close_fade: function(){
                if($.browser.msie){
                    window.setTimeout(function() {
                        overlay.hide().remove();
                    }, 300);

                }
                else {
                    overlay.fadeOut(300,function(){
                        overlay.remove();
                    });
                }

            },
            set_size: function(){
                config.evt_BeforeAppear();
                
                if($(".contentOverlay img",overlay).exists()){
                    overlay_width = $(".contentOverlay",overlay).outerWidth();
                    overlay_height = $(".contentOverlay",overlay).outerHeight();
                }
                
                $(".contentOverlay",overlay).css({position:'static',left:'auto',top:'auto',display:"none",visibility:'visible'});


                if(config.effect == 'grow') {
                    self.open_grow();
                }
                else if(config.effect == 'fade') {
                    self.open_fade();
                }
                else if(config.effect == 'bounce') {
                    self.open_bounce();
                }

				return self;
			},
			evt_trigger_after_load: function() {
                $("> .loader",overlay).remove();
                self.set_events();
                if(config.bool_resize_enabled) {
                    $(window).resize(function(){self.center();self.fit();});
                    $(window).scroll(function(){self.center();});
                }
			},
            image_load: function(number_of_images,total_images_to_load,images_loaded) {
				number_of_images++;
                number_of_images_preloaded = number_of_images;
				if(number_of_images_preloaded >= total_images_to_load && images_loaded != true){
					images_loaded = true;
					self.set_size();
					return true;
				}
				return self;
			},
			center: function() {
				if (overlay) {
					var left_offset = $(window).width()/2;
					left_offset -= overlay.outerWidth()/2;
					left_offset += $(window).scrollLeft();

					var top_offset = $(window).height()/2;
					top_offset -= overlay.outerHeight()/2;
					top_offset += $(window).scrollTop();

					overlay.css({ top: top_offset, left: left_offset});
					return self;
				}
			},
			fit: function() {
				if(mask){var size = viewport();mask.css({width:size[0], height:size[1]});}
				return self;
			}
		});

		if(!$('#overlay').exists()){self.load();}
        return $self;
	};
	$.overlay.defaults = {
		overlay_id                     : 'overlay',
		overlay_class                  : 'overlay',

		bool_mask_enabled              : true,
        bool_resize_enabled            : true,
		bool_mask_click_close_enabled  : true,
		bool_esc_keydown_close_enabled : true,
        bool_close_btn_enabled         : true,
        bool_fix_ratio_enabled         : false,

		mask_color                     : '#fff',
		mask_opacity                   : 0.7,

		close_btn_content              : '',

        fix_ratio_width                : 700,
        fix_ratio_height               : 700,

        effect                         : 'grow', // grow, fade, bounceTop

        start_grow_value               : 150,

		evt_BeforeLoad                 : function(){
		},
		evt_BeforeAppear               : function(){
		},
        evt_AfterAppear                : function(){
        },
		evt_BeforeClose                : function(){
		},
		evt_AfterClose                 : function(){
		}
	};
	
	/* one of the greatest headaches in the tool. finally made it */
	function viewport() {
		// the horror case
		if ($.browser.msie) {
			// if there are no scrollbars then use window.height
			var d = $(document).height(), w = $(window).height();
			return [
				window.innerWidth || 						// ie7+
				document.documentElement.clientWidth || 	// ie6  
				document.body.clientWidth, 					// ie6 quirks mode
				d - w < 20 ? w : d
			];
		} 
		// other well behaving browsers
		return [$(window).width(), $(document).height()];
	}
})(jQuery);
