
//----------------------------------------------------------------------------
// Code to determine the browser and version.
//----------------------------------------------------------------------------
function Browser() {

	var ua, s, i;

	this.isIE    = false;  // Internet Explorer
	this.isOP    = false;  // Opera
	this.isNS    = false;  // Netscape
	this.version = null;

	ua = navigator.userAgent;

	s = "Opera";
	if ((i = ua.indexOf(s)) >= 0) {
		this.isOP = true;
		this.version = parseFloat(ua.substr(i + s.length));
		return;
	}

	s = "Netscape6/";
	if ((i = ua.indexOf(s)) >= 0) {
		this.isNS = true;
		this.version = parseFloat(ua.substr(i + s.length));
		return;
	}

	// Treat any other "Gecko" browser as Netscape 6.1.

	s = "Gecko";
	if ((i = ua.indexOf(s)) >= 0) {
		this.isNS = true;
		this.version = 6.1;
		return;
	}

	s = "MSIE";
	if ((i = ua.indexOf(s))) {
		this.isIE = true;
		this.version = parseFloat(ua.substr(i + s.length));
		return;
	}
};


// The page manager object handles input field validation (for now...possibly more in the future).
function PageManager() {

    //--------------------------------------------------------------    
	// Define member variables.
	//--------------------------------------------------------------    
	
	// "Self" fixes loss-of-scope problem in inner functions.		
	var self = this; 
	
	
	this._metadata = null;
	
	//--------------------------------------------------------------    
	// Define member methods.
	//--------------------------------------------------------------    
	
	// TODO: might want to discontinue the "includeInSortList" functionality...
	
	// Update the page metadata collection.
    this.addMetadata = function (dataID, dataType, displayText, domID, includeInSortList) {
       
        var numMetadataItems;
        
        if (isEmpty(dataID)) { return self.displayError("Invalid dataID","addMetadata"); }
        if (isEmpty(dataType)) { return self.displayError("Invalid dataType","addMetadata"); }
        if (isEmpty(displayText)) { return self.displayError("Invalid displayText","addMetadata"); }
        if (isEmpty(domID)) { return self.displayError("Invalid domID","addMetadata"); }
        
        numMetadataItems = self._metadata.length;
        
        self._metadata[numMetadataItems] = new Object();
        self._metadata[numMetadataItems].dataID = dataID;
        self._metadata[numMetadataItems].dataType = dataType;
        self._metadata[numMetadataItems].displayText = displayText;
        self._metadata[numMetadataItems].domID = domID;
        self._metadata[numMetadataItems].includeInSortList = includeInSortList; 
    };
   
   
	// An "overridden" version of the global display error function.
    this.displayError = function (message, functionName) {
        return global_displayError(message, functionName, "PageManager");
    };
    
    
    this.initialize = function () {
    
        self._metadata = new Array();
    };
    
    
    // This function is called by the onblur event for input fields.
    this.validateField = function (control) {
        
        var controlID;
        var controlValue;
        var dataType;
        var displayText;
        var isValid;
        var metadataItem;
      
        if (control == null) { return self.displayError("Invalid control", "validateField"); }
        
        controlID = control.getAttribute("id");
        if (isEmpty(controlID)) { return self.displayError("Invalid controlID", "validateField"); }
        
        // TODO: get controlValue based on nodetype!
        controlValue = control.value;
        
        for (var p=0; p<self._metadata.length; p++) {
            metadataItem = self._metadata[p];
            if (metadataItem == null) { continue; }
            
            if (!isEmpty(metadataItem.domID) && metadataItem.domID.toUpperCase() == controlID.toUpperCase()) {
                dataType = metadataItem.dataType;
                displayText = metadataItem.displayText;
                break;
            }
        }
        
        isValid = isValidValue(controlValue, dataType);
	    if (isValid == false) {
		    if (dataType == 'int') {
		        control.value = "";
			    alert("Please enter a valid integer for '" + displayText + "'.");
			    control.focus();
			    return false;
		    }
		    else if (dataType == 'float') {
		        control.value = "";
			    alert("Please enter a valid number for '" + displayText + "'.");
			    control.focus();
			    return false;
		    }
		    else if (dataType == 'text') {
		        control.value = "";
			    alert("Please enter valid text for '" + displayText + "'.");
			    control.focus();
			    return false;
		    } else {
		        alert("Unknown data type for '" + displayText + "'.");
			    control.focus();
			    return false;
		    }
		    // Get rid of the offending value.
		    control.value = "";
    		
		    return false;
	    }
    	
	    return true;
    };
    
    
	//---------------------------------------------------------------------------
    // This is executed when the object is instantiated.
    //---------------------------------------------------------------------------
	self.initialize();
};


// Create a new instance of the Browser object.
var browser = new Browser();


// Get the X coordinate of the mouse's current location.
function getMouseX(e) {
  
    var mouseX;
    
    // Make sure the correct event is used.
    if (e == null) { e = window.event; }

    if (browser.isIE == true) { mouseX = e.clientX + document.body.scrollLeft; } 
    else { mouseX = e.pageX; }
 
    // Catch possible negative values (NS4?).
    if (mouseX < 0) { mouseX = 0 }; 
 
    return mouseX;
};


// Get the Y coordinate of the mouse's current location.
function getMouseY(e) {

    var mouseY;
    
    // Make sure the correct event is used.
    if (e == null) { e = window.event; }

    if (browser.isIE == true) { mouseY = e.clientY + document.body.scrollTop; }
    else { mouseY = e.pageY; }
 
    // Catch possible negative values (NS4?).
    if (mouseY < 0) { mouseY = 0 };  
 
    return mouseY;
};


// Generate a random number having a specific upper limit.
function getRandomNumber(upperLimit) {
    if (typeof(upperLimit) != "number") {alert("not a number!");}
    return Math.floor(Math.random()*upperLimit);
}


// Display an error message and return false.
function global_displayError(message, functionName, objectName) {
    
    var errorText = "";
    
    if (message == null) {message = "(unknown)";}
    if (functionName == null) {functionName = "";}
    if (objectName == null) {objectName = "";}
    
    errorText = "Error in ";
    if (objectName != "") {errorText += objectName;}
    if (functionName != "") {errorText += "." + functionName + "()";}
    errorText += " - " + message + "!";
    
    alert(errorText);
    
    return false;
};


// Display an error message and return zero.
function global_displayZeroAsError(message, functionName, objectName) {
    
    var errorText = "";
    
    if (message == null) {message = "(unknown)";}
    if (functionName == null) {functionName = "";}
    if (objectName == null) {objectName = "";}
    
    errorText = "Error in ";
    if (objectName != "") {errorText += objectName;}
    if (functionName != "") {errorText += "." + functionName + "()";}
    errorText += " - " + message + "!";
    
    alert(errorText);
    
    return 0;
};


// Is this value null, an empty string, or zero?
function isEmpty(value) {
    if (value == null) {
        return true;
    } else if (typeof(value) == "string" && value == "") {
        return true;
    } else if (typeof(value) == "number" && value == 0) {
        return true;
    } else {
        return false;
    }
};


// Is the input parameter a floating-point number?
function isFloat(value) {
	var isFloatRegExp = new RegExp("^(([0-9]*[.]?[0-9]+)|[0-9]+)$"); 
	return isFloatRegExp.test(value);
}

// Is the input parameter an integer value?
function isInteger(value) {
	var isNumericRegExp = new RegExp("^([0-9])+$"); 
	return isNumericRegExp.test(value);
}

// TODO: figure out how to match invalid / SQL-injection-hack text...
// Is the input parameter valid (SQL) text?
function isValidText(value) {
	//var isValidTextRegExp = new RegExp("^([0-9,a-z,A-Z])*$");
	//return isValidTextRegExp.test(value);
	
	// dmd testing 040607
	return true;
}

// A wrapper function for the individual validation functions.
function isValidValue(value, dataType) {

	if (value == null) {
		alert("Error in isValidValue: null value");
		return false;
	}
	else if (value == "") {
		// By default, validate an empty string.
		return true;
	}
	else if (dataType == null || dataType == "") {
		alert("Error in isValidValue: null or empty data type");
		return false;
	}
	
	switch (dataType) {
		case 'int':
			return isInteger(value);
			break;
		case 'float':
			return isFloat(value);
			break;
		case 'text':
			return isValidText(value);
			break;
	}
}

// Javascript Utility functions	
function checkForErrors(parameterA,parameterB,mode)
{
	// Note that the modes are expressed as assertions, ie. we're confirming that A < B.
	if (mode == "A<B" && parameterA.value != "" && parameterA.value != null)
	{
		if (parameterA.value < 1)
		{
			alert("Please enter a value of one or greater");
			eval("document.form1." + parameterA.name + ".value = '';");
			eval("setTimeout('document.form1." + parameterA.name + ".focus()',10);");
			
		}
		else if (parseInt(parameterA.value) > parseInt(parameterB.value) && parameterB.value != "" && parameterB.value != null && parameterA.value != "")
		{
			alert("This value must be empty or less than or equal to " + parameterB.value);
			eval("document.form1." + parameterA.name + ".value = ''");
			eval("setTimeout('document.form1." + parameterA.name + ".focus()',10);");
		}
		
	}
	if (mode == "B>A" && parameterB.value != "" && parameterB.value != null)
	{
		if (parameterB.value < 1)
		{
			alert("Please enter a value of one or greater");
			eval("document.form1." + parameterB.name + ".value = ''");
			eval("setTimeout('document.form1." + parameterB.name + ".focus()',10);");
		}
		else if (parseInt(parameterB.value) < parseInt(parameterA.value) && parameterA.value != null)
		{
			alert("This value must be empty or greater than or equal to " + parameterA.value);
			eval("document.form1." + parameterB.name + ".value = ''");
			eval("setTimeout('document.form1." + parameterB.name + ".focus()',10);");
		}
	}
}

// This "if" block belongs in web pages that call filterKeystrokes()
// It is commented out here due to possible conflicts with certain versions of Netscape.
// When placing this code into an ASP or HTML page, use the same "script" block conventions
// utilized in this page (i.e. commenting out --HTML style comments-- the actual javascript.)
/*
if (navigator.appName == 'Netscape') {
	window.captureEvents(Event.KEYPRESS);
	window.onKeyPress = filterKeystrokes;
}
*/

// Place the above "if" block into web pages that use filterKeystrokes().
function filterKeystrokes(datatype, e)
{
	if (navigator.appName == 'Microsoft Internet Explorer')
        	key = window.event.keyCode;
    	else
        	key = e.which;

	if (datatype == "float")
		{
		if ((key < 48 || key > 57) && (key != 46) && (key > 31))
			return false;
		}
	if (datatype == "int")
		{
		if ((key < 48 || key > 57) && (key > 31))
			return false;
		}
	return true;
}

// A function that dynamically creates a window. 
function makeWin(url, lWidth, lHeight, ScrollB) {
	
	agent = navigator.userAgent;
	windowName = "Sitelet";

	params  = "";
	params += "toolbar=0,";
	params += "location=0,";
	params += "directories=0,";
	params += "status=0,";
	params += "menubar=0,";
	params += "scrollbars=" + ScrollB + ",";
	params += "resizable=1,";
	params += "width=" + lWidth + ",";
	params += "height=" + lHeight;

	win = window.open(url, windowName , params);

	if (!win.opener) {
		win.opener = window;
	}
	// brings window to the front.
  if(win) win.focus();
}

// A function that dynamically creates a window, and accepts a window name.
function makeWin2(url, lWidth, lHeight, ScrollB, windowName) {
	
	agent = navigator.userAgent;

	params  = "";
	params += "toolbar=1,";
	params += "location=1,";
	params += "directories=1,";
	params += "status=1,";
	params += "menubar=1,";
	params += "scrollbars=" + ScrollB + ",";
	params += "resizable=1,";
	params += "width=" + lWidth + ",";
	params += "height=" + lHeight;

	win = window.open(url, windowName , params);

	if (!win.opener) {
		win.opener = window;
	}
	// brings window to the front.
  if(win) win.focus();	
}



// Populate a control with a value by specifying its "id". Note that the control type is dynamically determined and
// this determines the way it gets populated.
function populateControl(id, value) {

    var controlElement;
    var nodeName;
    var type;
    
    if (isEmpty(id)) {return global_displayError("Invalid id","populateControl","");}
    if (value == null) {value = "";}
    
    controlElement = document.getElementById(id);
    if (controlElement == null) {return false;}  // TODO: should this be an exception?
    
    nodeName = controlElement.nodeName;
    if (isEmpty(nodeName)) {return global_displayError("Invalid nodeName","populateControl","");}
    
    nodeName = nodeName.toUpperCase();
 
    // Use the node name to determine how to update the control.
    if (nodeName == "SELECT") {
    
        for (var i=0; i<controlElement.options.length; i++) {
            if (controlElement.options[i].value == value) {controlElement.options[i].selected = true;}
            else {controlElement.options[i].selected = false;}
        }
        
    } else if (nodeName == "TEXTAREA") {
    
        controlElement.text = value;
        
    } else if (nodeName == "INPUT") {
    
        type = controlElement.getAttribute("type");
        if (isEmpty(type)) {return global_displayError("Invalid type","populateControl","");}
        
        type = type.toUpperCase();
        
        if (type == "TEXT" || type == "HIDDEN") { controlElement.value = value; }
        if (type == "CHECKBOX") {
            // TODO: is this correct???
            if (value.toUpperCase() == "ON" || value == true) {controlElement.checked = true;}
            else {controlElement.checked = false;}
        }
    }
};


// Determine the most appropriate XML HTTP object for the browser/version.
// From http://www.quirksmode.org/js/xmlhttp.html.
var XMLHttpFactories = [
    function () {return new XMLHttpRequest()},
    function () {return new ActiveXObject("Msxml2.XMLHTTP")},
    function () {return new ActiveXObject("Msxml3.XMLHTTP")},
    function () {return new ActiveXObject("Microsoft.XMLHTTP")}
];


// Create an XMLHTTP object specific to the browser (from http://www.quirksmode.org/js/xmlhttp.html).
function createXMLHTTPObject() {
    var xmlhttp = false;
    for (var i=0; i<XMLHttpFactories.length; i++) {
	    try { xmlhttp = XMLHttpFactories[i](); }
	    catch (e) { continue; }
	    break;
    }
    return xmlhttp;
};
    
    
// Create and return an XMLHTTP object specific to the browser (from http://www.quirksmode.org/js/xmlhttp.html). 
// Note that this depends on the array of "XMLHttpFactories" that are defined above.
function getXmlDocument(xmlFileName) {

    var resultDocument = null;
    var xmlhttp = null;
    
    if (isEmpty(xmlFileName)) { return global_displayError("Invalid XML file name", "getXmlDocument","");}  
    
    for (var i=0; i<XMLHttpFactories.length; i++) {
	    try { xmlhttp = XMLHttpFactories[i](); }
	    catch (e) { continue; }
	    break;
    }
	    
	if (xmlhttp == null) {return global_displayError("Invalid XMLHTTPObject", "getXmlDocument","");}  
	
	// Get the XML file.
	xmlhttp.open("GET", xmlFileName, false);
    xmlhttp.send(null);
    
    resultDocument = xmlhttp.responseXML;
    if (resultDocument == null) {return global_displayError("Invalid XML document", "getXmlDocument","");} 
    
    return resultDocument; 
};



// Handle an asynchronous request for alias data.
function processAsyncAliasData(result) {

    var bodyElement;
    var aliasNode;
    var aliasNodes;
    var metadataNode;
    var metadataNodes;
    var status;
    var targetID;
    var titleText;
    var xmlDoc;
   
    // Validate the input.
    if (result == null) { return global_displayError("Invalid result","processAsyncAliasData",""); }
    
    // The responseXML attribute of the result should be an XML document.
    xmlDoc = result.responseXML;
    
    /* An example of the XML returned (without actual values):
    <alias_data>
        <metadata title="" target_id=""></metadata>
        <alias value=""> </alias>
    </alias_data>
    */
  
    // Get dialog metadata.
    metadataNodes = xmlDoc.getElementsByTagName("metadata"); 
 
    if (metadataNodes == null || metadataNodes.length < 1) { return global_displayError("Invalid metadataNodes.length","processAsyncAliasData",""); }
        
    // Get the first (and hopefully only) metadata node. These will be used to configure the dialog.
    metadataNode = metadataNodes[0];
    if (metadataNode == null || metadataNode.nodeType != 1) { return global_displayError("Invalid metadataNode","processAsyncAliasData",""); }
        
    status = metadataNode.getAttribute("status");
    titleText = metadataNode.getAttribute("title");
    targetID = metadataNode.getAttribute("target_id");
        
    // TODO: validate titleText, targetID!  
   
    bodyElement = document.getElementById(targetID);
    if (bodyElement == null) { return global_displayError("Invalid bodyElement","processAsyncAliasData",""); }
    
    // Get the alias node data.
    aliasNodes = xmlDoc.getElementsByTagName("alias"); 
 
    // Iterate thru the alias nodes. These represent rows of aliases in the dialog.
    for (var r=0; r<aliasNodes.length; r++) {
    
        var aliasRow;
        var value;
        
        aliasNode = aliasNodes[r];
        if (aliasNode == null || aliasNode.nodeType != 1) {continue;}
        
        value = aliasNode.getAttribute("value");
        if (isEmpty(value)) {continue; /* error? */ }
        
        // Create the Element for this row.
        aliasRow = document.createElement("div");
        aliasRow.className = "aliasInfoPanelRow";
        aliasRow.innerHTML = value;
        
        // Add the alias row to the body.
        bodyElement.appendChild(aliasRow);
    }
    bodyElement.className = "aliasInfoPanel";
    bodyElement.onmouseout = function () { bodyElement.className = "hiddenInfoPanel"; bodyElement.innerHTML = ""; };
    
}; 


// Handle an asynchronous request for linkout data.
function processAsyncLinkoutData(result) {

    var bodyElement;
    var buttonElement;
    var dialogElement;
    var dialogID;
    var linkoutNode;
    var linkoutNodes;
    var linkoutRowNode;
    var linkoutRowNodes;
    var metadataNode;
    var metadataNodes;
    var status;
    var titleText;
    var xmlDoc;
   
    // Validate the input.
    if (result == null) { return global_displayError("Invalid result","processAsyncLinkoutData",""); }
    
    // Set the dialog's ID.
    dialogID = "linkoutDialog";
    
    // The responseXML attribute of the result should be an XML document.
    xmlDoc = result.responseXML;
    
    /* An example of the XML returned (without actual values):
    <linkout_data>
        <metadata title="" x="" y=""></metadata>
        <linkout_row>
            <linkout key="" label="" description="" url=""> </linkout>
            ...
        </linkout_row>
    </linkout_data>
    */
  
    // Get dialog metadata.
    metadataNodes = xmlDoc.getElementsByTagName("metadata");
    if (metadataNodes == null || metadataNodes.length < 1) { return global_displayError("Invalid metadataNodes.length","processAsyncLinkoutData",""); }
        
    // Get the first (and hopefully only) metadata node. These will be used to configure the dialog.
    metadataNode = metadataNodes[0];
    if (metadataNode == null || metadataNode.nodeType != 1) { return global_displayError("Invalid metadataNode","processAsyncLinkoutData",""); }
        
    status = metadataNode.getAttribute("status");
    titleText = metadataNode.getAttribute("title");
    x = metadataNode.getAttribute("x");
    y = metadataNode.getAttribute("y");
        
    // TODO: validate titleText, x, y!  
    
    // Create and populate the DOM Elements required by the dialog. 
    bodyElement = document.createElement("div");
    bodyTableElement = document.createElement("table");
    bodyTbodyElement = document.createElement("tbody");
    buttonElement = document.createElement("input");
    
    bodyTableElement.className = dialogID + "_Table";
    bodyTableElement.setAttribute("cellpadding","0");
    bodyTableElement.setAttribute("cellspacing","0");
    
    bodyElement.setAttribute("id", dialogID + "_Body");
    
    buttonElement.setAttribute("id", dialogID + "_Button");
    buttonElement.setAttribute("type", "button");
    buttonElement.setAttribute("value", "Close");
    buttonElement.onclick = function () { destroyDialog(dialogID); }
    
    // Get the linkout row node data.
    linkoutRowNodes = xmlDoc.getElementsByTagName("linkout_row"); 
 
    // Iterate thru the linkout_row nodes. These represent rows of linkouts in the dialog.
    for (var r=0; r<linkoutRowNodes.length; r++) {
    
        //var imageElement;
        //var imageTD;
        var description;
        var key;
        var label;
        var linkout;
        var linkoutRow;
        var linkoutTD;
        var url;
        
        linkoutRowNode = linkoutRowNodes[r];
        if (linkoutRowNode == null || linkoutRowNode.nodeType != 1) {continue;}
        
        linkoutNodes = linkoutRowNode.childNodes;
        if (linkoutNodes == null) { return global_displayError("Link row has invalid linkouts","processAsyncLinkoutData",""); }
        
        // Create the Elements for this row.
        linkoutRow = document.createElement("tr");
        //imageTD = document.createElement("td");
        //imageElement = document.createElement("img");
            
            
        // TODO: note that I've created two *_thumbnail.jpgs for this (viralZone and ICTVdb)
        // that can be added!    
            
       
        // Populate the linkout row by iterating thru the linkouts.
        for (var l=0; l<linkoutNodes.length; l++) {
        
            // Get and validate the linkout node.
            linkoutNode = linkoutNodes[l];
            if (linkoutNode == null || linkoutNode.nodeType != 1) {continue;}
            
            // Get and validate the attributes.
            description = linkoutNode.getAttribute("description");
            key = linkoutNode.getAttribute("key");
            label = linkoutNode.getAttribute("label");
            url = linkoutNode.getAttribute("url");
            if (isEmpty(label)) { return global_displayError("Invalid label","processAsyncLinkoutData",""); }
      
            // Create the Elements for this linkout.
            linkoutTD = document.createElement("td");
            
            /*
            // dmd testing
            if (label.toUpperCase() == "VIRALZONE") {
                // Add an image.
                linkout = document.createElement("img");
                linkout.setAttribute("src","images/viralzone_thumbnail.jpg");
                
            } else if (label.toUpperCase().indexOf("ICTVDB") >= 0) {
                // Add an image.
                linkout = document.createElement("img");
                linkout.setAttribute("src","images/ICTVdb_thumbnail.jpg");
                
            }  else if (label.toUpperCase().indexOf("ATCC") >= 0) {
                // Add an image.
                linkout = document.createElement("img");
                linkout.setAttribute("src","images/ATCC_thumbnail.jpg");
                
            } else {*/
                if (!isEmpty(url)) {
                    linkout = document.createElement("a");
                    linkout.setAttribute("href", url);
                    linkout.setAttribute("target", "_blank");  // TODO: consider determining this based on whether local or not...
                } else {
                    linkout = document.createElement("span");
                }
                
                linkout.innerHTML = label;
                
                if (!isEmpty(description)) { linkout.setAttribute("title", description); }
            //}
            
            if (key == "db") { linkoutTD.className = "asyncLinkoutLabelClass"; }
            else { linkoutTD.className = "asyncLinkoutDataClass"; }
            
            linkoutTD.appendChild(linkout);
            
            linkoutRow.appendChild(linkoutTD);
        }
        
        // Add the linkout row to the body.
        bodyTbodyElement.appendChild(linkoutRow);
    }
    
    // Assemble the components.
    bodyTableElement.appendChild(bodyTbodyElement); 
    
    
    // If data exists, add a descriptive header row.
    if (status != "no data") {
        
        var headerTable = document.createElement("table");
        var headerTbody = document.createElement("tbody");
        var headerRow = document.createElement("tr");
        var headerLabel = document.createElement("th");
        var headerValue = document.createElement("th");
        
        headerTable.className = "asyncLinkoutHeaderRow";
        headerLabel.className = "asyncLinkoutHeaderRow_label";
        headerLabel.innerHTML = "Database";
        headerValue.className = "asyncLinkoutHeaderRow_value";
        headerValue.innerHTML = "Link";
        
        headerRow.appendChild(headerLabel);
        headerRow.appendChild(headerValue);
        headerTbody.appendChild(headerRow);
        headerTable.appendChild(headerTbody);
        
        // Add the linkout row to the body.
        //bodyTbodyElement.appendChild(headerRow);
        bodyElement.appendChild(headerTable);
    }
    
    
    bodyElement.appendChild(bodyTableElement);
    bodyElement.appendChild(buttonElement);
    
    // Pressing the enter key is the same as clicking on the close button.
    bodyElement.onkeypress = function (e) {detectEnterKey(e, "destroyDialog(" + dialogID + ")");}
    
    // First, destroy any existing dialogs.
    destroyDialog(dialogID);
    
    // Call the general-purpose displayDialog function.
    displayDialog(dialogID, titleText, bodyElement);  
    
    // Position the dialog based on x,y.
    dialogElement = document.getElementById(dialogID);
    if (dialogElement == null) { return global_displayError("Invalid dialogElement","processAsyncLinkoutData",""); }
    
    dialogElement.className = "asyncLinkoutDialogClass";
    dialogElement.style.left = x + "px";
    dialogElement.style.top = y + "px";
}; 
    


// Send an asynchronous request to the server (from http://www.quirksmode.org/js/xmlhttp.html).
function sendAsyncRequest(url, callback, postData) {

    var method;
    var req;
    var xmlHttpObject;
  
    // Instantiate the XMLHTTP object.
    xmlHttpObject = createXMLHTTPObject();   

    if (xmlHttpObject == null) { return global_displayError("Invalid XML HTTP object", "sendAsyncRequest", ""); }
    
    method = (postData) ? "POST" : "GET";
    
    xmlHttpObject.open(method, url, true);
    xmlHttpObject.setRequestHeader('User-Agent','XMLHTTP/1.0');
    
    if (postData) { xmlHttpObject.setRequestHeader('Content-type','application/x-www-form-urlencoded'); }
    
    xmlHttpObject.onreadystatechange = function () {
	    if (xmlHttpObject.readyState != 4) { return; }
	    if (xmlHttpObject.status != 200 && xmlHttpObject.status != 304) { return; }
	  
	    callback(xmlHttpObject);
    }
    
    if (xmlHttpObject.readyState == 4) { return;}
    xmlHttpObject.send(postData);
};



// -----------------------------START:  AC_RunActiveContent.js -------------------------
// 	(from http://download.macromedia.com/pub/developer/activecontent_samples.zip)
//	v1.0
//	Copyright 2006 Adobe Systems, Inc. All rights reserved.
function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '<object ';
  for (var i in objAttrs)
    str += i + '="' + objAttrs[i] + '" ';
  str += '>';
  for (var i in params)
    str += '<param name="' + i + '" value="' + params[i] + '" /> ';
  str += '<embed ';
  for (var i in embedAttrs)
    str += i + '="' + embedAttrs[i] + '" ';
  str += ' ></embed></object>';

  document.write(str);
}

function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    

    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblClick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "id":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}
//--------------------------END:  AC_RunActiveContent.js -----------------------------



//-----------------------START:  AC_ActiveX.js --------------------------
// 	(from http://download.macromedia.com/pub/developer/activecontent_samples.zip)
//	v1.1
//	Copyright 2006 Adobe Systems, Inc. All rights reserved.
function AC_AX_RunContent(){
  var ret = AC_AX_GetArgs(arguments);
 
 /* // Debug Code
  document.write("ret.objAttrs:<br>");
  for (var i in ret.objAttrs)
    document.write (ret.objAttrs[i] + '<br>');
    
  document.write("ret.params:<br>");
  for (var i in ret.params)
    document.write (ret.params[i] + '<br>');
    
  document.write("ret.embedAttrs:<br>");
  for (var i in ret.embedAttrs)
    document.write (ret.embedAttrs[i] + '<br>');
  */  
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_AX_GetArgs(args){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    

    switch (currArg){	
      case "pluginspage":
      case "type":
      case "src":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "data":
      case "codebase":
      case "classid":
      case "id":
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblClick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  return ret;
}
//---------------------END:   AC_ActiveX.js ------------------------

