 /*
 * Fullsize 2
 * Copyright 2009 Drew Wilson
 * www.drewwilson.com
 * www.fullsize.com
 *
 * Version 2.0   -   Updated: Oct. 12, 2009
 *
 * Fullsize is an attempt to standardize the way in page 'image popups' work.
 * It seems there are hundreds of javascripts light boxes, modal boxes, image zooms, image popups, etc.
 * But none of them provide a way to signal the user that what they just clicked on, is an
 * in page pop-up of a larger version (or 'fullsize' version) of the image they just clicked.
 * fullsize is an attempt to do just that, provide a 'standard' way for users to recognize an in page pop-up.
 *
 * My intention is to get a 'fullsize' attribute added to the <IMG> element in the next version of HTML.
 * This would allow browsers to do an in page pop-up of the 'fullsize' image natively.
 * 
 * In page pop ups are here to stay... so lets standardize them.
 *
 * Check out www.fullsize.com for more info and to show your support for Fullsize.
 *
 * This jQuery plug-in is my atempt to bring the idea of 'fullsize' into a reality.
 * Though my intention is to push this functionality to the browser itself and not rely on JavaScript libraries,
 * for now, this will have to do :)
 *
 * This Fullsize jQuery plug-in is dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

(function($){

	$.fn.fullsize = function(options) {

		var defaults = {  
		  	shadow: true,  
		  	zoomInSpeed: 200,  
		  	zoomOutSpeed: 200,
		  	fadeInSpeed: 250,  
		  	fadeOutSpeed: 250,
		  	leftOffset: 0,
		  	topOffset: 0,
		  	useIcon: true, 
		  	iconOffset: 8,
		  	showIndex: true,
		  	useRel: false, 
		  	autoResize: false,
		  	forceWidth: false,
		  	forceTitleBar: true,
		  	extraTrigger: false,
		  	parentSteps: 0,
		  	destroy: false,
		  	start: function(){},
		  	end: function(){}
	  	};  
	 	var opts = $.extend(defaults, options);
	 	
	 	// Remove all Fullsize Icons on destroy request
	 	if(opts.destroy){
	 		$("div.fullsize-icon").remove();
	 	}

	 	// If ESC key pressed, close Fullsize
	 	$(document).keydown(function(event){
	 		if(event.keyCode == 27){
	 			$("div.fullsize-wrapper, div.fullsize-sh-wrap").fadeOut(opts.fadeOutSpeed, function(){
	 				$(this).remove();
	 			});
	 			opts.end.call(this);
	 		}
	 	});
	 	
		var org_selector = this.filter("[longdesc]");
		var org_length = org_selector.length;
		
		return org_selector.each(function(){
			
			// Remove all Fullsize bound events
			if(opts.destroy){
				$(this).unbind();
			} else {
		
				// Declare the current Image as a variable, and gather some of it's properties.
				var org_image = $(this);	
				var img_title = org_image.attr("title");
				var img_src = org_image.attr("longdesc");
				
				// Move up Parents until the spcified limit has been met, then find the additional specified Selector
				var addTrigger;
				if(opts.extraTrigger){
					var theParent = org_image;
					for (var i=0; i <= opts.parentSteps; i++){
						theParent = theParent.parent();
					}
					addTrigger = theParent.find(opts.extraTrigger);
				}
				
				// Set trigger for click event
				var clickTrigger = org_image;
				
				// Show Icon if asked to
				if(opts.useIcon){
				
					// Setup the Fullsize Icon 
					var icon = $("<div></div>").addClass("fullsize-icon").css({"display":"none"});
				
					clickTrigger = icon;		
					org_image.add(addTrigger).hover(function(){
					
						// If the Original Image is contained inside of an Element that has a 'overflow' set to 'hidden',
						// and the Original Image has a negitive 'margin-top', this will make the Offest values be set to the 
						// Element with the 'overflow:hidden' property, rather than the Original Image itself.
						// Otherwise the fullsize icon would not show up in the correct position.
						var margin_top = org_image.css("marginTop").slice(0,-2);
						var margin_bottom = org_image.css("marginLeft").slice(0,-2);
						var margin_left = org_image.css("marginLeft").slice(0,-2);
						var margin_right = org_image.css("marginLeft").slice(0,-2);
						if (margin_top < 0 || margin_bottom < 0 || margin_left < 0 || margin_right < 0) {
							var parent_ele = $(org_image);
							var parentEls = $(org_image).parents();  
							 $(parentEls).each(function(){
								if(this.tagName == "BODY") {
									return false;
								} else if($(this).css("overflow") == "hidden") {
									parent_ele = $(this);
									return false;
								}
							});
							var offset = parent_ele.offset();
							var parent_border_top = parseInt(parent_ele.css("border-top-width"));
							var parent_border_left = parseInt(parent_ele.css("border-left-width"));
						} else {
							var offset = org_image.offset();
							var parent_border_top = parseInt(org_image.css("border-top-width"));
							var parent_border_left = parseInt(org_image.css("border-left-width"));
						}
						if (!parent_border_top){ parent_border_top = 0; }
						if (!parent_border_left){ parent_border_left = 0; }
												
						var displayFlag = false;
						$("div.fullsize-icon").each(function(){		
							if(parseInt($(this).css("top")) == (offset.top + opts.iconOffset + parent_border_top) && parseInt($(this).css("left")) == (offset.left + opts.iconOffset + parent_border_left)){
								displayFlag = true;
								curIcon = $(this);
							}
						});
						if(displayFlag == false){
							$(icon).css({"top":offset.top + opts.iconOffset + parent_border_top, "left":offset.left + opts.iconOffset + parent_border_left});
							$("body").prepend(icon);
						}
						$(icon).show();
					}, function(){
						$(icon).hide();
					});
					$(icon).hover(function(){
						$(this).show();
					}, function(){
						$(this).hide();
					});
				}
			
				clickTrigger.click(function(){
					
					opts.start.call(this);
					
					// If a Fullsize Popup is currently active, we will remove it before creating a new one.	
					$("div.fullsize-wrapper, div.fullsize-sh-wrap").remove();

					// Are we filtering by REL?
					if(opts.useRel){
						var org_rel = org_selector.filter("[rel="+$(this).attr('rel')+"]");
						org_length = org_rel.length;	
					}
					
					// Gather window & scroll positions.
					var win_w = $(window).width();
					var win_h = $(window).height();
					var scrolltop = $(window).scrollTop();
					var scrollleft = $(window).scrollLeft();								

					// Setup the Loading DIV 
					if(!$.support.opacity && parseInt($.browser.version.substr(0,1)) < "8"){
						var loading_left = (((win_w - opts.leftOffset) / 2) + scrollleft) - 25;
						var loading_top = (((win_h - opts.topOffset) / 2) + scrolltop) - 25;
					} else {
						var loading_left = (((win_w + opts.leftOffset) / 2) + scrollleft) - 25;
						var loading_top = (((win_h + opts.topOffset) / 2) + scrolltop) - 25;
					}
					var full_loading = $("<div></div>").addClass('fullsize-loading').css({"margin-left":loading_left, "margin-top":loading_top});
					var full_loading_inner = $("<div></div>").addClass('fullsize-loading-inner');
					$(full_loading).prepend(full_loading_inner);
					$("body").prepend(full_loading);
					
					// Setup the Fullsize Media 
					var longdesc = org_image.attr("longdesc");	
					if(longdesc.substr(0,1) != "#"){			
						var full_img = new Image();
						$(full_img).load(function(){
							do_zoom(this);
						});
					} else {
						var full_img = $("<div></div>").addClass("fullsize-html").html($(longdesc).html());
						do_zoom(full_img);
					}
									
					function do_zoom(obj){
						$(obj).hide();
						
						// Determine how to position the Fullsize Image into the center of the page.
						var img_w, img_h;
						var new_offset = org_image.offset();
						if(longdesc.substr(0,1) != "#"){			
							img_w = obj.width;
							img_h = obj.height;
						} else {
							img_w = parseInt($(longdesc+" [width]:first").attr("width"));
							img_h = parseInt($(longdesc+" [height]:first").attr("height"));
						}
					
						// If the Image is bigger than the window, shrink it to fit in the window.	
						var off_num = 36;
						if(org_length > 1){
							off_num = 90;
						}
						 					
						if(!opts.forceWidth){
							var aspect = img_w / img_h;
							if (((img_w + opts.leftOffset) + 32) > win_w) {
								img_w = (win_w - opts.leftOffset) - 32;
								img_h = img_w / aspect;
							}
							if (((img_h + opts.topOffset) + off_num) > win_h) {
								img_h = (win_h - opts.topOffset) - off_num;
								img_w = img_h * aspect;
							}
						}
						
						var new_h = img_h;
						var max_h = (win_h - opts.topOffset) - off_num;
						if(opts.forceWidth && img_h > max_h){
							new_h = max_h;
						}
						
						if(!$.support.opacity && parseInt($.browser.version.substr(0,1)) < "8"){
							var img_left = Math.round((((win_w - opts.leftOffset) - img_w) / 2) + scrollleft);
							var img_top = Math.round((((win_h - opts.topOffset) - new_h) / 2) + scrolltop);
						} else {
							var img_left = Math.round((((win_w + opts.leftOffset) - img_w) / 2) + scrollleft);
							var img_top = Math.round((((win_h + opts.topOffset) - new_h) / 2) + scrolltop);
						}
						if(img_left < 0) {
							img_left = 0;
						}
						if(img_top < 0) {
							img_top = 0;
						}	

						$(obj).css({"height": org_image.height() + "px", "width":org_image.width() + "px"});
						$("div.fullsize-loading").remove();
						var full_wrap = $("<div></div>").addClass("fullsize-wrapper").css({"display":"none", "margin-top":new_offset.top, "margin-left":new_offset.left});							
						// If we are showing the Title bar, display it.				
						if(img_title != "" || opts.forceTitleBar) {			
							var full_close = $("<a></a>").addClass("fullsize-close");
							var full_title = $("<div></div>").addClass("fullsize-title").css({"max-width":img_w});
							var full_title_text = $("<div></div>").addClass("fullsize-title-text").text(img_title);							
							$(full_title).prepend(full_close);
							$(full_title).prepend(full_title_text);
							$(full_wrap).prepend(full_title);
							if(img_top != 0) {
								if(org_length > 1){
									img_top = img_top - 32;
								} else {
									img_top = img_top - 12;
								}
							}	
							var is_title = true;
						} else {
							if(img_top != 0) {
								if(org_length > 1){
									img_top = img_top - 22;
								} else {
									img_top = img_top - 6;
								}
							}						
							$(obj).addClass("fullsize-close");
							var is_title = false;
						}
						
						var full_img_holder = $("<div></div>").addClass("fullsize-image-holder");						
						$(full_img_holder).append(obj);
						$(full_wrap).append(full_img_holder);
						if(org_length > 1){
							var full_opts = $("<div></div>").addClass("fullsize-opts").css({"max-width":img_w});
							var full_opts_index = $("<div></div>").addClass("fullsize-opts-index");
							var full_opts_left = $("<div></div>").addClass("fullsize-opts-left").html('<a href="" title="Previous"></a>');
							var full_opts_right = $("<div></div>").addClass("fullsize-opts-right").html('<a href="" title="Next"></a>');
							$(full_opts).prepend(full_opts_right);
							$(full_opts).prepend(full_opts_index);
							$(full_opts).prepend(full_opts_left);						
							$(full_wrap).append(full_opts);
						}
						$("body").prepend(full_wrap);

						// Setup Shadows
						if (opts.shadow == true) {
							if ($.browser.safari || ($.browser.mozilla && $.browser.version.substr(0,5) >= "1.9.1")) {
								$(full_wrap).css({"-webkit-box-shadow":"0 2px 16px #000", "-moz-box-shadow":"0 2px 16px #000", "box-shadow":"0 2px 16px #000"});
							} else {
								var full_sh_wrap = $("<div></div>").addClass("fullsize-sh-wrap").css({"display":"none", "width": org_image.width(), "margin-top":new_offset.top, "margin-left":new_offset.left});
								var full_sh_top = $("<div></div>").addClass("fullsize-sh-top");
								var full_sh_top_left = $("<div></div>").addClass("fullsize-sh-top-l");
								var full_sh_top_middle = $("<div></div>").addClass("fullsize-sh-top-m");
								var full_sh_top_right = $("<div></div>").addClass("fullsize-sh-top-r");
								$(full_sh_top).append(full_sh_top_left).append(full_sh_top_right).append(full_sh_top_middle);
								$(full_sh_wrap).prepend(full_sh_top);
								var full_sh_body = $("<div></div>").addClass("fullsize-sh-body");
								var full_sh_body_r = $("<div></div>").addClass("fullsize-sh-body-r");
								$(full_sh_body).append(full_sh_body_r);
								$(full_sh_wrap).append(full_sh_body);
								var full_sh_bottom = $("<div></div>").addClass("fullsize-sh-bottom");
								var full_sh_bottom_left = $("<div></div>").addClass("fullsize-sh-bottom-l");
								var full_sh_bottom_middle = $("<div></div>").addClass("fullsize-sh-bottom-m");
								var full_sh_bottom_right = $("<div></div>").addClass("fullsize-sh-bottom-r");
								$(full_sh_bottom).append(full_sh_bottom_left).append(full_sh_bottom_right).append(full_sh_bottom_middle);
								$(full_sh_wrap).append(full_sh_bottom);
								$("body").prepend(full_sh_wrap);
								
								if(org_length > 1){
									var sh_off_num = 62;
								} else {
									var sh_off_num = 22;
								}
								
								// Setup shadow Animations
								$(full_sh_body).animate({
									height: parseInt(full_wrap.height()) + $(full_img_holder).height() - sh_off_num	
								}, {queue:false, duration:opts.zoomInSpeed});
								$(full_sh_wrap).fadeIn(opts.fadeInSpeed).animate({
									height: parseInt(full_wrap.height()) + $(full_img_holder).height() + sh_off_num,
									width: img_w + 22,
									marginTop: img_top - 9,
									marginLeft: img_left - 11 				
								}, {queue:false, duration:opts.zoomInSpeed});
							}
						}
						
						// Generate Index numbers
						if(opts.useRel){
							var curr = org_rel.index(org_image);
						} else {
							var curr = org_selector.index(org_image);
						}
						if(org_length > 1 && opts.showIndex){
							$(full_opts_index).html("<em>"+(curr + 1)+"</em>/"+org_length);
						}
						
						// Attach clicks to next/prev buttoms
						if((curr + 1) == org_length){
							$(full_opts_right).children("a").css({"opacity":"0.4"}).addClass("disabled");
						}
						$(full_opts_right).children("a").click(function(){
							var newImage = $('<img class="fullsize-image"></img>').hide();
							if((curr + 1) < org_length){
								curr++;
								fullsizeClick(newImage, full_opts_left);							
							} 
							if((curr + 1) == org_length){
								$(this).css({"opacity":"0.4"}).addClass("disabled");
								$(full_opts_left).children("a").css({"opacity":"1"}).removeClass("disabled");
							}
							return false;
						});
						if((curr + 1) == 1){
							$(full_opts_left).children("a").css({"opacity":"0.4"}).addClass("disabled");
						}
						$(full_opts_left).children("a").click(function(){
							var newImage = $('<img class="fullsize-image"></img>').hide();
							if((curr + 1) > 1){
								curr--;
								fullsizeClick(newImage, full_opts_right);
							} 
							if((curr + 1) == 1){
								$(this).css({"opacity":"0.4"}).addClass("disabled");
								$(full_opts_right).children("a").css({"opacity":"1"}).removeClass("disabled");
							}
							return false;
						});	
						
						//Fullsize Nav Click Function
						function fullsizeClick(newImage, alt_trigger){
							if(opts.useRel){
								var longdesc = org_rel.eq(curr).attr("longdesc");
							} else {
								var longdesc = org_selector.eq(curr).attr("longdesc");
							}		
							$("img.fullsize-image, div.fullsize-html").remove();
							if(longdesc.substr(0,1) != "#"){
								var new_img_w = img_w;
								$(full_img_holder).append(newImage.load(function(){
									if(!is_title){
										$(this).addClass("fullsize-close");
										$(".fullsize-close").unbind().click(function(){
											closefullsize(org_image, full_wrap);
											return false;
										});
									}
									var height_c = false;
									if($(this).height() > $(full_img_holder).height()){
										height_c = true;
									}
									if(opts.autoResize){
										var this_w = $(this).width();
										var new_left = Math.round(((($(window).width() - opts.leftOffset) - this_w) / 2) + $(window).scrollLeft());
										$(full_img_holder).animate({
											width: this_w,
											}, {queue:false, duration:opts.zoomInSpeed, complete: function(){
												if(height_c){
													$(full_img_holder).css({"overflow-y":"auto","overflow-x":"hidden"});
												}
												$(full_opts).css({"max-width":this_w});
												if(is_title){
													$(full_title).css({"max-width":this_w});
												}
											}});
										$(full_wrap).animate({
											width: this_w,
											marginLeft: new_left,
											}, {queue:false, duration:opts.zoomInSpeed});
										if(this_w > $(full_img_holder).width()){
											$(full_opts).css({"max-width":this_w});
											if(is_title){
												$(full_title).css({"max-width":this_w});
											}
										}
										new_img_w = this_w;
									} else if($(this).width() > $(full_img_holder).width()){
										$(this).css("width",$(full_img_holder).width());
										$(full_opts).css({"max-width":this_w});
										if(is_title){
											$(full_title).css({"max-width":this_w});
										}
									}
									if(($(this).height()-1) > $(full_img_holder).height()){
										$(full_img_holder).css({"overflow-y":"auto","overflow-x":"hidden"});
										$(this).css("width",new_img_w - 15);
									} else {
										if(opts.forceWidth){
											$(this).css({"width":new_img_w});
										}
										$(this).css({"padding-top": Math.round(($(full_img_holder).height() - $(this).height())/2) +"px"});
									}
									$(this).show();
								}).attr("src",longdesc));
							} else {
								var holder_w = $(full_img_holder).width();
								var holder_h = $(full_img_holder).height();
								var new_div = $('<div class="fullsize-html"></div>').css({"width":holder_w,"height":holder_h}).html($(longdesc).html());
								$(full_img_holder).css("overflow","inherit").append(new_div);
								var this_w = new_div.children(":first").attr("width");
								var this_h = new_div.children(":first").attr("height");
								new_div.find("[height]").attr("height",holder_h);
								if(opts.autoResize){
									var new_left = Math.round(((($(window).width() - opts.leftOffset) - this_w) / 2) + $(window).scrollLeft());
									$(full_opts).css({"max-width":this_w+"px"});
									if(is_title){
										$(full_title).css({"max-width":this_w+"px"});
									}
									$(full_img_holder).animate({
										width: this_w,
										}, {queue:false, duration:opts.zoomInSpeed});
									$(full_wrap).animate({
										width: this_w,
										marginLeft: new_left,
										}, {queue:false, duration:opts.zoomInSpeed});
									$(full_opts).css({"max-width":this_w});
									if(is_title){
										$(full_title).css({"max-width":this_w});
									}
								} else {
									new_div.find("[width]").attr("width",holder_w);
								}
							}
							if(is_title){
								if(opts.useRel){
									$(full_title_text).text(org_rel.eq(curr).attr("title"));
								} else {
									$(full_title_text).text(org_selector.eq(curr).attr("title"));
								}
							}
							$(full_opts_index).children("em").text(curr+1);
							$(alt_trigger).children("a").css({"opacity":"1"}).removeClass("disabled");
						}					
						
						// Setup Animations
						$(obj).fadeIn(opts.fadeInSpeed).animate({
							height: img_h,
							width: img_w				
						}, {queue:false, duration:opts.zoomInSpeed});
						$(full_wrap).fadeIn(opts.fadeInSpeed).animate({
							width: img_w,
							marginTop: img_top,
							marginLeft: img_left			
						}, {queue:false, duration:opts.zoomInSpeed, complete:function(){
							$(full_img_holder).css("height",img_h+"px");
							if(opts.forceWidth){
								if(img_h > max_h){
									$(full_img_holder).css({"overflow-y":"auto","overflow-x":"hidden","height":max_h+"px"});
								}
							}
							// Make sure Index Text is small enought to fit on 1 line
							if(parseInt($(full_opts_index).width()) < 60){
								$("div.fullsize-opts-index, div.fullsize-opts-index em").css({"font-size":"12px", "margin-top":"12px"});		
							} else if(parseInt($("div.fullsize-opts-index").width()) < 100){
								$("div.fullsize-opts-index, div.fullsize-opts-index em").css({"font-size":"20px", "margin-top":"8px"});
							}
						}});					
		
						$(".fullsize-close").click(function(){
							closefullsize(org_image, full_wrap);
							return false;
						});
					}	
					
					if(longdesc.substr(0,1) != "#"){		
						$(full_img).attr("src",img_src).addClass("fullsize-image");
					}
					if(!opts.useIcon){
						return false;
					}
					
				});				
				
				// This function is purposely pulled out of the Image Load function.
				// By doing so the Fullsize Image will now find the exact loacation of the Original Image 
				// when you click the Close button. This way the Fullsize Image will always go back to it's
				// original position, even if you resize the window, and the Original Image changes it's position.
				function closefullsize(org_image, full_wrap) {
					var offsets = org_image.offset();
					var the_img = $("img.fullsize-image");
					the_img.parent().andSelf().fadeOut(opts.fadeOutSpeed).animate({
						height: org_image.height(),
						width: org_image.width()				
					}, {queue:false, duration:opts.zoomOutSpeed, complete: function(){$(this).remove();}});
										
					if (opts.shadow) {
						$("div.fullsize-sh-wrap").remove();
					}
					$(full_wrap).fadeOut(opts.fadeOutSpeed).animate({
						width: org_image.width(),
						height: (org_image.height() + 56),
						marginTop: offsets.top,
						marginLeft: offsets.left			
					}, {queue:false, duration:opts.zoomOutSpeed, complete: function(){$(this).remove();the_img.remove();}});
					
					opts.end.call(this);
				}

			}		
		});
	}
})(jQuery);  