var ModalDialog = function()
{
	var previouslyFocused = null;
	var previousScrollPosition = [0,0];
	function toggleModal()
	{
		if(document.body.className.search(/(^|\s+)modal(\s+|$)/) < 0)	//modal is not currently displayed
		{
			var s = (new WindowDimensions()).window.scroll;
			previousScrollPosition = [s.top, s.left];
			previouslyFocused = document.activeElement || previouslyFocused;
			document.body.className += " modal";
			setScrollPosition(document.getElementById("bodyWrapper"), s.top, s.left);
			document.getElementById("modalFocusLink").focus();
			disableBodyFocus();
		}
		else	//modal is currently displayed
		{
			reEnableBodyFocus();
			document.body.className = document.body.className.replace(/(^|\s+)modal(\s+|$)/g, " ");
			if(previouslyFocused) previouslyFocused.focus();
			setDocumentScrollPosition(previousScrollPosition[0], previousScrollPosition[1]);
		}
	}
	function disableBodyFocus()
	{
		var b = document.createElement("button");
		b.id = "modalBodyBlurButton";
		b.onfocus = redirectFocus;
		b.innerHTML = " ";
		document.body.appendChild(b);
		
		b = document.createElement("a");
		b.id = "modalBodyBlurLink";
		b.href = "#";
		b.onfocus = redirectFocus;
		b.innerHTML = " ";
		document.body.appendChild(b);
	}
	function reEnableBodyFocus()
	{
		var b = document.getElementById("modalBodyBlurLink");
		b.parentNode.removeChild(b);
		
		b = document.getElementById("modalBodyBlurButton");
		b.parentNode.removeChild(b);
	}
	function redirectFocus(evt)
	{
		document.getElementById("modalFocusLink").focus();
	}
	function confineEvent(evt)
	{
		evt = evt || event;
		if(evt.stopPropagation) evt.stopPropagation();
		else evt.cancelBubble = true;
	}
	function recordActiveElement(evt)
	{
		previouslyFocused = evt.target;
	}
	function fixOverlay(evt)
	{
		var modalDimensions = new ElementDimensions(document.getElementById("modalMask"));
		var overlay = document.getElementById("modalMaskOverlay");
		
		var height = modalDimensions.inner.height;
		var top = modalDimensions.scroll.top;
		overlay.style.height = (height+top)+"px";
		
		var width = modalDimensions.inner.width;
		var left = modalDimensions.scroll.left;
		overlay.style.width = (width+left)+"px";
	}
	
	function addHandler(obj, type, handler)
	{
		if(window.addEventListener) obj.addEventListener(type, handler, false);
		else obj.attachEvent("on"+type, handler);
	}
	
	//hideOnClick: hide the modal when you click outside of the dialog box
	function init(hideOnClick)
	{
		var mask = document.getElementById("modalMask");
		addHandler(document.getElementById("modalBlurLink"), "focus", redirectFocus);
		addHandler(document.getElementById("modalBlurButton"), "focus", redirectFocus);
		
		//only the most common events will be bounded by the mask
		addHandler(mask, "click", confineEvent);
		addHandler(mask, "dblclick", confineEvent);
		addHandler(mask, "keydown", confineEvent);
		addHandler(mask, "keypress", confineEvent);
		addHandler(mask, "keyup", confineEvent);
		addHandler(mask, "mousedown", confineEvent);
		addHandler(mask, "mouseup", confineEvent);
		addHandler(mask, "contextmenu", confineEvent);
		addHandler(mask, "mousemove", confineEvent);
		addHandler(mask, "mouseover", confineEvent);
		addHandler(mask, "mouseenter", confineEvent);
		addHandler(mask, "mouseleave", confineEvent);
		addHandler(mask, "mouseout", confineEvent);
		addHandler(mask, "mousewheel", confineEvent);
		addHandler(mask, "scroll", confineEvent);
		addHandler(mask, "reset", confineEvent);
		addHandler(mask, "submit", confineEvent);
		
		//update the size of the overlay when the dialog box is scrolled or the window is resized
		addHandler(mask, "scroll", fixOverlay);
		addHandler(window, "resize", fixOverlay);
		
		if(hideOnClick)
		{
			//hide the modal when you click outside of the dialog box
			addHandler(document.getElementById("modalContent"), "click", confineEvent);
			addHandler(document.getElementById("modalMaskOverlay"), "click", toggleModal);
		}
		
		//hack to get around Safari's lack of implementation for document.activeElement
		if(!document.activeElement && window.addEventListener)
		{
			var e = document.getElementById("bodyWrapper").getElementsByTagName("*");
			for(var i=0; i<e.length; i++)
			{
				e[i].addEventListener("focus", recordActiveElement, false);
			}
		}
	}
	
	return {
		init: init,
		toggle: toggleModal
	};
}();

