/*!	ColorBox v1.3.1 - a full fea18;5~tured, light-weight, customizable lightbox based on jQuery 1.3 */
//	(c) 2009 Jack Moore - www.colorpowered.com - jack@colorpowered.com
//	Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php

(function ($) {
	//Shortcuts (to increase compression)
	var modalbox = 'modalbox',
	hover = 'hover',
	TRUE = true,
	FALSE = false,
	mboxPublic,
	isIE = !$.support.opacity,
	isIE6 = isIE && !window.XMLHttpRequest,

	//Event Strings (to increase compression)
	mbox_click = 'click.modalbox',
	mbox_open = 'mbox_open',
	mbox_load = 'mbox_load',
	mbox_complete = 'mbox_complete',
	mbox_cleanup = 'mbox_cleanup',
	mbox_closed = 'mbox_closed',
	mbox_resize = 'resize.mbox_resize',
	mbox_ie6 = 'resize.mboxie6 scroll.mboxie6',

	//Cached jQuery Object Variables
	$overlay,
	$mbox,
	$wrap,
	$content,
	$topBorder,
	$leftBorder,
	$rightBorder,
	$bottomBorder,
	$related,
	$window,
	$loaded,
	$loadingOverlay,
	$loadingGraphic,
	//$title,

	//Variables for cached values or use across multiple functions
	interfaceHeight,
	interfaceWidth,
	loadedHeight,
	loadedWidth,
	maxWidth,
	maxHeight,
	element,
	index,
	settings,
	open,
	callback,
	
	// ColorBox Default Settings.	
	// See http://colorpowered.com/modalbox for details.
	
	
	defaults = {
		transition: "elastic",
		speed: 350,
		width:800, 
		height:FALSE,
		initialWidth:500, 
		initialHeight:350,
		maxWidth: 1000,
		maxHeight: 700,
		scalePhotos: TRUE,
		scrollbars: TRUE,
		inline: FALSE,
		html: FALSE,
		iframe: FALSE,
		photo: FALSE,
		href: FALSE,
		title: FALSE,
		rel: FALSE,
		opacity: 0.9,
		preloading: TRUE,
		current: "image {current} of {total}",
		previous: "previous",
		next: "next",
		close: "close",
		open: FALSE,
		overlayClose: false
		
		
	};

	// ****************
	// HELPER FUNCTIONS
	// ****************
	
	// Set Navigation Key Bindings
	/*function mbox_key(e) {
		if (e.keyCode === 37) {
			e.preventDefault();
			$prev.click();
		} else if (e.keyCode === 39) {
			e.preventDefault();
			$next.click();
		}
	}*/
	
	// Convert % values to pixels
	function setSize (size, dimension) {
		dimension = dimension === 'x' ? document.documentElement.clientWidth : document.documentElement.clientHeight;
		return (typeof size === 'string') ? (size.match(/%/) ? (dimension / 100) * parseInt(size, 10) : parseInt(size, 10)) : size;
	}

	// Checks an href to see if it is a photo.
	// There is a force photo option (photo: true) for hrefs that cannot be matched by this regex.
	function isImage (url) {
		return settings.photo || url.match(/\.(gif|png|jpg|jpeg|bmp)(?:\?([^#]*))?(?:#(\.*))?$/i);
	}
	
	// Assigns functions results to their respective settings.  This allows functions to be used to set ColorBox options.
	function process () {
		for (var i in settings) {
			if (typeof(settings[i]) === 'function') {
			    settings[i] = settings[i].call(element);
			}
		}
	}

	// ****************
	// PUBLIC FUNCTIONS
	// Usage format: $.fn.modalbox.close();
	// Usage from within an iframe: parent.$.fn.modalbox.close();
	// ****************
	
	mboxPublic = $.fn.modalbox = function (options, custom_callback) {
		
		if (this.length) {
			this.each(function () {
				var data = $(this).data(modalbox) ? $.extend({},
					$(this).data(modalbox), options) : $.extend({}, defaults, options);
				$(this).data(modalbox, data).addClass("mboxelement");
			});
		} else {
			$(this).data(modalbox, $.extend({}, defaults, options));
		}
		
		$(this).unbind(mbox_click).bind(mbox_click, function (event) {
			
			element = this;
			
			settings = $(element).data(modalbox);
			
			process();//process settings functions
			
			$().bind("keydown.mbox_close", function (e) {
				if (e.keyCode === 27) {
					e.preventDefault();
					mboxPublic.close();
				}
			});
			if (settings.overlayClose) {
				$overlay.css({"cursor": "pointer"}).one('click', mboxPublic.close);
			}
			
			//remove the focus from the anchor to prevent accidentally calling
			//modalbox multiple times (by pressing the 'Enter' key
			//after modalbox has opened, but before the user has clicked on anything else)
			element.blur();
			
			callback = custom_callback || FALSE;
			
			var rel = settings.rel || element.rel;
			
			if (rel && rel !== 'nofollow') {
				$related = $('.mboxelement').filter(function () {
					var relRelated = $(this).data(modalbox).rel || this.rel;
					return (relRelated === rel);
				});
				index = $related.index(element);
				
				if (index < 0) { //this checks direct calls to modalbox
					$related = $related.add(element);
					index = $related.length - 1;
				}
			
			} else {
				$related = $(element);
				index = 0;
			}
			if (!open) {
				open = TRUE;
				$.event.trigger(mbox_open);
				$overlay.css({"opacity": settings.opacity}).show();
				mboxPublic.position(setSize(settings.initialWidth, 'x'), setSize(settings.initialHeight, 'y'), 0);
				if (isIE6) {
					$window.bind(mbox_ie6, function () {
						$overlay.css({width: $window.width(), height: $window.height(), top: $window.scrollTop(), left: $window.scrollLeft()});
					}).trigger(mbox_ie6);
				}
			}
			
			mboxPublic.load();
			
			event.preventDefault();
		});
		
		if (options && options.open) {
			$(this).triggerHandler(mbox_click);
		}
		
		return this;
	};

	// Initialize ColorBox: store common calculations, preload the interface graphics, append the html.
	// This preps modalbox for a speedy open when clicked, and lightens the burdon on the browser by only
	// having to run once, instead of each time modalbox is opened.
	mboxPublic.init = function () {
		
		// jQuery object generator to save a bit of space
		function $div(id) {
			return $('<div id="mbox' + id + '"/>');
		}
		
		// Create & Append jQuery Objects
		$window = $(window);
		$mbox = $('<div id="modalbox"/>');
		$overlay = $div("Overlay").hide();
		$wrap = $div("Wrapper");
		$content = $div("Content").append(
					
			$loaded = $div("LoadedContent").css({width: 0, height: 0}),
			$loadingOverlay = $div("LoadingOverlay"),
			$loadingGraphic = $div("LoadingGraphic")
		);
		$wrap.append( // The 3x3 Grid that makes up ColorBox
			$('<div/>').append(
				$div("TopLeft"),
				$topBorder = $div("TopCenter"),
				$div("TopRight")
			),
			$('<div/>').append(
				$leftBorder = $div("MiddleLeft"),
				$content,
				$rightBorder = $div("MiddleRight")
			),
			$('<div/>').append(
				$div("BottomLeft"),
				$bottomBorder = $div("BottomCenter"),
				$div("BottomRight")
			)
		).children().children().css({'float': 'left'});
		$('body').prepend($overlay, $mbox.append($wrap));
				
		if (isIE) {
			$mbox.addClass('mboxIE');
			if (isIE6) {
				$overlay.css('position', 'absolute');
			}
		}
		
		// Add rollover event to navigation elements
		$content.children()
		.addClass(hover)
		.mouseover(function () { $(this).addClass(hover); })
		.mouseout(function () { $(this).removeClass(hover); })
		.hide();
		
		//$leftBorder.append( $div("MiddleLeftTop"), $div("MiddleLeftBottom") );
		//$leftBorder.append( $div("MiddleLeftMiddle") );		
		 
		
		// Cache values needed for size calculations
		interfaceHeight = /*$title.height() +*/  $topBorder.height() + $bottomBorder.height() + $content.outerHeight(TRUE) - $content.height();//Subtraction needed for IE6
		interfaceWidth = $leftBorder.width() + $rightBorder.width() + $content.outerWidth(TRUE) - $content.width();
		
		loadedHeight = $loaded.outerHeight(TRUE);
		loadedWidth = $loaded.outerWidth(TRUE);
		
		// Setting padding to remove the need to do size conversions during the animation step.
		$mbox.css({"padding-bottom": interfaceHeight, "padding-right": interfaceWidth}).hide();
		
		// Adding the 'hover' class allowed the browser to load the hover-state
		// background graphics.  The class can now can be removed.
		$content.children().removeClass(hover);
	};

	mboxPublic.position = function (mWidth, mHeight, speed, loadedCallback) {
		var winHeight = document.documentElement.clientHeight,
		posTop = winHeight / 2 - mHeight / 2,
		posLeft = document.documentElement.clientWidth / 2 - mWidth / 2,
		animate_speed;
		
		//keeps the box from expanding to an inaccessible area offscreen.
		if (mHeight > winHeight) { posTop -=(mHeight - winHeight); }
		if (posTop < 0) { posTop = 0; } 
		if (posLeft < 0) { posLeft = 0; }
		
		posTop += $window.scrollTop();
		posLeft += $window.scrollLeft();
		
		mWidth = mWidth - interfaceWidth;
		mHeight = mHeight - interfaceHeight;
		
		//setting the speed to 0 to reduce the delay between same-sized content.
		animate_speed = ($mbox.width() === mWidth && $mbox.height() === mHeight) ? 0 : speed;
		
		//this gives the wrapper plenty of breathing room so it's floated contents can move around smoothly,
		//but it has to be shrank down around the size of div#modalbox when it's done.  If not,
		//it can invoke an obscure IE bug when using iframes.
		$wrap[0].style.width = $wrap[0].style.height = "9999px";
		
		function modalDimensions (that) {
			//loading overlay size has to be sure that IE6 uses the correct height.
			$topBorder[0].style.width = /*$title[0].style.width =*/ $bottomBorder[0].style.width = $content[0].style.width = that.style.width;			
			$loadingGraphic[0].style.height = $loadingOverlay[0].style.height = $content[0].style.height = $leftBorder[0].style.height = $rightBorder[0].style.height = that.style.height;			
		}
		
		$mbox.dequeue().animate({height:mHeight, width:mWidth, top:posTop, left:posLeft}, {duration: animate_speed,
			complete: function(){
				modalDimensions(this);
				
				//shrink the wrapper down to exactly the size of modalbox to avoid a bug in IE's iframe implementation.
				$wrap[0].style.width = (mWidth+interfaceWidth) + "px";
				$wrap[0].style.height = (mHeight+interfaceHeight) + "px";
				
				if (loadedCallback) {loadedCallback();}
			},
			step: function(){
				modalDimensions(this);
			}
		});
	};

	mboxPublic.resize = function (object) {
		if(!open){ return; }
		
		var width,
		height,
		topMargin,
		prev,
		prevSrc,
		next,
		nextSrc,
		photo,
		timeout,
		speed = settings.transition==="none" ? 0 : settings.speed;
		
		$window.unbind(mbox_resize);
		
		if(!object){
			timeout = setTimeout(function(){ //timer allows IE to render the dimensions before attempting to calculate the height
				height = $loaded.children().outerHeight(TRUE);
				$loaded[0].style.height = height + 'px';
				mboxPublic.position($loaded.width()+loadedWidth+interfaceWidth, height+loadedHeight+interfaceHeight, speed);
			}, 1);
			return;
		}
		
		$loaded.remove();
		$loaded = $(object);
		
		function getWidth(){
			width = settings.width ? maxWidth : maxWidth && maxWidth < $loaded.width() ? maxWidth : $loaded.width();
			return width;
		}
		function getHeight(){
			height = settings.height ? maxHeight : maxHeight && maxHeight < $loaded.height() ? maxHeight : $loaded.height();
			return height;
		}
		
		if(!settings.scrollbars){
			$loaded.css({overflow:'hidden'});
		}
		
		$loaded.hide().appendTo('body')
		.attr({id:'mboxLoadedContent'})
		.css({width:getWidth()})
		.css({height:getHeight()})//sets the height independently from the width in case the new width influences the value of height.
		.prependTo($content);
		
		// Hides 'select' form elements in IE6 because they would otherwise sit on top of the overlay.
		if (isIE6) {
			$('select:not(#modalbox select)').filter(function(){
				return $(this).css('visibility') !== 'hidden';
			}).css({'visibility':'hidden'}).one(mbox_cleanup, function(){
				$(this).css({'visibility':'inherit'});
			});
		}
		
		photo = $('#mboxPhoto')[0];
		if (photo && settings.height) {
			topMargin = (height - parseInt(photo.style.height, 10))/2;
			photo.style.marginTop = (topMargin > 0 ? topMargin : 0)+'px';
		}
		
		function setPosition (s) {
			var mWidth = width+loadedWidth+interfaceWidth,
			mHeight = height+loadedHeight+interfaceHeight;
			

			mboxPublic.position(mWidth, mHeight, s, function(){
				if (!open) { return; }
				
				if (isIE) {
					//This fadeIn helps the bicubic resampling to kick-in.
					if( photo ){$loaded.fadeIn(100);}
					//IE adds a filter when ColorBox fades in and out that can cause problems if the loaded content contains transparent pngs.
					$mbox[0].style.removeAttribute("filter");
				}
				
				$content.children().show();
				
				//Waited until the iframe is added to the DOM & it is visible before setting the src.
				//This increases compatability with pages using DOM dependent JavaScript.
				$('#mboxIframeTemp').after("<iframe id='mboxIframe' name='iframe_"+new Date().getTime()+"' frameborder=0 src='"+(settings.href || element.href)+"' />").remove();
				
				//$title.html(settings.title || element.title);
				
				$loadingOverlay.hide();
				$loadingGraphic.hide();
				
				
				
				$.event.trigger(mbox_complete);
				
				if (callback) {
					callback.call(element);
				}
				
				if (settings.transition === 'fade'){
					$mbox.fadeTo(speed, 1, function(){
						if(isIE){$mbox[0].style.removeAttribute("filter");}
					});
				}
				
				$window.bind(mbox_resize, function(){
					mboxPublic.position(mWidth, mHeight, 0);
				});
			});
		}
		
		if((settings.transition === 'fade' && $mbox.fadeTo(speed, 0, function(){setPosition(0);})) || setPosition(speed)){}
		
		// Preloads images within a rel group
		if (settings.preloading && $related.length>1) {
			//prev = index > 0 ? $related[index-1] : $related[$related.length-1];
			//next = index < $related.length-1 ? $related[index+1] : $related[0];
			//nextSrc = $(next).data(modalbox).href || next.href;
			//prevSrc = $(prev).data(modalbox).href || prev.href;
			
			//if(isImage(nextSrc)){
			//	$('<img />').attr('src', nextSrc);
			//}
			
			//if(isImage(prevSrc)){
			//	$('<img />').attr('src', prevSrc);
			//}
		}
	};

	mboxPublic.show_loading = function ()
	{
		$loadingOverlay.show();
		$loadingGraphic.show();	
	}

	mboxPublic.hide_loading = function ()
	{
		$loadingOverlay.hide();
		$loadingGraphic.hide();			
	}

	mboxPublic.load = function () {
		var height, width, href, loadingElement, resize = mboxPublic.resize;
		
		element = $related[index];
		
		settings = $(element).data(modalbox);
		
		//convert functions to static values
		process();
		
		$.event.trigger(mbox_load);
		
		// Evaluate the height based on the optional height and width settings.
		height = settings.height ? setSize(settings.height, 'y') - loadedHeight - interfaceHeight : FALSE;
		width = settings.width ? setSize(settings.width, 'x') - loadedWidth - interfaceWidth : FALSE;
		
		href = settings.href || element.href;
		
		$loadingOverlay.show();
		$loadingGraphic.show();

		
		//Re-evaluate the maximum dimensions based on the optional maxheight and maxwidth.
		if(settings.maxHeight){
			maxHeight = settings.maxHeight ? setSize(settings.maxHeight, 'y') - loadedHeight - interfaceHeight : FALSE;
			height = height && height < maxHeight ? height : maxHeight;
		}
		if(settings.maxWidth){
			maxWidth = settings.maxWidth ? setSize(settings.maxWidth, 'x') - loadedWidth - interfaceWidth : FALSE;
			width = width && width < maxWidth ? width : maxWidth;
		}
		
		maxHeight = height;
		maxWidth = width;
		
		if (settings.inline) {
			$('<div id="mboxInlineTemp" />').hide().insertBefore($(href)[0]).bind(mbox_load+' '+mbox_cleanup, function(){
				$loaded.children().insertBefore(this);
				$(this).remove();
			});
			resize($(href).wrapAll('<div/>').parent());
		} else if (settings.iframe) {
			resize($("<div><div id='mboxIframeTemp' /></div>"));
		} else if (settings.html) {
			resize($('<div/>').html(settings.html));
		} else if (isImage(href)){
			loadingElement = new Image();
			loadingElement.onload = function(){
				loadingElement.onload = null;
				
				if((maxHeight || maxWidth) && settings.scalePhotos){
					var width = this.width,
					height = this.height,
					percent = 0,
					that = this,
					setResize = function(){
						height += height * percent;
						width += width * percent;
						that.height = height;
						that.width = width;	
					};
					
					if( maxWidth && width > maxWidth ){
						percent = (maxWidth - width) / width;
						setResize();
					}
					if( maxHeight && height > maxHeight ){
						percent = (maxHeight - height) / height;
						setResize();
					}
				}
				
				resize($("<div />").css({width:this.width, height:this.height}).append($(this).css({width:this.width, height:this.height, display:"block", margin:"auto", border:0}).attr('id', 'mboxPhoto')));
				
				if($related.length > 1){
					$(this).css({cursor:'pointer'}).click(mboxPublic.next);
				}
				
				if(isIE){
					this.style.msInterpolationMode='bicubic';
				}
			};
			loadingElement.src = href;
		} else {
			$('<div />').load(href, function(data, textStatus){
				if(textStatus === "success"){
					resize($(this));
				} else {
					resize($("<p>Request unsuccessful.</p>"));
				}
			});
		}
	};


	//Note: to use this within an iframe use the following format: parent.$.fn.modalbox.close();
	mboxPublic.close = function () {
		$.event.trigger(mbox_cleanup);
		open = FALSE;
		$window.unbind(mbox_resize+" "+mbox_ie6);
		$overlay.css({cursor: 'auto'}).fadeOut('fast');
		
		$mbox
		.stop(TRUE, FALSE)
		.fadeOut('fast', function () {
			$loaded.remove();
			$mbox.css({'opacity': 1});
			$content.children().hide();
			$.event.trigger(mbox_closed);
		});
	};

	mboxPublic.element = function(){ return element; };

	mboxPublic.settings = defaults;

	// Initializes ColorBox when the DOM has loaded
	$(mboxPublic.init);

}(jQuery));
