function getRootPath(){
    var dLoc = document.location;
    var path = dLoc.pathname.toLowerCase();
    var root = dLoc.protocol + "//" + dLoc.hostname + "/";
    if ( path.indexOf ( "/carnival" ) == 0 ){
        root += "carnival/";
    }
    return root;
}

var root = getRootPath();

var imagesFolder = root + "images/";
var _popupManager = null;

/** IE specific **/

/**
* FUNCTION NAME:	CreateWindowsContainerIE
* RETURN TYPE:		void
*
* SUMMARY: 
*	Creates a table container to which pop-up DHTML will be added.
*	The created table container is then appended to the body content
*	of the implementing web page document.
*/
function CreateWindowsContainerIE(){
    var table = document.createElement("table"); 
    table.id="CarnivalWindowsContainer"; 
    document.body.appendChild(table)
}

/**
* FUNCTION NAME:	PopupDragStartIE
* RETURN TYPE:		void
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Initializes the popup object to prepare it for dragging. Initialization
*	include the x/y coordinates of the mouse within the popup titlebar relative
*	to the top left corner of the popup position.
*/
function PopupDragStartIE( popup ){
    popup.startX = popup.style.left;
    popup.startY = popup.style.top;
    popup.eventX = event.screenX;
    popup.eventY = event.screenY;

    event.srcElement.oldClick = event.srcElement.onClick;
    event.srcElement.popup = popup;
}

/**
* FUNCTION NAME:	MovePopupIE
* RETURN TYPE:		void
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	This function is triggered in the popup OnDrag event. Internally, it sets
*	the positions of the popup, the popup shadow, the popup resizable icon
*	relative to the event's x/y coordinates and the initial dragging position
*	relative to the popup's title bar (see PopupDragStartIE).
*/
function MovePopupIE( popup ){
    if ( popup.shadow == null ){
        popup.shadow = popup.parentNode.childNodes[2];
        popup.blanket = popup.parentNode.childNodes[0];
    }
    var x = parseInt( popup.style.left );
    var y = parseInt( popup.style.top );
    var maxWidth = ( document.body.clientWidth  + document.body.scrollLeft - parseInt( popup.style.width ) );
    var maxHeight = ( document.body.clientHeight  + document.body.scrollTop - parseInt( popup.style.height ) );
    x += ( event.screenX - popup.eventX );
    popup.eventX = event.screenX
//    if ( ( x < maxWidth ) && ( x > 0 ) ){
        popup.shadow.style.left = x;
        popup.style.left = x;
        popup.blanket.style.left = x;
//    }

    y += ( event.screenY - popup.eventY );
    popup.eventY = event.screenY;
//    if ( ( y < maxHeight ) && ( y > 0 ) ){
        popup.shadow.style.top = y;
        popup.style.top = y;
        popup.blanket.style.top = y;
//    }
    MoveResizableIconIE(popup);
}

function doSetCloseNormalPopupIE( iframe ){
	try{
		with ( document.frames[iframe.name] ){
			window.closeButton = iframe.parentNode.parentNode.parentNode.firstChild.getElementsByTagName("a")[0];
			window.close = ClickCloseButtonIE;
		}
	}
	catch(e){}
}

function ClickCloseButtonIE(){
	this.closeButton.click();
}

/**
* FUNCTION NAME:	WindowOpenIE
* RETURN TYPE:		void
*
* SUMMARY: 
*	This function is triggered when a call to the brower's window.open
*	is made. Internally, it creates the DHTML structure representation
*	of a window using the standard dialog arguments of the browser's
*	window.open method.
*/
function WindowOpenIE(){
    var openArgs = new WindowArguments ( arguments );
    
    var windowHeight = document.body.clientHeight;
    var windowWidth = document.body.clientWidth;
	var offsetX = document.body.scrollLeft;
	var offsetY = document.body.scrollTop;
    
    var table = document.createElement("table");
    with ( table ){
        setAttribute( "cellpadding", "0" );
        setAttribute( "cellspacing", "0" );
        setAttribute( "ondragstart", "PopupDragStartIE( this )");
        setAttribute( "ondrag", "MovePopupIE( this )");
        
        with ( style ){
            borderStyle = "solid";
            borderWidth = "2px;"
            borderColor = "#92cced #03649C #03649C #92cced";
            width = parseInt(openArgs.width);
            height = parseInt(openArgs.height);
            padding = "0px";
            position = "absolute";
            zIndex = 1000;
            
            if ((openArgs.top == "px") || (openArgs.top == "")){
				openArgs.top = 100;
            }            
            
            if ( openArgs.top == "CENTER" ){
				top = parseInt(( windowHeight - parseInt(openArgs.height) )/2) + offsetY
            }
            else{
				top = parseInt(openArgs.top) + offsetY;
            }
            
            if ((openArgs.left == "px") || (openArgs.left == "")){
				openArgs.left = 100;
            } 
            
            if ( openArgs.left == "CENTER" ){
				left = parseInt(( windowWidth - parseInt(openArgs.width) )/2) + offsetX
            }
            else{
				left = parseInt(openArgs.left) + offsetX;
            }
        }
    }
    tableShadow = GetShadowTableIE( table.style.width, table.style.height, table.style.top, table.style.left );
    
    // window title bar	    
    var tr = table.insertRow();
    tr.height=26;
    var tr2 = table.insertRow();
    
    // window content
    var td = tr.insertCell();
    var td2 = tr2.insertCell();
    with ( td ){
        colspan = 2;
        
        with ( style ){
            color = "#FFFFFF";
            textAlign = "right";
            verticalAlign = "top"
            fontFamily = "arial";
            fontSize = "12px";
            fontWeight = "800";
            backgroundColor = "#0486d0";
            borderStyle = "solid";
            borderWidth = 
            padding = "0";
        }
        appendChild ( getTopBarContentNodeIE() );
    }

	//
	// Workaround:	IE DOM model treats the IFrame element, and the IFrame frame as two separate object types.
	//				This workaround will mark the iframe reference with a "name" flag using the current time
	//				in milliseconds, then will retrieve the IFrame frame reference using the name attribute
	// ** BEGIN SECTION WORKAROUND **
	var nameFlag = "";
	do{
		nameFlag = "frame" + new Date().valueOf();
	}
	while ( document.frames[ nameFlag ] ); // create a new name if a frame with same name exists (chances slim to none)
    var iframe = document.createElement("<iframe class='popupFrame' name='"+nameFlag+"' onload='doSetCloseNormalPopupIE(this)'></iframe>");
	// ** END SECTION WORKAROUND
	
    with ( iframe ){
        setAttribute( "width", "100%" );
		var urlToLoad = ( openArgs.url == "" )? root + "BlankPage.htm" : GetAbsolutePath ( openArgs.url );
		setAttribute( "src", urlToLoad );
        setAttribute( "height", "100%" );
        setAttribute( "frameborder", "none" );
        with ( style ){
            position = "absolute";
            borderStyle = "solid";
            borderColor = "#0486d0";
            borderWidth = "0 0 12 0"
        }
    }

    //
    //	This section is a work-around to address
    //	IE bug with windowed items (select boxes, activeX, etc.)
    //	being generated on a separate layer dimension
    //	more documentation can be found at:
    //	http://support.microsoft.com/default.aspx?scid=kb;en-us;177378
    // ** BEGIN SECTION WORKAROUND **
    var blanket = document.createElement( "iframe" ); // use an iframe as a blanket to cover windowed items
    with ( blanket ){
		setAttribute ( "frameborder", "0" );
		setAttribute ( "src", root + "blankpage.htm" );
		with ( style ){
			zIndex = 1000;
			position = "absolute";
            top = table.style.top;
            left = table.style.left;
            width = table.style.width;
            height = table.style.height;
		}
    }
    // the blanket will be added to the WindowContainer row at the end of the function
    // ** END SECTION WORKAROUND **


    td2.appendChild ( iframe );
    tr2.setAttribute("height", "100%");

    var windowContainer = document.getElementById("CarnivalWindowsContainer");
    var trow = windowContainer.insertRow();
    var tcell = trow.insertCell();
    tcell.innerHTML = blanket.outerHTML + tableShadow.outerHTML + table.outerHTML + GetResizableIconIE(table).outerHTML;
    return tcell
}

/**
* FUNCTION NAME:	getTopBarContentNodeIE
* RETURN TYPE:		HTMLTableNode
*
* SUMMARY: 
*	This function creates a table containing the structure
*	of the popup title bar, including close icon, Carnival logo
*	and a transparent image created as a workaround to bubble
*	the window's OnDrag event.
*/
function getTopBarContentNodeIE() {
	var table = document.createElement ( "table" );
	with ( table ){
		setAttribute("cellpadding","0");
		setAttribute("cellspacing","0");
		with ( style ){
			padding = "0";
			width = "100%";
			height = "100%";
			borderStyle = "none";
            backgroundImage="url('"+imagesFolder+"carnivallogo.gif')";
            backgroundRepeat="no-repeat";
		}
	}
    // Create an image to triggar a bubbling of the ondrag event
	var dragBubbleImage = new Image();
	with ( dragBubbleImage ){
		title = "move"
		src = imagesFolder + "empty_pixel.gif";
		with ( style ){
			width = "100%";
			height = "100%";
		}
	}

	var tr = table.insertRow();
	var td = tr.insertCell();
	with ( td ){
		td.width="100%";
		td.appendChild ( dragBubbleImage );
	}

	var td2 = tr.insertCell();
    var a = document.createElement ( "a" );
	with ( td2 ){
		appendChild ( a );
		with ( td2.style ){
			whiteSpace = "nowrap"
		}
	}

    var img = new Image();
    with ( img ){
        src = imagesFolder + "close_blue.gif";
        with ( style ){
            borderStyle = "none";
        }
    }
    a.onClick = "ClosePopupIE(this)";
    a.href = "JavaScript:;";
    a.onMouseover = "this.style.cursor='hand'";
    with ( a ){
		title = "close window"
        with ( a.style ){
            textDecoration = "none";
            color = "#FFFFFF";
            fontSize = "12px";
            fontWeight = "800"
        }
        appendChild ( img );
    }
	return table;
}


/**
* FUNCTION NAME:	ClosePopupIE
* RETURN TYPE:		void
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Triggered by the OnClick event of the titlebar's "close" link,
*	this function simulates the closing of a popup by referencing the 
*	row in which it resides, under the table element marked with the
*	CarnivalWindowsContainer ID, and removing it.
*/
function ClosePopupIE(popup){
	if ( document.body.shuffler != null ){
		with ( document.body ){
			shuffler.focus();
			removeChild ( shuffler );
			shuffler = null;
		}
	}
    var popRow = popup.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
    popRow.parentNode.removeChild(popRow);
    if ( document.body.firstChild.nodeName.toLowerCase() == "iframe" ){
		document.body.removeChild( document.body.firstChild );
    }
}

/**
* FUNCTION NAME:	MoveResizableIconIE
* RETURN TYPE:		void
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Moves the resize icon, located at the bottom right corner of the popup
*	to position it relative to the rest of the popup
*/
function MoveResizableIconIE ( popup ){
    if ( popup.ResizableIcon == null ){
        popup.ResizableIcon = popup.parentNode.childNodes[4];
    }
    with ( popup.ResizableIcon.style ){
        left = parseInt(popup.style.left) + parseInt(popup.style.width) - 13;
        top = parseInt(popup.style.top) + parseInt(popup.style.height) - 13;
    }
}

/**
* FUNCTION NAME:	ResizeTableIE
* RETURN TYPE:		void
* ARGUMENTS		
*	resizer:		The resizer icon node
*
* SUMMARY: 
*	Moves the resize icon, located at the bottom right corner of the popup
*	to position it relative to the rest of the popup
*/
function ResizeTableIE ( resizer ){
    if ( resizer.popupShadow == null ){
        resizer.popupShadow = resizer.parentNode.childNodes[2];
        resizer.popup = resizer.parentNode.childNodes[3];
        resizer.blanket = resizer.parentNode.childNodes[0];
    }
    
    var isResizableX = ((event.screenX + document.body.scrollLeft - parseInt(resizer.popup.style.left) - 52) > 0);
    var isResizableY = ((event.screenY + document.body.scrollTop - parseInt(resizer.popup.style.top) - 140) > 0);
    
    with ( resizer ){
        with ( style ){
            if ( isResizableX ){
				left = event.screenX + document.body.scrollLeft;
            }
			if ( isResizableY ){
				top = event.screenY - 110 + document.body.scrollTop;
            }
        }
        with ( resizer.popupShadow.style ){ //shadow
			if ( isResizableX ){
				width = event.screenX + document.body.scrollLeft - parseInt(left) + 5;
			}
            if ( isResizableY ){
				height = event.screenY + document.body.scrollTop - parseInt(top) -103;
			}
        }
        with ( resizer.popup.style ){ //popup
			if ( isResizableX ){
				width = event.screenX + document.body.scrollLeft - parseInt(left) + 13;
			}
            if ( isResizableY ){
				height = event.screenY + document.body.scrollTop - parseInt(top) - 97;
			}
        }
        with ( resizer.blanket.style ){ //blanket
			if ( isResizableX ){
				width = event.screenX  + document.body.scrollLeft - parseInt(left) + 13;
			}
            if ( isResizableY ){
				height = event.screenY + document.body.scrollTop - parseInt(top) - 97;
			}
        }
    }
}

/**
* FUNCTION NAME:	GetShadowTableIE
* RETURN TYPE:		HTMLTableNode
* ARGUMENTS		
*	w:		The width of the box shadow to be created
*	h:		The height of the box shadow to be created
*	t:		The topmost position of the box shadow to be created
*	l:		The leftmost position of the box shadow to be created
*
* SUMMARY: 
*	Creates a shadow representation for a table of the dimensions 
*	specified by the argument values, and renders it into a shadow
*	using Microsoft Transition filters.
*/
function GetShadowTableIE( w, h, t, l ){
    var shadow = document.createElement( "table" );
    with ( shadow ){
		setAttribute( "cellpadding", "0" );
		setAttribute( "cellspacing", "0" );
        with ( style ){
            position = "absolute";
            width = parseInt(w)-8;
            height = parseInt(h)-8;
            top = t;
            left = l;
            zIndex = 1000;
        }
    }
    var tr = document.createElement("tr");
    var td = document.createElement("td");
    
    
    shadow.style.backgroundColor="#223344";
    shadow.style.filter=" \
        progid:DXImageTransform.Microsoft.dropshadow(OffX=0, OffY=0, Color='#FFFFFF', Positive='false') \
        progid:DXImageTransform.Microsoft.Blur(pixelradius=8) \
        progid:DXImageTransform.Microsoft.Wheel(duration=30)";
    tr.appendChild( td );
    shadow.appendChild ( tr );
    return shadow;
}

/**
* FUNCTION NAME:	GetResizableIconIE
* RETURN TYPE:		HTMLImageNode
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Creates and returns the popup's resize icon, 
*	positioned relative to the containing popup
*/
function GetResizableIconIE( popup ){
    var img = new Image();
    img.onMouseover = "this.style.cursor='nw-resize'"
    img.onDrag = "ResizeTableIE( this )";
    with ( img ){
        src=imagesFolder + "resizable.gif";
        with ( style ){
            position = "absolute";
            left = parseInt(popup.style.left) + parseInt(popup.style.width) - 13;
            top = parseInt(popup.style.top) + parseInt(popup.style.height) - 13;
            zIndex=1000;
        }
    }
    return img;
}

/**
* FUNCTION NAME:	ShowModalIE
* RETURN TYPE:		void
*
* ARGUMENTS
*	Standard window.showModalDialog arguments are accepted,
*	however, for those cases in which script execution is required
*	after the dialog window has closed, i.e., to populate fields based
*	on values supplied in the dialog window, a fourth argument can be used
*	as the OnPostClose event, where the name of a one argument function 
*	can be supplied. The argument supplied to the function will be the object 
*	passed to the dialog as the dialogArguments as follows:
*
*	function OnDialogClose ( dialogArguments ){
*		txtName.value = dialogArguments.name;
*	}
*
* SUMMARY: 
*	Opens a pop-up and performs DOM operations necessary
*	to make it simulate a modal window, and pass references
*	via the dialogArguments. Additionally, window can be closed
*	by a script in the page contained within the pop-up
*/
function ShowModalIE(){
	var strFeatures = "";
	if ( arguments.length > 1 ){
		strFeatures = GetModalToPopupFeaturesConversion ( arguments[2].toString() );
	}

	// empty url to insure page gets loaded after onload event has been assigned
	var popupCell = window.open ( "", "", strFeatures ); 
	var popupFrame = popupCell.childNodes[3].rows[1].cells[0].firstChild;

	// assign onload event
	if ( arguments.length > 0 ){
		//
		// Workaround: IE doesn't allow dynamic assignment of the OnLoad attribute
		// Instead, the IFrame will be retrieved as an HTML string
		// and the OnLoad event will be inserted in the string
		// ** BEGIN WORKAROUND **
		var iframeHTML = popupFrame.outerHTML;
		iframeHTML = iframeHTML.replace (" ", " onload='SetDialogReferencesIE(this)' ");
		var newFrame = document.createElement ( iframeHTML );
		newFrame.src= GetAbsolutePath(arguments[0]);

		popupFrame.parentNode.replaceChild( newFrame, popupFrame );

		popupFrame = newFrame;
		//popupFrame.frame = document.frames[document.frames.length-1]

		popupCell.parentNode.setAttribute("id", "CurrentModalDialog");

		document.body.lastFrame = document.frames[document.frames.length-1]
		document.body.lastFrameDialogArguments = arguments[1];
		// ** END WORKAROUND **
	}
	
	if ( arguments.length > 3 ){
		// assign the OnPostClose event;
		popupCell.parentNode.OnPostClose = arguments[3];
	}
	var blocker = document.createElement ("iframe")
	var documentHeight = document.body.offsetHeight + document.body.scrollTop + document.body.clientHeight;
	var documentWidth = document.body.offsetLeft + document.body.scrollLeft + document.body.clientWidth;
	with ( blocker ){
		src= root + "blankpage.htm";
		with ( style ){
			width=documentWidth;
			height=documentHeight;
			zIndex=300;
			position="absolute"
			top=0;
			left=0;
			filter="progid:DXImageTransform.Microsoft.Alpha(opacity=40)";
		}
	}
	document.body.insertBefore ( blocker, document.body.firstChild );
	document.body.blocker = blocker;
}

function OnWindowResize(){
    if ( document.body.blocker ){
	    var documentHeight = document.body.offsetHeight + document.body.scrollTop + document.body.clientHeight;
	    var documentWidth = document.body.offsetLeft + document.body.scrollLeft + document.body.clientWidth;
		with ( document.body.blocker.style ){
			width=documentWidth;
			height=documentHeight;
		}
    }
}

/**
* FUNCTION NAME:	SetDialogReferencesIE
* RETURN TYPE:		void
* ARGUMENTS
*	contentFrame:	the iframe element reference
*
* SUMMARY: 
*	Sets the dialogArguments property of the window contained
*	in the pop-up's content frame, and assigned a reference to
*	the OnClose event handler
*/
function SetDialogReferencesIE( contentFrame ){
	try{
		document.body.lastFrame.window.close=CloseDialogIE;
	}
	catch (e){
		var ex = e.toString();
	}
	try{
		document.body.lastFrame.window.dialogArguments=document.body.lastFrameDialogArguments;
	}
	catch (e){
		var ex = e.toString();
	}
	var t,l;
	try{
		with ( document.getElementById(document.body.lastFrame.name).parentNode.parentNode.parentNode.parentNode.style ){
			t = top;
			l = left;
		}
		var shuffler = null;
		if ( document.body.shuffler != null ){
			shuffler = document.body.shuffler
		}
		else{
			shuffler = document.createElement ("<input style='position: absolute; height: 1px; width 1px; border-style: none;z-index:0; padding:0px;'></input>")
			document.body.appendChild( shuffler );
			document.body.shuffler = shuffler;
		}
		with ( shuffler.style ){
			top = t;
			left = l;
		}
	}
	catch(e){
	}
}

/**
* FUNCTION NAME:	CloseDialogIE
* RETURN TYPE:		void
* SUMMARY: 
*	Performs the necessary DOM operations to
*	simulate the closing of the pop-up window
*/
function CloseDialogIE(){
	//
	// WORKAROUND:	A bug in IE causes the Blocker frame to prevent access
	//				to any window form text input controls, even though the blocker 
	//				frame has been removed. This only occurs when a blank space on 
	//				the popup frame document has been clicked on. This is documented
	//				in Clearcase ISSDM00057416. During bug reproduction, it was noted
	//				that the user could override text input blockage by tabbing to any
	//				input control, thus, script was introduced 
	//				forcing the selection of a "shuffler" input control.
	//
	//** BEGIN WORKAROUND **
	if ( document.body.shuffler != null ){
		with ( document.body ){
			shuffler.focus();
			removeChild ( shuffler );
			shuffler = null;
		}
	}
	//** END WORKAROUND **
	if ( document.body.firstChild.nodeName.toUpperCase() == "IFRAME" ){
		document.body.removeChild(document.body.firstChild);
	}
	var containerRow = this.parent.document.getElementById("CurrentModalDialog");
	if ( containerRow != null ){
		containerRow.parentNode.removeChild ( containerRow );
		if ( containerRow.OnPostClose != null ){
			containerRow.OnPostClose( this.dialogArguments );
		}
	}
}

/** Mozilla specific **/

/**
* FUNCTION NAME:	CreateWindowsContainerIE
* RETURN TYPE:		void
*
* SUMMARY: 
*	Creates a table container to which pop-up DHTML will be added.
*	The created table container is then appended to the body content
*	of the implementing web page document.
*/
function CreateWindowsContainerMO(){
    var table = document.createElement("table"); 
    table.id="CarnivalWindowsContainer"; 
    document.body.appendChild(table)
}

/**
* FUNCTION NAME:	PopupDragStartMO
* RETURN TYPE:		void
* ARGUMENTS		
*	event:			The triggerring event
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Initializes the popup object to prepare it for dragging. Initialization
*	include the x/y coordinates of the mouse within the popup titlebar relative
*	to the top left corner of the popup position.
*
*	Additionally, as a workaround to the lack of an OnDrag event in Mozilla's DOM,
*	events are set for OnMouseMove and OnMouseUp, to simulate the OnDrag event.
*/
function PopupDragStartMO( event, popup ){
    popup.startX = popup.style.left;
    popup.startY = popup.style.top;
    popup.eventX = event.clientX;
    popup.eventY = event.clientY;

    popup.setAttribute("onmousemove", "MovePopupMO(event, this)");
    document.body.popup = popup;
    document.body.setAttribute ("onmousemove", "MovePopupMO(event, document.body.popup)");
}

/**
* FUNCTION NAME:	PopupDragStartMO
* RETURN TYPE:		void
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	This function is called when the popup OnMouseUp event is triggered,
*	after dragging has occurred. Internally it resets all the values
*	and events set when the dragging was initiated.
*/
function CancelPopupDrag( popup ){
	popup.setAttribute("onmousemove", "");
	document.body.setAttribute("onmousemove", "");
    document.body.popup.content.style.visibility="visible";
	document.body.popup = null;
}

/**
* FUNCTION NAME:	MovePopupMO
* RETURN TYPE:		void
* ARGUMENTS		
*	event:			The triggerring event.
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	This function is triggered in the popup OnMouseMove event. Internally, it sets
*	the positions of the popup, the popup shadow, the popup resizable icon
*	relative to the event's x/y coordinates and the initial dragging position
*	relative to the popup's title bar (see PopupDragStartMO).
*/
function MovePopupMO( event, popup ){
	popup.content.style.visibility="hidden";
    popup.shadow = popup.parentNode.childNodes[0];
    var x = parseInt( popup.style.left );
    var y = parseInt( popup.style.top );
    var maxWidth = ( document.body.clientWidth - parseInt( popup.style.width ) );
    var maxHeight = ( document.body.clientHeight - parseInt( popup.style.height ) );
    x += ( event.clientX - popup.eventX );
    popup.eventX = event.clientX

    if ( ( x < maxWidth ) && ( x > 0 ) ){
        popup.shadow.style.left = x;
        popup.style.left = x;
    }

    y += ( event.clientY - popup.eventY );
    popup.eventY = event.clientY;
    if ( ( y < maxHeight ) && ( y > 0 ) ){
        popup.shadow.style.top = y;
        popup.style.top = y;
    }
    MoveResizableIconMO(popup);
}

/**
* FUNCTION NAME:	doSetCloseNormalPopupMO
* RETURN TYPE:		void
*
* SUMMARY: 
*	Sets the functionality required to allow closing of normal popups
*	from scripts contained within the page contained by the popup.
*	This is achieved by passing references to the desired functions
*	to be invoked, and setting them as spoofed windows methods.
*/
function doSetCloseNormalPopupMO( iframe ){
	try{
		frames[iframe.name].window.closeButton = iframe.closeButton;
		frames[iframe.name].window.close = doCloseNormalPopupMO;
	}
	catch ( e ){
	}
}

/**
* FUNCTION NAME:	doCloseNormalPopupMO
* RETURN TYPE:		void
*
* SUMMARY: 
*	Invokes the close function on the popups close button
*/
function doCloseNormalPopupMO(){
	ClosePopupMO(this.closeButton)
}

/**
* FUNCTION NAME:	WindowOpenMO
* RETURN TYPE:		void
*
* SUMMARY: 
*	This function is triggered when a call to the brower's window.open
*	is made. Internally, it creates the DHTML structure representation
*	of a window using the standard dialog arguments of the browser's
*	window.open method.
*/
function WindowOpenMO(){
    var openArgs = new WindowArguments ( arguments );
    var windowHeight = document.body.clientHeight;
    var windowWidth = document.body.clientWidth;
	var offsetX = document.body.scrollLeft;
	var offsetY = document.body.scrollTop;

    var table = document.createElement("table");
    with ( table ){
        cellPadding = 0;
        cellSpacing = 0;
        setAttribute( "onmousedown", "PopupDragStartMO( event, this )");
        setAttribute( "onmouseup", "CancelPopupDrag( this )");
        
        with ( style ){
            borderStyle = "solid";
            borderWidth = "2px;"
            borderColor = "#92cced #03649C #03649C #92cced";
            width = openArgs.width;
            height = openArgs.height;
            padding = "0px";
            position = "absolute";
            zIndex = 1000;
            if ( openArgs.top == "CENTER" ){
				top = (parseInt( windowHeight) - parseInt(openArgs.height))/2 + offsetY
				
            }
            else{
				top = openArgs.top + offsetY;
            }
            
            if ( openArgs.left == "CENTER" ){
				left = (parseInt( windowWidth )- parseInt( openArgs.width ))/2 + offsetX
            }
            else{
				left = openArgs.left + offsetX;
            }
        }
    }
    tableShadow = GetShadowTableMO( table.style.width, table.style.height, table.style.top, table.style.left );
    
    // window title bar	    
    var tr = table.insertRow(0);
    var tr2 = table.insertRow(1);
    
    // window content
    var td = tr.insertCell(0);
    var td2 = tr2.insertCell(0);
    td2.style.backgroundColor = "#FFFFFF";

    var a = document.createElement ( "a" );
    var img = document.createElement ( "img" );
    with ( img ){
        src = imagesFolder + "close_blue.gif";
        with ( style ){
			borderStyle = "none";
            borderColor = "#FFFFFF";
            borderWidth = "1px";
        }
    }
    a.setAttribute("onclick", "ClosePopupMO(this)");
    a.href = "JavaScript:;";
    a.onMouseover = "this.style.cursor='hand'";
    with ( a ){
        appendChild ( img );
        with ( style ){
            textDecoration = "none";
            color = "#FFFFFF";
            width = "100%";
        }
    }

    with ( td ){
        colspan = 2;
        appendChild ( a );
        with ( style ){
            backgroundImage="url('" + imagesFolder + "carnivallogo.gif')";
            backgroundRepeat="no-repeat";
			height="26"
            color = "#FFFFFF";
            textAlign = "right";
            verticalAlign = "middle"
            fontFamily = "arial";
            fontSize = "12px";
            fontWeight = "800";
            backgroundColor = "#0486d0";
            padding = "0";
        }
        setAttribute("onmouseover", "this.style.cursor='hand'");
    }
    tr2.setAttribute("height", "100%");

    var windowContainer = document.getElementById("CarnivalWindowsContainer");
    var trow = windowContainer.insertRow(windowContainer.rows.length);
    var tcell = trow.insertCell(0);

    tcell.appendChild(tableShadow)
    tcell.appendChild(table)
    var iframe = document.createElement("iframe");
	var nameFlag = "";
	/**
	* Workaround:	Mozilla's DOM model treats the IFrame element, and the IFrame frame as two separate object types.
	*				This workaround will mark the iframe reference with a "name" flag using the current time
	*				in milliseconds, then will retrieve the IFrame frame reference using the name attribute
	*/
	do{
		nameFlag = "frame" + new Date().valueOf();
	}
	while ( frames[ nameFlag ] != null ); // create a new name if a frame with same name exists (chances slim to none)
    
	iframe.closeButton = a;
    with ( iframe ){
		setAttribute( "name", nameFlag );
		setAttribute( "onload", "doSetCloseNormalPopupMO(this)" );
        setAttribute( "width", td2.clientWidth );
		setAttribute( "src", openArgs.url );
        setAttribute( "height", td2.clientHeight );
        setAttribute( "frameborder", "none" );
        style.backgroundColor="#FFFFFF";
        with ( style ){
            borderStyle = "solid";
            borderColor = "#0486d0";
            borderWidth = "0 0 12 0"
            zIndex="1000"
        }
    }
    td2.appendChild ( iframe );
    tcell.appendChild(GetResizableIconMO(table));
    table.content = iframe;
    this.popup = table;
    this.shadow = tableShadow;
    this.iframe = iframe;
    return tcell;
}

/**
* FUNCTION NAME:	ClosePopupMO
* RETURN TYPE:		void
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Triggered by the OnClick event of the titlebar's "close" link,
*	this function simulates the closing of a popup by referencing the 
*	row in which it resides, under the table element marked with the
*	CarnivalWindowsContainer ID, and removing it.
*/ 
function ClosePopupMO(popup){
    var popRow = popup.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
    popRow.parentNode.removeChild(popRow);
    if ( document.body.blocker != null ){
		document.body.removeChild( document.body.blocker );
		document.body.blocker = null;
    }
}

/**
* FUNCTION NAME:	MoveResizableIconMO
* RETURN TYPE:		void
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Moves the resize icon, located at the bottom right corner of the popup
*	to position it relative to the rest of the popup
*/
function MoveResizableIconMO ( popup ){
    with ( popup.parentNode.childNodes[2].style ){
        left = parseInt(popup.style.left) + parseInt(popup.style.width) - 13;
        top = parseInt(popup.style.top) + parseInt(popup.style.height) -3;
    }
}

/**
* FUNCTION NAME:	ResizeTableMO
* RETURN TYPE:		void
* ARGUMENTS		
*	resizer:		The resizer icon node
*
* SUMMARY: 
*	Moves the resize icon, located at the bottom right corner of the popup
*	to position it relative to the rest of the popup
*/
function ResizeTableMO ( event ){
    var resizer = document.body.resizer;
    var w, h;
    with ( resizer ){
		var isResizableX = ( (event.clientX - parseInt(parentNode.childNodes[0].style.left)-52) > 0);
		var isResizableY = ( (event.clientY - parseInt(parentNode.childNodes[0].style.top) - 40) > 0);

        with ( style ){	// resizer icon
			if ( isResizableX ){
	            left = event.clientX;
			}        
            if ( isResizableY ){
				top = event.clientY - 7;
			}
        }
        with ( parentNode.childNodes[0].style ){ // shadow
			if ( isResizableX ){
				w = event.clientX - parseInt(left) + 13// - 319;
				width = w+14;
			}
			if ( isResizableY ){
				h = event.clientY - parseInt(top) + 13 - 16;
				height = h+22;
			}
        }
        with ( parentNode.childNodes[1].style ){ // td
			if ( isResizableX ){
				width = w;
			}
			if ( isResizableY ){
				height = h;
            }
        }
        document.body.hiddenFrameContent = parentNode.childNodes[1].rows[1].cells[0].childNodes[0]; // frame
        with ( document.body.hiddenFrameContent ){ 
			style.visibility="hidden";
			if ( isResizableX ){
				setAttribute("width",w-4);
            }
            if ( isResizableY ){
				setAttribute("height",h-34);
            }
        }
    }
}

/**
* FUNCTION NAME:	GetShadowTableMO
* RETURN TYPE:		HTMLTableNode
* ARGUMENTS		
*	w:		The width of the box shadow to be created
*	h:		The height of the box shadow to be created
*	t:		The topmost position of the box shadow to be created
*	l:		The leftmost position of the box shadow to be created
*
* SUMMARY: 
*	Creates a shadow representation for a table of the dimensions 
*	specified by the argument values, and renders a surrounding shadow
*	using PNG images and Mozilla native alpha blending.
*/
function GetShadowTableMO( w, h, t, l ){
    var shadow = document.createElement( "table" );
    var img;
    
	with ( shadow ){
		setAttribute("cellpadding", "0");
		setAttribute("cellspacing", "0");
		with ( style ){
			zIndex = 1000;
			position = "absolute";
			top = parseInt(t);
			left = parseInt(l);
			width = parseInt(w) + 14;
			height = parseInt(h) + 24;
		}

		var tr1 = insertRow(0);
		var tr2 = insertRow(1);
		var tr3 = insertRow(2);

		tr1.height = 14;
		tr2.setAttribute("height", "100%")
		tr3.height = 14;
		
		var td11 = tr1.insertCell(0);
		with ( td11 ){
			style.backgroundColor="#FFFFFF";
			setAttribute("rowspan", 2);
			setAttribute("colspan", 2);
		}
		
		var td12 = tr1.insertCell(1);
		with ( td12 ){
			width=14;
			img = new Image();
			with ( img ){
				src=imagesFolder + "top_right_shadow.png";
			}
			appendChild ( img );
		}
		
		var td21 = tr2.insertCell(0);
		with ( td21 ){
			img = new Image();
			with ( img ){
				src=imagesFolder + "right_shadow.png";
				setAttribute("height", "100%");
				setAttribute("width", "14");
			}
			appendChild ( img );
		}
		
		var td31 = tr3.insertCell(0);
		with ( td31 ){
			width = "14";
			img = new Image();
			with ( img ){
				src=imagesFolder + "bottom_left_shadow.png";
			}
			td31.appendChild ( img );
		}
		
		var td32 = tr3.insertCell(1);
		with ( td32 ){
			setAttribute("width", "100%");
			img = new Image();
			with ( img ){
				setAttribute("height", "14");
				setAttribute("width", "100%");
				src=imagesFolder + "bottom_shadow.png";
			}
			appendChild( img );
		}
		var td33 = tr3.insertCell(2);
		with ( td33 ){
			width="14";
			img = new Image();
			with ( img ){
				src = imagesFolder + "bottom_right_shadow.png";
			}
			appendChild ( img );
		}
	}
    return shadow;
}

/**
* FUNCTION NAME:	SetMouseMove
* RETURN TYPE:		void
* ARGUMENTS		
*	event:		The triggerring event
*	img:		The image to which the event will be set.
*
* SUMMARY: 
*	Sets the MouseMove event for the HTMLImageNode, to allow it to be
*	resized. When the MouseUp event is triggered, the CancelResizeTableMO
*	function is called, unsetting this event.
*/
function SetMouseMove(event, img){
    event.img = img;
    document.body.setAttribute("onmousemove","ResizeTableMO(event)");
    img.setAttribute("onmousemove","ResizeTableMO(event)");
    document.body.resizer=img;
    document.body.setAttribute("onmouseup", "CancelResizeTableMO(event)");
}

/**
* FUNCTION NAME:	CancelResizeTableMO
* RETURN TYPE:		void
* ARGUMENTS		
*	event:		The triggerring event
*
* SUMMARY: 
*	Cancels the MouseMove event, thus completing the OnDrag event simulation
*	for Mozilla based browsers.
*/
function CancelResizeTableMO(event){
	if (document.body.hiddenFrameContent != null ){
		document.body.hiddenFrameContent.style.visibility = "visible";
		document.body.hiddenFrameContent = null;
	}
    document.body.setAttribute("onmousemove", "");
    document.body.resizer.setAttribute("onmousemove","");
    document.body.resizer = null;
}

/**
* FUNCTION NAME:	GetResizableIconMO
* RETURN TYPE:		HTMLImageNode
* ARGUMENTS		
*	popup:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Creates and returns the popup's resize icon, 
*	positioned relative to the containing popup
*/
function GetResizableIconMO( table ){
    var img = document.createElement("img");
    img.setAttribute("onmouseover", "this.style.cursor='nw-resize'")
    img.setAttribute("onmousedown", "SetMouseMove(event, this)");

    with ( img ){
        src=imagesFolder + "resizable.gif";
        with ( style ){
            position = "absolute";
            left = parseInt(table.style.left) + parseInt(table.style.width) - 13;
            top = parseInt(table.style.top) + parseInt(table.style.height);
            zIndex=1000;
        }
    }
    return img;
}

/**
* FUNCTION NAME:	CloseDialogMO
* RETURN TYPE:		void
* SUMMARY: 
*	Performs necessary DOM operations to simulate
*	the closing of the pop-up window
*/
function CloseDialogMO(){
	var containerRow = this.parent.document.getElementById("CurrentModalDialog");
	var containerContent = this.parent.document.getElementById("CurrentModalDialogContent");
	document.body.removeChild(document.getElementById("ModalBlanket"));
	containerRow.parentNode.removeChild ( containerRow );
	if ( containerRow.OnPostClose != null ){
		containerRow.OnPostClose( this.dialogArguments );
	}
}


/**
* FUNCTION NAME:	ShowModalMO
* RETURN TYPE:		void
* SUMMARY: 
*	Opens a pop-up and performs DOM operations necessary
*	to make it simulate a modal window, and pass references
*	via the dialogArguments. Additionally, window can be closed
*	by a script in the page contained within the pop-up
*/
function ShowModalMO(){
	var blocker = document.createElement ("img")
	var documentHeight = document.body.offsetHeight + document.body.scrollTop + document.body.clientHeight;
	var documentWidth = document.body.offsetWidth + document.body.scrollLeft;
	var blanketTop = document.body.scrollTop;
	var blanketLeft = document.body.scrollLeft;
	with ( blocker ){
		src=imagesFolder+"blanket.png"
		with ( style ){
			width=documentWidth;
			height=documentHeight;
			position="absolute"
			top=blanketTop;
			left=blanketLeft;
			id="ModalBlanket"
		}
	}
	document.body.insertBefore ( blocker, document.body.firstChild );
	document.body.blocker = blocker;
	var strFeatures = "";
	if ( arguments.length > 1 ){
		strFeatures = GetModalToPopupFeaturesConversion ( arguments[2].toString() );
	}

	// empty url to insure page gets loaded after onload event has been assigned
	var popupCell = window.open ( "", "", strFeatures ); 
	
	var popupFrame = popupCell.childNodes[1].rows[1].cells[0].firstChild;
	popupFrame.setAttribute ( "src", arguments[0] )

	// assign onload event
	if ( arguments.length > 0 ){
		popupFrame.setAttribute("onload", "SetDialogReferencesMO( this )");
		popupFrame.setAttribute("id", "CurrentModalDialogContent" );
		popupCell.parentNode.setAttribute("id", "CurrentModalDialog");
		popupFrame.dialogArguments = arguments[1];
	}
	if ( arguments.length > 3 ){
		// assign the OnPostClose event;
		popupCell.parentNode.OnPostClose = arguments[3];
	}
}

/**
* FUNCTION NAME:	SetDialogReferencesMO
* RETURN TYPE:		void
* ARGUMENTS
*	contentFrame:	the iframe element reference
* SUMMARY: 
*	Sets the dialogArguments property of the window contained
*	in the pop-up's content frame, and assigned a reference to
*	the OnClose event handler
*/
function SetDialogReferencesMO( contentFrame ){
	with ( frames[frames.length-1] ){
		window.dialogArguments = contentFrame.dialogArguments;
		window.close=CloseDialogMO;
	}
}


/** Generic **/

/**
* FUNCTION NAME:	WindowArguments
* RETURN TYPE:		Object
* ARGUMENTS		
*	arguments:			A reference to the table object representing the popup
*
* SUMMARY: 
*	Creates and returns an object encapsulation of the window.open
*	dialog arguments. The returned object also acts as a Name/Value
*	dictionary, allowing properties such as Width and Height to be returned
*	by calling both WindowArguments.Height, or WindowArguments["Height"]
*/
function WindowArguments( arguments ){
    this.url =  arguments[0];
    this.name = "";
    this.channelMode = ""; // not implemented (yet)
    this.directories = ""; // not implemented (yet)
    this.fullscreen = ""; // not implemented (yet)
    this.location = "";
    this.menubar = ""; // not implemented (yet)
    this.resizeable = "yes";
    this.scrollbars = ""; // not implemented (yet)
    this.status = ""; // not implemented (yet)
    this.titlebar = ""; // not implemented (yet)
    this.toolbar = ""; // not implemented
	
    this.top = "CENTER";
    this.left = "CENTER";
    this.height = 200;
    this.width = 200;
    
    if ( arguments.length > 1 ){
        PopulateWindowArgs ( this, arguments[2].toString() );
    }
    this.replace = ""; // not implemented
}

/**
* FUNCTION NAME:	PopulateWindowArgs
* RETURN TYPE:		void
* ARGUMENTS		
*	objArgs:			A reference to the object created using the WindowArguments constructor
*	args:				A token string containing the window.open dialog arguments
*
* SUMMARY: 
*	Parses the args token string and assigns the objArgs properties accordingly.
*/
function PopulateWindowArgs ( objArgs, args ){
	var args = args.replace (/;$/, "");
	var args = args.replace (/,$/, "");
    var argsArray = args.split ( "," );
    var nameValArray = null;
    for ( var i = 0; i < argsArray.length; i ++ ){
        nameValArray = argsArray[i].split("=");
        objArgs[ nameValArray[0].trim().toLowerCase() ] = nameValArray[1].trim();
    }
}

/**
* FUNCTION NAME:	trim
* RETURN TYPE:		String
*
* SUMMARY: 
*	Set as a prototype method of the String class, 
*	removes heading or trailing spaces from the object instance
*/
function trim(){
    var str = this.toString();
    while( str.indexOf(" ") == 0 ){
        str = str.substring ( 1, str.length );
    }
    while( str.indexOf(" ") == str.length - 1 ){
        str = str.substring ( 0, str.length - 1 );
    }
    return str;
}

/**
* FUNCTION NAME:	appendToOnload
* RETURN TYPE:		void
*
* SUMMARY: 
*	Appends the event that triggers creation of the WindowsContainer
*	to the Body.Onload event, thus insuring the document body has been
*	fully loaded before appending the DHTML structure.
*/
function appendToOnload(){
	// parses function body, appends new call, and assigns new body.onload
	appendFunctionToOnload ( "CreateWindowsContainerIE()" );
}
function appendFunctionToOnload( functionName ){
	// parses function body, appends new call, and assigns new body.onload
	var anonymous = document.body.onload.toString();
	var aBody = anonymous.substring( anonymous.indexOf("{")+1, anonymous.lastIndexOf("}") ) ;
	aBody += "\n" + functionName +";";
	document.body.onload = new Function (aBody);
}

/**
* FUNCTION NAME:	PopupManager
* RETURN TYPE:		void
*
* SUMMARY: 
*	Constructor for the PopupManager instance, used for 
*	browser specific functionality selection and detection, and
*	the overriding of the Window.Open event.
*/
function PopupManager(){
    this.WindowOpen = null;
    this.PopupDragStart = null
    this.MovePopup = null
    this.ClosePopup = null;
    this.MoveResizableIcon = null;
    this.ResizeTable = null;
    this.GetShadowTable = null;
    this.ShowModal = null;
}

/**
* FUNCTION NAME:	SetPopupManager
* RETURN TYPE:		void
*
* SUMMARY: 
*	Sets the PopupManager events in accordance to the detected browser.
*/
function SetPopupManager(){
    _popupManager = new PopupManager();
    with ( _popupManager ){
        if ( navigator.appName.toLowerCase().indexOf( "explorer" ) > 0 ){
            // assume version 5.5+
            WindowOpen = WindowOpenIE;
            PopupDragStart = PopupDragStartIE;
            MovePopup = MovePopupIE;
            ClosePopup = ClosePopupIE;
            MoveResizableIcon = MoveResizableIconIE;
            ResizeTable = ResizeTableIE;
            GetShadowTable = GetShadowTableIE;
            ShowModal = ShowModalIE;

            // prepare body with PopUpContainer
            if ( document.body.onload != null ){
                appendToOnload();
            }
            else{
                document.body.onload = CreateWindowsContainerIE;
            }
            document.body.onresize = OnWindowResize;
        }
        else{
            WindowOpen = WindowOpenMO;
            PopupDragStart = PopupDragStartMO;
            MovePopup = MovePopupMO;
            ClosePopup = ClosePopupMO;
            MoveResizableIcon = MoveResizableIconMO;
            ResizeTable = ResizeTableMO;
            GetShadowTable = GetShadowTableMO;
            ShowModal = ShowModalMO;
            if (document.body.getAttribute("onload") == null ){
                document.body.setAttribute("onload", "CreateWindowsContainerMO();");
            }
            else{
                document.body.setAttribute("onload", document.body.getAttribute("onload") + "; CreateWindowsContainerMO();");
            }
        }
    }
    // replace window.open method
    window.open = _popupManager.WindowOpen;
	window.showModalDialog = _popupManager.ShowModal;
}

function PopulateModalArguments( objFeatures, strFeatures){
	var featuresArray = strFeatures.split(";");
	var keyVal;
	for ( var i = 0; i < featuresArray.length; i ++ ){
		keyVal = (featuresArray[i].indexOf(":") > 0 )? featuresArray[i].split(":"): featuresArray[i].split("=");
		objFeatures[keyVal[0]] = keyVal[1];
	}
}

function GetModalToPopupFeaturesConversion( strFeatures ){
	var conversion = strFeatures;
	conversion = conversion.replace(/dialog/gi, "")
	conversion = conversion.replace(/;/gi, ",")
	conversion = conversion.replace(/:/gi, "=")
	conversion = conversion.toLowerCase();
	return conversion;
}

function GetAbsolutePath ( relativePath ){
	var rtr = relativePath;
	if ( ( relativePath.indexOf("http") < 0 ) && ( relativePath.indexOf("/") != 0 ) ){
		var path = document.location.protocol+"//"+document.location.hostname + document.location.pathname;
		rtr = ( path.substring(0, path.lastIndexOf("/")+1) + relativePath );
	}
	return rtr;
}

GetAbsolutePath( "" );
imagesFolder = GetAbsolutePath( imagesFolder );

String.prototype.trim = trim;
SetPopupManager();
if ( navigator.appName.toLowerCase().indexOf( "explorer" ) > 0 )
{
    window.onload = CreateWindowsContainerIE;
}
