(function($) {
	$.fn.moogal = function(options) {
		var modal = ".rosettaModal";
		var overlay = ".moogalOverlay";
		var shim = ".moogalShim";
		var isActive = false;
		var isOversized = false;
		var isPositionFixed = false;
		var positionInfo = {};
		
		var defaults = {
			openTrigger: null,
			closeTrigger: overlay,
			ajax: null,
			opacity: "0.8",
			shim: false
		};
		
		var o = $.extend(defaults, options);
		
		//console.log("openTrigger: " + o.openTrigger);
		//console.log("closeTrigger: " + o.closeTrigger);
		//console.log("ajax: " + o.ajax);
		//console.log("shim: " + o.shim);
		//console.log("opacity: " + o.opacity);
		
		var config = function() {
			$("body").append("<script type='text/javascript'>var ie6 = false;</script><!--[if IE 6]><script type='text/javascript'>ie6 = true;</script><![endif]-->");
			
			if(o.openTrigger) {
				$(o.openTrigger).live("click", function() {
					init(this);
					return false;	// prevent following link
				});
			}
			
			if(o.closeTrigger) {
				$(o.closeTrigger).live("click", function() {
					dispose();
					return false;	// prevent following link
				});
			}
			
			if($(overlay).size() > 0) {
				$(overlay).remove();
			}
		}
		
		var init = function(otrig) {
			//console.log("initializing...");
			if($(overlay).size() === 0) {	// execute these items the first time the overlay is added to the page
				$("body").append("<div class=" + overlay.substr(1) + "></div>");	// embed the overlay into the page before the closing body tag
				
				if(o.shim && ie6) {		// iframe shim for ie6
					$(overlay).prepend("<iframe class='" + shim.substr(1) + "' frameborder='0' style='filter: alpha(opacity = 0); position: absolute; top: 0; left: 0; width: 100%; height: 100%;'></iframe>");
					if(o.closeTrigger.search(overlay) >= 0) {
						$(shim).load(function() {
							var iframeShim = $(this).contents().get(0);		// get moogalShim dom element
							$(iframeShim).click(function() {	// and apply a click event
							    dispose();
							});
						});
					}
				}
				
				$(overlay).css("opacity", o.opacity);
			}
			
			if(o.ajax) {
				var tempUrl = o.ajax;
				if($(modal).size() > 0) {
					$(modal).remove();	// remove existing ajax modal
				}
				
				if(o.ajax === "@href") {
					tempUrl = $(otrig).attr("href");
				}
				
				$.get(tempUrl, function(html) {
					$("body").append(html);
					display();
				});
			} else {
				display();
			}
		};
		

		
		var display = function() {
			//console.log("displaying...");
			isOversized = false;
			isPositionFixed = false;
			//$(modal).css("visibility", "hidden").show();
			positionInfo = {
				position: $(modal).css("position"),
				left: "50%",
				top: "50%",
				leftMargin: "-" + ($(modal).outerWidth()/2) + "px",
				topMargin: "-" + ($(modal).outerHeight()/2) + "px",
				zIndex: parseInt($(overlay).css("z-index")) + 1
			}
//			alert("outerHeight: " + $(modal).outerHeight());
//			alert("outerWidth: " + $(modal).outerWidth());
			
			$(overlay).show();
			
			if(ie6) {
				adjustOverlay();
				$(overlay).css("display", "block");	// force overlay to re-render over any select elements
				emulatePositionFixed();
			}
			
			$(modal).css("margin-left", positionInfo.leftMargin).css("margin-top", positionInfo.topMargin).css("z-index", positionInfo.zIndex);
			oversizedPositioning();
			$(modal).show()//.css("visibility", "visible");
			isActive = true;
		}
		
		var dispose = function() {
			//console.log("disposing...");
			if(ie6) { abandonPositionFixed(); }
			$(modal).hide();
			$(overlay).hide();
			isActive = false;
		};
		
		var adjustOverlay = function() {
			//console.log("adjusting overlay...");
			$(overlay).width($(document).width()).height($(document).height());
		};
		
		var emulatePositionFixed = function() {
			//console.log("emulating position fixed...");
			$(window).bind("scroll", function() {
				$(modal).css("top", $(document).scrollTop() + $(window).height() / 2 + "px");
			});
			isPositionFixed = true;
		};
		
		var oversizedPositioning = function() {
			//console.log("oversized positioning...");
			if($(modal).width() > $(window).width() || $(modal).height() > $(window).height()) {
				if(ie6 && isPositionFixed) { abandonPositionFixed(); }
				$(modal).css("position", "absolute");
				if($(modal).width() > $(window).width() && $(modal).height() > $(window).height()) {
					$(".console").text("width and height too large");
					$(modal).css("top", $(document).scrollTop());
					$(modal).css("margin-top", 0);
					$(modal).css("left", $(document).scrollLeft());
					$(modal).css("margin-left", 0);
				} else if($(modal).height() > $(window).height()) {
					$(".console").text("height too large");
					////console.log("height too large");
					$(modal).css("top", $(document).scrollTop());
					$(modal).css("margin-top", 0);
					$(modal).css("left", ($(document).scrollLeft() + ($(window).width() / 2)) + "px")
					if(isOversized) {
						$(modal).css("margin-left", positionInfo.leftMargin);
					}
				} else {
					$(modal).css("left", $(document).scrollLeft());
					$(modal).css("margin-left", 0);
					$(modal).css("top", ($(document).scrollTop() + ($(window).height() / 2)) + "px")
					if(isOversized) {
						$(modal).css("margin-top", positionInfo.topMargin);
					}
				}
				
				isOversized = true;
			} else {
				if(ie6) {
					$(modal).css("top", $(document).scrollTop() + $(window).height() / 2 + "px");
					$(modal).css("left", $(document).scrollLeft() + $(window).width() / 2 + "px");
				}
				if(isOversized) {
					restorePosition();
					isOversized = false;
				}
			}
		}
		
		var restorePosition = function() {
			//console.log("restoring position...");
			$(modal).css("position", positionInfo.position).css("left", positionInfo.left).css("top", positionInfo.top).css("margin-left", positionInfo.leftMargin).css("margin-top", positionInfo.topMargin);
			if(ie6 && !isPositionFixed) { emulatePositionFixed(); }
		}
		
		var abandonPositionFixed = function() {
			//console.log("abandoning position fixed...");
			$(window).unbind("scroll");
			isPositionFixed = false;
		}
		
//		var customEvent = function() {
//			//name of the event
//			this.eventName = arguments[0];
//			var mEventName = this.eventName;
//
//			//function to call on event fire
//			var eventAction = null;
//
//			//subscribe a function to the event
//			this.subscribe = function(fn) {
//				eventAction = fn;
//			};
//
//			//fire the event
//			this.fire = function(sender, eventArgs) {
//				this.eventName = eventName2;
//				if(eventAction != null) {
//					eventAction(sender, eventArgs);
//				}
//				else {
//					alert("There was no function subscribed to the " + mEventName + " event!");
//				}
//			};
//		};


		$(window).resize(function() {
			if(isActive) {
				if(ie6) { adjustOverlay(); }
				oversizedPositioning();
			}
		});
		
		config();
	}
	
})(jQuery);
