function ModalLayerDialog(dialogId, titleId, focusId)
{
	this.Dialog = null;
	this.Title = null;
	this.FocusElement = null;
	this.FirstOpen = true;
	this.HiddenDiv = null;
	this.CSS3Container = null;
	this.NeedsShadow = true;
	this.DialogPos = { top: 0, left: 0 };
	var m_OriginalShadowZIndex = 0;
	var m_OriginalShadowDisplay = "none";
	var m_OriginalShadowPos = { top: 0, left: 0 };
	var m_OriginalShadowSize = { width: 0, height: 0 };
	var m_OriginalOverlayZIndex = 0;
	var undefined;

	if (ModalLayerDialog.arguments.length >= 1) // constructor should work without arguments for inheritence
	{
		this.Dialog = document.getElementById(dialogId);
		if (this.Dialog)
			this.NeedsShadow = !HasShadow(this.Dialog);
		if (ModalLayerDialog.arguments.length >= 2 && titleId != null)
		{
			this.Title = document.getElementById(titleId);
			if (this.Title != null)
				this.Title.style.cursor = "url(common/cursors/drag.cur), pointer";
			if (ModalLayerDialog.arguments.length >= 3 && focusId != null)
				this.FocusElement = document.getElementById(focusId);												
		}
	}
	
	if (ModalLayerDialog.prototype.IsIFrameNeeded == null)
	{
		// covering IFrame only needed for IE prior version 7 to hide "select" input fields
		ModalLayerDialog.prototype.IsIFrameNeeded = false;
		var msie = navigator.userAgent.toLowerCase().split("msie");		
		if (msie.length > 1)
		{
			var version = parseFloat(msie[1]);
			if (version < 7)
				ModalLayerDialog.prototype.IsIFrameNeeded = true;
		}
	}
	
	var self = this;
	this.m_DragFunctions = new Array (
	                         function(event) { self.StartDrag(event); },
	                         function(event) { self.DragDialog(event); },
	                         function(event) { self.StopDrag(event); }
	                       );
	
	
	this.IsValid = function()
	{
		var node = this.Dialog;
		while (node != null && node.nodeType == 1)
		{
			if (node.tagName == "BODY")
				return true;
			node = node.parentNode;
		}
		return false;
	}

	this.SaveShadowData = function(shadowDiv)
	{
		if (shadowDiv != null)
		{
			m_OriginalShadowZIndex = shadowDiv.style.zIndex;
			m_OriginalShadowDisplay = shadowDiv.style.display;
			m_OriginalShadowPos.top = shadowDiv.offsetTop;
			m_OriginalShadowPos.left = shadowDiv.offsetLeft;
			m_OriginalShadowSize.width = shadowDiv.offsetWidth;
			m_OriginalShadowSize.height = shadowDiv.offsetHeight;
		}
	}

	this.RestoreShadowData = function(shadowDiv)
	{
		if (shadowDiv != null)
		{
			shadowDiv.style.zIndex = m_OriginalShadowZIndex;
			shadowDiv.style.display = m_OriginalShadowDisplay;
			shadowDiv.style.top = m_OriginalShadowPos.top + "px";
			shadowDiv.style.left = m_OriginalShadowPos.left + "px";
			shadowDiv.style.width = m_OriginalShadowSize.width + "px";
			shadowDiv.style.height = m_OriginalShadowSize.height + "px";
		}
	}
	
	this.SaveOverlayData = function(overlayDiv)
	{
		m_OriginalOverlayZIndex = overlayDiv.style.zIndex;
	}

	this.RestoreOverlayData = function(overlayDiv)
	{
		overlayDiv.style.zIndex = m_OriginalOverlayZIndex;
	}

	function HasShadow(element)
	{
		var styleValue;
		if (element.currentStyle) //IE
			styleValue = element.currentStyle["box-shadow"]
		else if (document.defaultView && document.defaultView.getComputedStyle) // others
		{
			var style = document.defaultView.getComputedStyle(element, null);
			styleValue = style.getPropertyValue("box-shadow")
			if (styleValue === undefined || styleValue == null || styleValue.length == 0)
				styleValue = style.MozBoxShadow; // old FF browsers
			if (styleValue === undefined || styleValue == null || styleValue.length == 0)
				styleValue = style.webkitBoxShadow; // old webkit (safari) browsers
		}
		
		return (!(styleValue === undefined) && (styleValue.length > 0));
	}
}

ModalLayerDialog.prototype.IsIFrameNeeded = null;
ModalLayerDialog.prototype.OverlayDiv = null;
ModalLayerDialog.prototype.ShadowDiv = null;
ModalLayerDialog.prototype.CoveringFrame = null;
ModalLayerDialog.prototype.ResourceCounter = 0;
ModalLayerDialog.prototype.OrgWindowResize = null;
ModalLayerDialog.prototype.OrgWindowScroll = null;
ModalLayerDialog.prototype.OrgDocumentSelectStart = null;
ModalLayerDialog.prototype.OrgDocumentMouseMove = null;
ModalLayerDialog.prototype.OrgDocumentMouseUp = null;
ModalLayerDialog.prototype.InitialMousePos = null;
ModalLayerDialog.prototype.InitialDialogPos = null;
ModalLayerDialog.prototype.Dragging = false;

ModalLayerDialog.prototype.GetClientResolution = function()
{
	var res = { width : 800, height : 600 };

	if (window.innerWidth) // Non-IE
	{
		res.width = window.innerWidth;
		res.height = window.innerHeight;
	}
	else if (document.documentElement && (document.documentElement.clientWidth > 0 || document.documentElement.clientHeight > 0)) // IE 6+ in compliant mode
	{
		res.width = document.documentElement.clientWidth;
		res.height = document.documentElement.clientHeight;
	}
	else if (document.body) // other IE
	{
		res.width = document.body.clientWidth;
		res.height = document.body.clientHeight;
	}
	
	return res;
}

ModalLayerDialog.prototype.GetPageSize = function()
{
	var size = { width : 0, height : 0 };

	if (window.innerWidth && window.scrollMaxX) // Firefox
	{
		size.width = window.innerWidth + window.scrollMaxX;
		size.height = window.innerHeight + window.scrollMaxY;
	}
	else if (document.body.scrollWidth) // all but Explorer Mac
	{
		size.width = document.body.scrollWidth;
		size.height = document.body.scrollHeight;
	}
	else // works in Explorer 6 Strict, Mozilla (not FF) and Safari
	{
		size.width = document.body.offsetWidth + document.body.offsetLeft;
		size.height = document.body.offsetHeight + document.body.offsetTop;
	}
	
	return size;
}

ModalLayerDialog.prototype.ResizeOverlay = function()
{
	var page = ModalLayerDialog.prototype.GetPageSize();

	ModalLayerDialog.prototype.OverlayDiv.style.top = "0px";
	ModalLayerDialog.prototype.OverlayDiv.style.left = "0px";
	ModalLayerDialog.prototype.OverlayDiv.style.width = page.width + "px";
	ModalLayerDialog.prototype.OverlayDiv.style.height = page.height + "px";

	if (ModalLayerDialog.prototype.CoveringFrame != null)
	{
		ModalLayerDialog.prototype.CoveringFrame.style.top = "0px";
		ModalLayerDialog.prototype.CoveringFrame.style.left = "0px";
		ModalLayerDialog.prototype.CoveringFrame.style.width = page.width + "px";
		ModalLayerDialog.prototype.CoveringFrame.style.height = page.height + "px";
	}
}

ModalLayerDialog.prototype.UpdateShadow = function(init)
{
	if (this.Dialog != null && this.NeedsShadow)
	{
		ModalLayerDialog.prototype.ShadowDiv.style.top = this.Dialog.offsetTop + 4 + "px";
		ModalLayerDialog.prototype.ShadowDiv.style.left = this.Dialog.offsetLeft + 4 + "px";
		if (init)
		{
			ModalLayerDialog.prototype.ShadowDiv.style.width = this.Dialog.offsetWidth + "px";
			ModalLayerDialog.prototype.ShadowDiv.style.height = this.Dialog.offsetHeight + "px";
		}
	}
}

ModalLayerDialog.prototype.SaveInputs = function(element)
{
	for (var child = element.firstChild; child != null; child = child.nextSibling)
	{
		if (child.tagName == "INPUT" && (child.type == "radio" || child.type == "checkbox"))
			child.oldValue = child.checked;
		else
			ModalLayerDialog.prototype.SaveInputs(child);
	}
}

ModalLayerDialog.prototype.RestoreInputs = function(element)
{
	for (var child = element.firstChild; child != null; child = child.nextSibling)
	{
		if (child.tagName == "INPUT" && (child.type == "radio" || child.type == "checkbox"))
			child.checked = child.oldValue;
		else
			ModalLayerDialog.prototype.RestoreInputs(child);
	}
}

ModalLayerDialog.prototype.Open = function(centerHorizontal, centerVertical, atPos)
{
	if (this.Dialog != null)
	{
		// css3-containers are added with PIE (css3pie.com) for html5 compatibility in older browsers, we need to move those containers too
		// We can't do this test in the contructor, as the containers are not yet created at that time
		if (this.CSS3Container == null && this.Dialog.previousSibling != null && this.Dialog.previousSibling.tagName == "css3-container")
			this.CSS3Container = this.Dialog.previousSibling;

		// adding an hidden div to hide dialog, this is faster then changing style.display for big dialogs
		if (this.HiddenDiv == null)
		{
			this.HiddenDiv = document.createElement("div");
			this.HiddenDiv.style.display = "none";
			var node = (this.CSS3Container != null) ? this.CSS3Container : this.Dialog;
			this.Dialog.parentNode.insertBefore(this.HiddenDiv, node);
		}
		// parent of dialog needs to be the same as OverlayDiv (and CoveringFrame) else the z-indexes wont work.
		// We can't do this at the construction as the page is not completely created at that time and it will crash the browser.
		if (this.Dialog.parentNode != document.body && this.Dialog.parentNode != null)
		{
			// Save radiobuttons and checkboxes (they don't survive the move of the dialog)
			ModalLayerDialog.prototype.SaveInputs(this.Dialog);
			if (this.CSS3Container != null)
				document.forms[0].appendChild(this.CSS3Container);
			document.forms[0].appendChild(this.Dialog);
			ModalLayerDialog.prototype.RestoreInputs(this.Dialog);
		}

		if (ModalLayerDialog.prototype.OverlayDiv == null)
		{
			var overlayDiv = document.createElement("div");
			overlayDiv.style.position = "absolute";
			overlayDiv.style.backgroundColor = "white";
			overlayDiv.style.display = "none";
			overlayDiv.style.opacity = 0.5;
			overlayDiv.style.filter = "alpha(opacity=50)";
			document.forms[0].appendChild(overlayDiv);
			ModalLayerDialog.prototype.OverlayDiv = overlayDiv;
			
			if (ModalLayerDialog.prototype.IsIFrameNeeded && ModalLayerDialog.prototype.CoveringFrame == null)
			{
				coveringFrame = document.createElement("iframe");
				coveringFrame.src = "blank.html";
				coveringFrame.scrolling = "no";
				coveringFrame.frameBorder = 0;
				coveringFrame.style.position = "absolute";
				coveringFrame.style.display = "none";
				coveringFrame.style.opacity = 0;
				coveringFrame.style.filter = "alpha(opacity=0)";
				document.forms[0].appendChild(coveringFrame);
				ModalLayerDialog.prototype.CoveringFrame = coveringFrame;
			}
		}
		
		if (ModalLayerDialog.prototype.ShadowDiv == null && this.NeedsShadow)
		{
			var shadowDiv = document.createElement("div");
			shadowDiv.style.position = "absolute";
			shadowDiv.style.backgroundColor = "gray";
			overlayDiv.style.display = "none";
			shadowDiv.style.opacity = 0.3;
			shadowDiv.style.filter = "alpha(opacity=30)";
			document.forms[0].appendChild(shadowDiv);
			ModalLayerDialog.prototype.ShadowDiv = shadowDiv;
		}

		if (ModalLayerDialog.prototype.ResourceCounter == 0)
		{
			ModalLayerDialog.prototype.OrgWindowResize = window.onresize;
			ModalLayerDialog.prototype.OrgWindowScroll = window.onscroll;
			window.onresize = ModalLayerDialog.prototype.ResizeOverlay;
			window.onscroll = ModalLayerDialog.prototype.ResizeOverlay;
		}
		ModalLayerDialog.prototype.ResourceCounter++;

		if (this.Dialog.style.zIndex < 3)
		{
			this.Dialog.style.zIndex = 50;
			if (this.CSS3Container != null)
				this.CSS3Container.style.zIndex = this.Dialog.style.zIndex;
		}

		this.SaveShadowData(ModalLayerDialog.prototype.ShadowDiv);
		this.SaveOverlayData(ModalLayerDialog.prototype.OverlayDiv);
		var zIndex = this.Dialog.style.zIndex - 1;

		if (this.NeedsShadow)
		{
			ModalLayerDialog.prototype.ShadowDiv.style.zIndex = zIndex;
			ModalLayerDialog.prototype.ShadowDiv.style.display = "block";
		}
		else if (ModalLayerDialog.prototype.ShadowDiv != null)
			ModalLayerDialog.prototype.ShadowDiv.style.display = "none";
		ModalLayerDialog.prototype.OverlayDiv.style.zIndex = zIndex - 1;
		ModalLayerDialog.prototype.OverlayDiv.style.display = "block";
		if (ModalLayerDialog.prototype.CoveringFrame != null)
		{
			ModalLayerDialog.prototype.CoveringFrame.style.zIndex = zIndex - 2;
			ModalLayerDialog.prototype.CoveringFrame.style.display = "block";
		}

		ModalLayerDialog.prototype.ResizeOverlay()

		if (this.Dialog.style.display == "none")
			this.Dialog.style.display = "block";

		if (!(atPos === undefined))
			this.DialogPos = atPos;
		else if (this.FirstOpen)
		{
			this.DialogPos.left = this.Dialog.offsetLeft;
			this.DialogPos.top = this.Dialog.offsetTop;
			if (centerHorizontal || centerVertical)
			{
				var res = ModalLayerDialog.prototype.GetClientResolution();
				if (centerHorizontal)
					this.DialogPos.left = Math.max(0, (res.width - this.Dialog.offsetWidth) / 2);
				if (centerVertical)
					this.DialogPos.top = Math.max(0, (res.height - this.Dialog.offsetHeight) / 2);
			}
			this.FirstOpen = false;
		}
		this.Dialog.style.left = document.body.scrollLeft + this.DialogPos.left + "px";
		this.Dialog.style.top = document.body.scrollTop + this.DialogPos.top + "px";
		this.UpdateShadow(true);

		if (this.Title != null)
			this.Title.onmousedown = this.m_DragFunctions[0];
		if (this.FocusElement != null)
			this.FocusElement.focus();
	}
}

ModalLayerDialog.prototype.Close = function()
{
	if (this.Dialog != null)
	{
		if (ModalLayerDialog.prototype.ResourceCounter > 0)
		{
			ModalLayerDialog.prototype.ResourceCounter--;
			if (ModalLayerDialog.prototype.ResourceCounter == 0)
			{
				if (ModalLayerDialog.prototype.ShadowDiv != null)
					ModalLayerDialog.prototype.ShadowDiv.style.display = "none";

				ModalLayerDialog.prototype.OverlayDiv.style.display = "none";

				if (ModalLayerDialog.prototype.CoveringFrame != null)
					ModalLayerDialog.prototype.CoveringFrame.style.display = "none";

				window.onresize = ModalLayerDialog.prototype.OrgWindowResize;
				window.onscroll = ModalLayerDialog.prototype.OrgWindowScroll;
			}

			this.DialogPos.left = this.Dialog.offsetLeft - document.body.scrollLeft;
			this.DialogPos.top = this.Dialog.offsetTop - document.body.scrollTop;
			this.RestoreShadowData(ModalLayerDialog.prototype.ShadowDiv);
			this.RestoreOverlayData(ModalLayerDialog.prototype.OverlayDiv);

			if (ModalLayerDialog.prototype.CoveringFrame != null)
				ModalLayerDialog.prototype.CoveringFrame.style.zIndex = ModalLayerDialog.prototype.OverlayDiv.style.zIndex - 1;

			// restoring position
			if (this.HiddenDiv != null)
			{
				// Save radiobuttons and checkboxes (they don't survive the move of the dialog)
				ModalLayerDialog.prototype.SaveInputs(this.Dialog);
				if (this.CSS3Container != null)
					this.HiddenDiv.appendChild(this.CSS3Container);
				this.HiddenDiv.appendChild(this.Dialog);
				ModalLayerDialog.prototype.RestoreInputs(this.Dialog);
			}
			return true;
		}
	}
	return false;
}

ModalLayerDialog.prototype.ParseInt2 = function(val)
{
	var i = 0;
	if (val)
	{
		i = parseInt(val);
		if (isNaN(i))
			i = 0;
	}
	return i;
}

ModalLayerDialog.prototype.GetMouseCoords = function(evt)
{
	var coords = {x : 0, y : 0};
	if (evt)
	{
		coords.x = document.body.scrollLeft + evt.clientX;
		coords.y = document.body.scrollTop + evt.clientY;
	}
	return coords;
}

ModalLayerDialog.prototype.StartDrag = function(evt)
{
	evt = (evt) ? evt : ((window.event) ? window.event : null);

	if (evt != null && this.Dialog != null && !ModalLayerDialog.prototype.Dragging)
	{
		ModalLayerDialog.prototype.Dragging = true;

		ModalLayerDialog.prototype.InitialMousePos = this.GetMouseCoords(evt);
		ModalLayerDialog.prototype.InitialDialogPos = { x : this.ParseInt2(this.Dialog.style.left), y : this.ParseInt2(this.Dialog.style.top) };

		ModalLayerDialog.prototype.OrgDocumentMouseMove = document.onmousemove;
		ModalLayerDialog.prototype.OrgDocumentMouseUp = document.onmouseup;
		ModalLayerDialog.prototype.OrgDocumentSelectStart = document.onselectstart;

		document.onmousemove = this.m_DragFunctions[1];
		document.onmouseup = this.m_DragFunctions[2];
		// disable onselectstart to avoid scrolling the page while dragging the mouse cursor
		document.onselectstart = function() { return false; };
	}
	
	return false;
}

ModalLayerDialog.prototype.DragDialog = function(evt)
{
	evt = (evt) ? evt : ((window.event) ? window.event : null);

	if (evt != null && this.Dialog != null)
	{
		var mousePos = this.GetMouseCoords(evt);
		var res = ModalLayerDialog.prototype.GetClientResolution();

    var left = (ModalLayerDialog.prototype.InitialDialogPos.x + mousePos.x - ModalLayerDialog.prototype.InitialMousePos.x);
    var top = (ModalLayerDialog.prototype.InitialDialogPos.y + mousePos.y - ModalLayerDialog.prototype.InitialMousePos.y);

		left = Math.max(document.body.scrollLeft, Math.min(left, document.body.scrollLeft + res.width - this.Dialog.offsetWidth));
		top = Math.max(document.body.scrollTop, Math.min(top, document.body.scrollTop + res.height - this.Dialog.offsetHeight));

    this.Dialog.style.left = left + "px";
    this.Dialog.style.top = top + "px";
		this.UpdateShadow(false);
	}
	
	return false;
}

ModalLayerDialog.prototype.StopDrag = function(evt)
{
	document.onmousemove = ModalLayerDialog.prototype.OrgDocumentMouseMove;
	document.onmouseup = ModalLayerDialog.prototype.OrgDocumentMouseUp;
	document.onselectstart = ModalLayerDialog.prototype.OrgDocumentSelectStart;
	ModalLayerDialog.prototype.Dragging = false;
	return false;
}

ModalLayerDialog.prototype.OnResize = function()
{
	if (this.Dialog != null)
		this.UpdateShadow(true);
}

// Example of how to override this class
/*
// Derived class
DerivedDialog.prototype = new ModalLayerDialog();
DerivedDialog.prototype.constructor = DerivedDialog;

function DerivedDialog(modalDialogId, titelId)
{
	// Call base constructor
	ModalLayerDialog.call(this, modalDialogId, titelId);
	
	// Example of how to override the Open function
	this.Open = function()
	{
		// call base class function
		ModalLayerDialog.prototype.Open.call(this, true, false);
	}
}
*/
