﻿function fnAssignCompanySelected(element,selection)
{
    var elID = element.split("__");
    document.getElementById(elID[0]).value=selection;
    document.getElementById(elID[1]).style.visibility = "hidden";
}
function fnChangeClass(element,state)
{
	if(state==1)
	{
		document.getElementById(element).className = "ajaxLinkHover";
	}
	else
	{
		document.getElementById(element).className = "ajaxLink";
	}
	
}
/***
Title: fnAbortMSAjaxPostBack()
Author: Yeng Yang
Description: This function aborts any MS .NET Ajax callbacks that are pending.
***/
function fnAbortMSAjaxPostBack(){

    var obj = Sys.WebForms.PageRequestManager.getInstance();
    if (obj.get_isInAsyncPostBack()) 
        obj.abortPostBack();
        
    if (typeof xmlHttp != "undefined" && xmlHttp){
        xmlHttp.abort();
        delete xmlHttp;
    }// if
    
    if (typeof ajax != "undefined" && ajax){
        ajax.abort();
        delete ajax;
    }// if
}
/************
    Title: fnEvaluateJSON()
    Author: Yeng Yang
    Purpose: Evaluates a JSON string into an object.
************/
function fnEvaluateJSON(jsonStr){
    return eval('(' + jsonStr + ')');

}
/***********
    TITLE:      createXMLHttpRequest
    AUTHOR:     Dean Reid
    PURPOSE:    This function creates an XML
                request to initiate AJAX
                calls
***********/
function createXMLHttpRequest()
{
    if (window.ActiveXObject)
    {
	    xmlHttp=new ActiveXObject("Microsoft.XMLHttp");   
    }
    else if (window.XMLHttpRequest)
    {
	    xmlHttp=new XMLHttpRequest();
    }
}
function createAjaxHandle()
{
    var ajaxHandle;
    if (window.ActiveXObject)
    {
	    ajaxHandle=new ActiveXObject("Microsoft.XMLHttp");   
    }
    else if (window.XMLHttpRequest)
    {
	    ajaxHandle=new XMLHttpRequest();
    }
    
    return ajaxHandle
}
/***********
    TITLE:      fnGetUNSPSCTree
    AUTHOR:     Steven Ciarleglio
    PURPOSE:    This function handles the AJAX tree lookup
                of a UNSPSC code. 
***********/
function fnGetUNSPSCTree(State,Code,RowID)
{
    if(State=="SHOW")
    {
        var AjaxURL = new String();
        createXMLHttpRequest();
        xmlHttp.onreadystatechange = fnHandleStateChangeFORGetUNSPSCTree;
        AjaxURL = "../AjaxProcessing.aspx?Requestor=UNSPSC&RequestType=TreeLookup&RowID=" + RowID + "&Code=" + Code;

        xmlHttp.open("Get",AjaxURL,true);
        xmlHttp.send(null);
    }
    else if (State="HIDE")
    {
        document.getElementById("UNSPSCTree_"+RowID).style.visibility = "hidden";
    }
}
/***********
    TITLE:      fnGetUNSPSCTree
    AUTHOR:     Steven Ciarleglio
    PURPOSE:    This function handles the state change
    for fnGetUNSPSCTree
***********/
function fnHandleStateChangeFORGetUNSPSCTree()
{
    if(xmlHttp.readyState == 4)
    {
        if(xmlHttp.status == 200)
        {
          if (xmlHttp.responseText)
          {     
                all = xmlHttp.responseText.split("##");
                document.getElementById("UNSPSCTree_"+all[0]).style.visibility = "hidden";
                for (var i=1;i<=all.length-1;i++)
                {
                     if ( all[i] === undefined )
                     {
                     }
                     else
                     {
                        part = all[i].split(";");
                        switch(i)
                        {
                            case 1:
                                document.getElementById("divUNSPSCSegment_"+all[0]).innerHTML = part[0];
                                document.getElementById("divUNSPSCSegmentTitle_"+all[0]).innerHTML = part[1];
                                break;
                            case 2:
                                document.getElementById("divUNSPSCFamily_"+all[0]).innerHTML = part[0];
                                document.getElementById("divUNSPSCFamilyTitle_"+all[0]).innerHTML = part[1];
                                break;
                            case 3:
                                document.getElementById("divUNSPSCClass_"+all[0]).innerHTML = part[0];
                                document.getElementById("divUNSPSCClassTitle_"+all[0]).innerHTML = part[1];
                                break;
                            case 4:
                                document.getElementById("divUNSPSCCommodity_"+all[0]).innerHTML = part[0];
                                document.getElementById("divUNSPSCCommodityTitle_"+all[0]).innerHTML = part[1];
                                break;  	                        	                    	                    
                        }
                     }
               }
               document.getElementById("UNSPSCTree_"+all[0]).style.visibility = "visible";
          }      
        }  
    }
}
/***********
    TITLE:      fnCloseSubApplication
    AUTHOR:     Steven Ciarleglio
    PURPOSE:    This function should be called from 
                the header link "Return to pricePAL". 
                It generates an AJAX request to delete all
                specified footprints.
***********/
function fnCloseSubApplication(UID,Requestor)
{
    if(window.opener!=null)
    {
	    if(window.opener.closed)
	    {
		    //alert('Your session has expired. Please login again.');
	    }
	}

    var AjaxURL = new String();
    var ajax = createAjaxHandle();
            
	switch(Requestor)
	{
	    case "LogoutClicked":

            ajax.onreadystatechange = function(){
                if(ajax.readyState == 4)
                {
                    if(ajax.status == 200)
                    {
                        if (ajax.responseText)
                        {    
                        
                            delete ajax; 
                        }
                    }
                }
            }
            AjaxURL = "../AjaxProcessing.aspx?Requestor=Utilities&RequestType=DisposeFootPrints&UID=" + UID;

            ajax.open("Get",AjaxURL,true);
            ajax.send(null);
            
	        window.close();
	        break;
	    case "WindowClosed":	    

            ajax.onreadystatechange = function(){
                if(ajax.readyState == 4)
                {
                    if(ajax.status == 200)
                    {
                        if (ajax.responseText)
                        {    
                        
                            delete ajax; 
                        }
                    }
                }
            }
            AjaxURL = "../AjaxProcessing.aspx?Requestor=Utilities&RequestType=DisposeFootPrints&UID=" + UID;

            ajax.open("Get",AjaxURL,true);
            ajax.send(null);    
	        break;
	}
}
/***********
    TITLE:      fnCloseSubApplication
    AUTHOR:     Steven Ciarleglio
    PURPOSE:    This function handles the state change
                for fnCloseSubApplication
***********/
function fnHandleStateChangeFORCloseSubApplication()
{
    if(xmlHttp.readyState == 4)
    {
        if(xmlHttp.status == 200)
        {
            if (xmlHttp.responseText)
            {    
            
                delete xmlHttp; 
            }
        }
    }
}

/****************************
Title: fnCreateElement()
Author: Yeng Yang
Description: This function dynamically creates an element and sets its
            innerHTML body. The function looks for an element according to its id
            to see if exists. If it does not exist, the new element is created, its
            innerHTML gets set, and the function returns true. If the element is found, 
            its innerHTML is set to the "elementHtmlBody" parameter value and the 
            function returns false. The element can be created within a parent element.
            If the parent does not exist it will be created in the main body. 
Parameters:
            parentID - ID of parent element to create new element in.
            elementID - ID to assign new element with.
            elementTag - Type of tag to create. (span,div,input,etc...)
            elementHtmlBody - A string containing html to assign to the element's innerHTML
            elementClass - CSS class to assign element to.
*****************************/
function fnCreateElement(parentID, elementID, elementTag, elementHtmlBody, elementClass){
    
    // create new element if it does not exist
    if (document.getElementById(elementID) == null){
        newEle = document.createElement(elementTag);    // create element
        newEle.setAttribute("id", elementID);           // set id
        
        // set element css class
        newEle.className = elementClass;
        //newEle.setAttribute("class", elementClass);   
          
        newEle.innerHTML = elementHtmlBody;             // set element html body stuff
        
        // attemt to add to parent container - if parent does not exists add to body
        if (parentID.length == 0 || document.getElementById(parentID) == null){       
            document.body.appendChild(newEle);        
        }else{
            document.getElementById(parentID).appendChild(newEle);
        }// if-else
        return newEle;
        
    }else{
        // get existing element and set its body
        curEle = document.getElementById(elementID);
        curEle.innerHTML = elementHtmlBody;
        return curEle;
    }// if-else
}

// global variables for company info popups
var hidePopup = true;
var onControl = false;
var currentCompanyID = 0;

/***********************
Title: fnHideCompanyInfoPopup()
Author: Yeng Yang
Purpose: This function pauses for 50 milliseconds and then hides the company info popup  
        according to the global hidePopup flag. If hidePopup = true the element is hidden, 
        if hidePopup = false the element is not hidden.
************************/
function fnHideCompanyInfoPopup(){


//    var popup = document.getElementById('ajaxCompanyInfoPopup');
//    if (popup){
//        popup.style.visibility = 'hidden';
//    }// if
    
    onControl = false;
    
    if (document.getElementById("ajaxCompanyInfoPopup") != undefined){
        setTimeout("if (hidePopup && !onControl){document.getElementById('ajaxCompanyInfoPopup').style.visibility = 'hidden';}", 50);
        setTimeout("if (hidePopup && !onControl){document.getElementById('ajaxCompanyInfoPopup').style.visibility = 'hidden';}", 300);
    }// if
}

/***************************
Title: fnShowCompanyInfo()
Author: Yeng Yang
Purpose: This function retrieves a company's info using ajax and shows
        it in a popup container (div/span/etc...). The popup container's
        innerText needs to be empty. If the container is empty the company's 
        info will be retrieved through ajax. if the container is not empty,
        it is assumed that the company info was already retrieved through ajax
        and the popup container's visibility will only need to be shown.
            
Parameters: companyID - Record ID of company to retrieve.
            popupID - Client side ID of container to put company info into.
            hoverPosition - position of popup panel            
            offsetX - x value to offset popup position
            offsetY - y value to offset popup position

*****************************/
function fnShowCompanyInfo(companyID, hoverControlID, hoverPosition, offsetX, offsetY){


    hidePopup = false;
    onControl = true;
    
    // create element if it does not exist
    if (document.getElementById("ajaxCompanyInfoPopup") == null){
        retval = fnCreateElement("", "ajaxCompanyInfoPopup", "div", "", "companyInfoPopupStyle");
    }// if
    
    var popupPanel = document.getElementById("ajaxCompanyInfoPopup");
    
    // set popup position
    if (hoverPosition == "right"){
        // to the right of hover control
        popupPanel.style.top = findPosY(hoverControlID) + offsetX + "px";
        popupPanel.style.left = findPosX(hoverControlID)+ offsetY +document.getElementById(hoverControlID).offsetWidth+2 + "px";
    }else if(hoverPosition == "bottomright"){
        // to the right and below of hover control
        popupPanel.style.top = findPosY(hoverControlID) + 16 + offsetX + "px";
        popupPanel.style.left = findPosX(hoverControlID)+ offsetY + document.getElementById(hoverControlID).offsetWidth+2 + "px";
   
    }else{
        // default bottom
        popupPanel.style.top = findPosY(hoverControlID) + 16 + offsetX + "px";
        popupPanel.style.left = findPosX(hoverControlID) - 5 + offsetY + "px";
    
    }// if-else
    
    popupPanel.onmouseover = function(){hidePopup=false;onControl = true;};
    popupPanel.onmouseout = function(){hidePopup=true;onControl = false;fnHideCompanyInfoPopup();};

    // check if popup container is empty
//    if (companyID == currentCompanyID){
//        // if company id is same as current show popup - information already previously retrieved
//        popupPanel.style.visibility = 'visible';
//        
//    }else{
    
       
        var ajax = createAjaxHandle();
        ajax.onreadystatechange = function(){
            if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText)
            {
                var responseDataList = new Array();
                //responseDataList = xmlHttp.responseText.split(";");       // retrieve string from ajax response
                
                var response = ajax.responseText;
                
                if (response.length > 0 && !hidePopup){
                    popupPanel.innerHTML = response;
                    popupPanel.style.visibility = 'visible';
                    currentCompanyID = companyID;
                }else{
                    popupPanel.style.visbility = 'hidden';
                }// if-else
                                
                hidePopup = true;
            }// if
        
        }// function()

        ajax.open("Get","../AjaxProcessing.aspx?Requestor=Common&RequestType=GetCompanyInfo&Criteria=" + companyID,true);
        ajax.send(null);
//    }// if
}

/********************
    Title: fnGetCompanies()
    Author: Steven Ciarleglio
    Purpose: This function gets all companies for a suggestion container.
********************/
function fnGetCompanies(inputControlID,MetaData)
{  
    var AjaxURL = new String();   
         
    var inputControl = document.getElementById(inputControlID); 
    if (inputControl){   
        var Criteria = inputControl.value;
        
        var containerElement = new Object();    
        containerElement = fnCreateElement('',"ajaxCompanySuggest","div","","ajaxCompanySuggest");                
        
        Criteria = Criteria.replace("&", "%26");
        
        if(Criteria.length>=1)
        {
            var MetaElements = new Array();
            MetaElements = MetaData.split(";");
            
            var Requestor = new String();
            var RequestType = new String();
            var Params = new String();
            
            Requestor = MetaElements[0];
            RequestType = MetaElements[1];
                           
            if(MetaElements[2]!=undefined)
            {
                for(i=2;i<MetaElements.length;i++)
                {
                    Params = Params + MetaElements[i];
                }
            }
            
            AjaxURL = "../AjaxProcessing.aspx?Requestor="+Requestor+"&RequestType="+RequestType;
                   
            if(Params!=undefined)
            {
                AjaxURL = AjaxURL + "&" + Params;
            }//endif
            AjaxURL = AjaxURL + "&Criteria=" + Criteria;
                                   
            fnGetCompanySuggestion(inputControlID,containerElement,AjaxURL);
        }//if
        else
        {
            containerElement.style.visibility = "hidden";
        }//else-if   
    }// if
}
    
/*********************
    Title: fnGetSuggestion()
    Author: Steve Ciarleglio
    Purpose: This function populates a suggestion box with a list string. A link
             is created for each string in the suggestion box and the text is set
             to get inserted into an input control when the link is clicked.
    Parameters: inputControlID - client side id of input control to get the selected value
                containerBoxID - id of div container to hold suggestion links in
                ajaxurl - url to do ajax processing (must return a ";" delimited string in response)
*********************/
function fnGetCompanySuggestion(inputControlID,container,ajaxurl)
{

        var ajax = createAjaxHandle();
        ajax.onreadystatechange = function(){
            if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText){
		    
                var datalist = new String();
                suggestionList = ajax.responseText.split(";");       // retrieve string from ajax response
                                           
                container.style.visibility = "hidden";
                    
                // check if there are suggestions
                if(suggestionList[0]=="NO_SUGGESTION")
                {
                    container.style.visibility="hidden";
                }
                else
                {
                    
                    // loop through suggestion list and create link
                    for(var i=0;i<suggestionList.length-1;i++)
                    {
                        if(suggestionList[i]===undefined)
                        {                            
                        }
                        else
                        {
                            // create link for each suggestion
                            datalist = datalist + "<a class='ajaxLink' onclick='fnAssignCompanySelected(this.id,this.name);' name='"+ suggestionList[i]+"' id='" + inputControlID + "__"+container.id+"__"+suggestionList[i]+"'>" + suggestionList[i] + "</a><br>";
                            container.innerHTML = datalist;
                        }// if-else
                    }// for
                    
                    if(datalist.length>0 && datalist!=" " && datalist!= "<br>" && datalist!="\n")
                    {                        
                        container.style.top = findPosY(inputControlID)+20 + "px";
                        container.style.left = findPosX(inputControlID) + "px";                                                
                        container.style.visibility = "visible";
                        
                    }// if
                    else
                    {
                        container.style.visibility="hidden";
                    }
                }// if-else    
                
                delete ajax;        
            }// if
        
        }// function()
        
        AjaxURL = ajaxurl;
        ajax.open("Get",AjaxURL,true);
        ajax.send(null);     
}

function findPosX(element)
{
    var obj = new Object();
     if (element.nodeName){
        obj = element;
    }else{
        obj = document.getElementById(element);
    }// if-else

    var curleft = 0;
    if(obj != null){
        if (obj.offsetParent)
            while(1) 
            {
              curleft += obj.offsetLeft;
              if(!obj.offsetParent)
                break;
              obj = obj.offsetParent;
            }
        else if(obj.x)
            curleft += obj.x;
    }// if
    return curleft;
}

function findPosY(element)
{
    var obj = new Object();
    if (element.nodeName){
        obj = element;
    }else{
        obj = document.getElementById(element);
    }// if-else
    
    var curtop = 0;
    if(obj != null){
        if(obj.offsetParent)
            while(1)
            {
              curtop += obj.offsetTop;
              if(!obj.offsetParent)
                break;
              obj = obj.offsetParent;
            }
        else if(obj.y)
            curtop += obj.y;
    }// if
    return curtop;
}
function findPos(element)
{
    var obj = new Object();
    if (element.nodeName){
        obj = element;
    }else{
        obj = document.getElementById(element);
    }// if-else
    
    var curtop = 0;
    var curleft = 0;
    if(obj != null){
        if(obj.offsetParent){
            while(1)
            {
              curtop += obj.offsetTop;
              curleft += obj.offsetLeft;
              if(!obj.offsetParent)
                break;
              obj = obj.offsetParent;
            }
        }else{
            if(obj.y)
                curtop += obj.y;
                
            if (obj.x)
                curleft += obj.x;
        }// if-else
    }// if
    return {x:curleft, y:curtop};
}
function findRelativePos(positionElement, relativeElement)
{
    // set positioning element
    var obj = new Object();
    if (positionElement.nodeName){
        obj = positionElement;
    }else{
        obj = document.getElementById(positionElement);
    }// if-else
    
    // set relative element
    var relativeEle;
    if (relativeElement.nodeName){
        relativeEle = relativeElement;
    }else{
        relativeEle = document.getElementById(relativeElement);
    }// if-else
    
    var top = 0;
    var left = 0;
    
    // get position if both elements exists
    if(obj != null && relativeEle != null){
    
        // set relative positioned element to top of its parent
        relativeEle.style.top = "0px";
        relativeEle.style.left = "0px";
      
        var positionEleXY = findPos(obj);
        var relEleXY = findPos(relativeEle);
        
        top = positionEleXY.y - relEleXY.y;
        left = positionEleXY.x - relEleXY.x;        
      
    }// if
    return {y:top, x:left};
}
/***************
    Title: fnGetRecallDistributions()
    Author: Yeng Yang
    Purpose: This function does an ajax callback to retrieve a control
            containing the list of recall distribution areas. The control
            is then added to the container.
    Parameters: containerID - id of container to old control
                dropdownID - id of type dropdown
                valueControlID - id of control that contains selected values
***************/
function fnGetRecallDistributions(containerID, dropdownID, valueControlID){
        
    var dropdown = document.getElementById(dropdownID);
    var valControl = document.getElementById(valueControlID);
    var selectedValues = "";
    
    if (valControl != null){
        selectedValues = valControl.value;
    }// if
    
    if (dropdown != null){
        var distributionType = dropdown[dropdown.selectedIndex].value;
       
        UI_fdaRECALLS_UControls_DistributionControl.GetRecallDistributions(containerID, distributionType, selectedValues, valueControlID
            , function(result){
                document.getElementById(containerID).innerHTML = result.value;
            });
    }// if
}

/****************
    Title: fnSetValueByCheckBox()
    Author: Yeng Yang
    Purpose: This function adds or removes the text values of checkboxes
            within a value control. If the checkbox is checked the text
            is added, if the checkbox is unchecked the text is removed.
    Parameters: valueHolderID - id of control that hold the string value
                checkBoxHandle - handle of the calling checkbox
****************/
function fnSetValueByCheckBox(valueHolderID, checkBoxHandle){
    var valControl = document.getElementById(valueHolderID);

    if (valControl != null && checkBoxHandle != null){
        var newStr = valControl.value.toUpperCase();
        var pattern = new RegExp("(^|\\s|,)" + checkBoxHandle.nextSibling.innerText.toUpperCase() + "($|\\s|,)", "mg");
        var idx = newStr.search(pattern);
        
        if (checkBoxHandle.checked){
            // add string if not present
            if (idx == -1){
                newStr += " " + checkBoxHandle.nextSibling.innerText.toUpperCase();
            }// if
        
        }else{
        
            while(idx > -1){
                newStr = newStr.replace(pattern, " ");   
                idx = newStr.search(pattern);         
            }// while
        
        }// if-else
        
        valControl.value = newStr;
    }// if
}


var infoPopupMouseOver = false;

/*************************
Title: fnHideInfoPopup()
Description: This function hides a contract info popup container.
Parameters: containerID - id of contract info container to hide
*************************/
function fnHideInfoPopup(containerID){
    var container = document.getElementById(containerID);
    
    // get ajax container if parameter container does not exist
    if (container == null){
        container = document.getElementById("ajaxInfoPopup");
    }// if
    
    // hide container if container exists
    if (container != null){
        container.style.visibility = 'hidden';
    }// if
    
    infoPopupMouseOver = false;
}

/*********************
Title: fnShowInfoPopup()
Description: This function shows an info popup container. If the 
             passed in container does not exist, a new container 
             is created and positioned under the hover control.
Parameters: contractID - id of contract to load
            callingControlID - id of the calling control
            containerID - id of container to show contract info in
            hoverPosition - position to hover popup if a new container is created - values are "right" or "bottom"
            requestType - type of info to request
            offsetX - x value to offset popup position
            offsetY - y value to offset popup position
*********************/
function fnShowInfoPopup(parameters, callingControlID, containerID, hoverPosition, requestType, offsetX, offsetY){
        
    
    infoPopupMouseOver = true; 
        
    var popupPanel = document.getElementById(containerID);
    
    // create new popup if container does not exist
    if (popupPanel == null){
    
        // create element if it does not exist
        if (document.getElementById("ajaxInfoPopup") == null){
            retval = fnCreateElement("", "ajaxInfoPopup", "div", "", "infoPopupStyle");
        }// if
        
        popupPanel = document.getElementById("ajaxInfoPopup");
       
        // position new element by parent if parent exists
        if (callingControlID != ""){
            // set popup position
            if (hoverPosition == "right"){
                // to the right of hover control
                popupPanel.style.top = findPosY(callingControlID) + "px";
                popupPanel.style.left = findPosX(callingControlID) + document.getElementById(callingControlID).offsetWidth+2 + "px";
            }else{
                // default bottom
                popupPanel.style.top = findPosY(callingControlID) + 16 + offsetX + "px";
                popupPanel.style.left = findPosX(callingControlID) - 5 + offsetY + "px";
            
            }// if-else 
        }// if
    }// if
                   
    
    var ajax = createAjaxHandle();
    ajax.onreadystatechange = function(){
            {
            var x;
            x = "";
            }
        if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText){
        
            // get response and put into popup container's innerHTML
            var response = ajax.responseText;
            
            if (response.length > 0 && infoPopupMouseOver){
                popupPanel.innerHTML = response;
                popupPanel.style.visibility = 'visible';
            }else{
                popupPanel.style.visibility = 'hidden';
            }// if-else
            
            delete ajax;
        }// if
    }// function()
        
    ajax.open("GET","../AjaxProcessing.aspx?Requestor=Common&RequestType="+requestType+"&Criteria=" + parameters,true);
    ajax.send(null);  
   
}

/***
    Title: fnKeepAlive()
    Author: Yeng Yang
    Description: This function keeps a session alive by doing ajax callbacks to the server.
    Parameters: [interval] - pause interval to do ajax callback (minutes)
                [randomIdx] - index count used as an incrementing query string parameter to
                              prevent the browser from caching the ajax callback.
***/
function fnKeepAlive(interval){
    
    // do ajax call back
//    createXMLHttpRequest();
//    xmlHttp.onreadystatechange = function(){
//        if(xmlHttp.readyState == 4 && xmlHttp.status == 200 && xmlHttp.responseText){
//            var response = xmlHttp.responseText;
//        }// if
//    }// function    
//    xmlHttp.open("GET", "../AjaxProcessing.aspx?Requestor=KeepAlive&callbackdate=" + Date(), true);
//    xmlHttp.send("");
//    
//    // reset a bit and call again - recursive call forever (or until browser is closed)
//    setTimeout("fnKeepAlive(" + interval + ")", interval * 60 * 1000);
    
}

var mouseOverMarkup = '';
/***
Title: fnGetMarkupDetails()
Author: Yeng Yang
Description: This function displays a popup of contract markup details.
***/
function fnGetMarkupDetails(ele, popupID, popupClass, basePrice, markupAmount, offsetX, offsetY){
    
    // set hide attribute
    ele.onmouseout = function(){
        document.getElementById(popupID).style.visibility = 'hidden';
        mouseOverMarkup = mouseOverMarkup.replace(popupID, '');
    }// function

    // create element if it does not exist
    if (document.getElementById(popupID) == null){
        retval = fnCreateElement("", popupID, "div", "", popupClass);
    }// if
    
    // set mouse over flag
    mouseOverMarkup += popupID;
    
    var popupPanel = document.getElementById(popupID);
    
    // set popup position
    popupPanel.style.visibility = 'hidden';
    popupPanel.style.top = findPosY(ele.id) + offsetY + "px";
    popupPanel.style.left = findPosX(ele.id) + offsetX + "px";
    
    var ajax = createAjaxHandle();
    ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText)
        {
            var response = ajax.responseText;
            
            if (response.length > 0 && mouseOverMarkup.search(popupID) > -1){
                popupPanel.innerHTML = response;
                popupPanel.style.visibility = 'visible';
            }else{
                popupPanel.style.visbility = 'hidden';
            }// if-else              
         
            delete ajax;
        }// if
    
    }// function()

    ajax.open("Get","../AjaxProcessing.aspx?Requestor=Common&RequestType=MarkupDetails&baseprice=" + basePrice + "&markupamount=" + markupAmount,true);
    ajax.send(null); 
}

var showPriceParityPopup = false;

/***
Title: fnHidePriceParityFacilities()
Author: Yeng Yang
Description: This function hides a priceparity popup. This is used to link to a mouseout event.
***/
function fnHidePriceParityFacilities(){
    var popupPanel = document.getElementById("priceParityFacilities");
    if (popupPanel){
        popupPanel.style.visibility = 'hidden';
    }// if
    
    showPriceParityPopup = false;

}

/***
Title: fnGetPriceParityFacilities()
Author: Yeng Yang
Description: This function gets price parity facilities and displays it in a popup.
Parameters:
    ele         - current handle of calling element (this)
    guid        - guid of user's current session
    clientid    - id of facility client
    oemitemid   - id of oem item
    price       - price for facility po history to match
    type        - type of price to match (High or Low)
    offsetX     - pixels to horizontally offset popup to calling element
    offsetY     - pixels to vertically offset popup to calling element
***/
function fnGetPriceParityFacilities(ele, guid, clientid, oemitemid, price, type, offsetX, offsetY){

    var popupPanel = document.getElementById("priceParityFacilities")

    // create element if it does not exist
    if (popupPanel == null){
        popupPanel = fnCreateElement("", "priceParityFacilities", "div", "", "priceParityFacilitiesStyle");
    }// if
    
    // set popup position
    popupPanel.style.visibility = 'hidden';
    popupPanel.style.top = findPosY(ele.id) + offsetY + "px";
    popupPanel.style.left = findPosX(ele.id) + offsetX + "px";
    showPriceParityPopup = true;
    
    // set ajax callback
    var ajax = createAjaxHandle();
    ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText)
        {
            var response = ajax.responseText;
            
            // set rendered control
            if (response.length > 0 && showPriceParityPopup){
                popupPanel.innerHTML = response;
                popupPanel.style.visibility = 'visible';
            }else{
                popupPanel.style.visbility = 'hidden';
            }// if-else 
    
        }// if
    }// function

    // do ajax callback
    var url = "../AjaxProcessing.aspx?Requestor=Common&RequestType=priceparityfacilities";
    url += "&guid=" + guid;
    url += "&clientid=" + clientid;
    url += "&oemitemid=" + oemitemid;
    url += "&pricetype=" + type;
    url += "&price=" + price;
    ajax.open("Get", url,true);
    ajax.send(null);

}

var showGenericList = false;

/***
Title: fnHidePriceParityFacilities()
Author: Yeng Yang
Description: This function hides a priceparity popup. This is used to link to a mouseout event.
***/
function fnHideGenericPopup(popupName){

    if (typeof popupName == "undefined") {
        popupName = "genericpopup";
    }// if

    var popupPanel = document.getElementById(popupName);
    if (popupPanel){
        popupPanel.style.visibility = 'hidden';
    }// if
    
    showGenericList = false;

}

var popupList = Array();
/***
Title: fnAddToPopupList()
Author: Yeng Yang
Description: This function checks if already in popup list and adds a value to the popupList.
***/
function fnAddToPopupList(val){
    
    var found = false;
    for (var i = 0; i < popupList.length; i++){
        if (popupList[i] == val){
            found = true;
            break;
        }//  if
        
    }// for
    
    if (!found){
        popupList[popupList.length + 1] = val;
    }

}
/***
Title: fnShowGenericPopup()
Author: Yeng Yang
Description: This function does an ajax callback to load a usercontrol 
             dynamically and displays it in a generic popup.
***/
function fnShowGenericPopup(callingElement, controlPath, jsonParams, offsetX, offsetY, popupName, evt, keepOnScreen, keepOnScreenOffsetY, turnOffCache, keepOnScreenOffsetX){
        
    var e = evt || window.event;
    
    // stop event bubble
    if (e.stopPropagation){
        e.stopPropagation();
    }else{
        e.cancelBubble = true;
    }// if-else
    
    // initialize optional parameters
    if (typeof popupName == "undefined") {
        popupName = "genericpopup";
    }// if
    if (typeof keepOnScreen == "undefined"){
        keepOnScreen = false;
    }// if
    if (typeof keepOnScreenOffsetY == "undefined"){
        keepOnScreenOffsetY = 0;
    }// if
    if (typeof turnOffCache == "undefined"){
        turnOffCache = false;
    }// if

    // register popup to list
    fnAddToPopupList(popupName);
    
    var popupPanel = document.getElementById(popupName)

    // create element if it does not exist
    if (popupPanel == null){
        popupPanel = fnCreateElement("", popupName, "div", "", "genericItemListStyle");
    }// if
    
    // set popup position
    popupPanel.style.visibility = 'visible';
    popupPanel.innerHTML = "Loading...";
    popupPanel.style.top = findPosY(callingElement) + offsetY + "px";
    popupPanel.style.left = findPosX(callingElement) + offsetX + "px";
    showGenericList = true;
    
    // get uid from query string
    var uid = GetQueryString(parent.document.URL, "UID");
        
    // set ajax callback
    var ajax = createAjaxHandle();
    ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText)
        {
            var response = ajax.responseText;
            
            // set rendered control
            if (response.length > 0 && showGenericList && response.substring(0, 5).toUpperCase() != "ERROR"){
                popupPanel.innerHTML = response;
                popupPanel.style.visibility = 'visible';
                
                // keep popup on screen view if flag is set and if browser height is > 500px
                if (keepOnScreen && document.body.clientHeight > 500){
                
                    // get popup bottom left position
                    var popupBottomLeft = (popupPanel.clientHeight + popupPanel.offsetTop);
                    // calculate out of screen percentage that determines how much a popup needs to go out
                    // of screen before repositioning
                    var outOfScreenPercent = (70 - Math.abs((document.body.clientHeight - 500)/100 * 20))/100;
                    
                    // check if reposition is needed
                    if (popupBottomLeft > document.body.clientHeight
                        && (popupBottomLeft - document.body.clientHeight) > (popupPanel.clientHeight * outOfScreenPercent)){
                        // reposition popup
                        popupPanel.style.top = popupPanel.offsetTop - popupPanel.clientHeight - offsetY - keepOnScreenOffsetY + "px";
                    }// if     
                               
                }// if
                
                // keep on screen X axis
                if (keepOnScreen && (popupPanel.clientWidth + popupPanel.offsetLeft) >= document.body.clientWidth){
                   var keepOnScreenOffset = (popupPanel.clientWidth + popupPanel.offsetLeft) - document.body.clientWidth;
                   popupPanel.style.left = popupPanel.offsetLeft - keepOnScreenOffset - keepOnScreenOffsetX;
                    
                }// if
                
            }else{
                popupPanel.style.visbility = "hidden";
                
                if (response.substring(0, 5).toUpperCase() == "ERROR"){
                    alert(response);
                }// if
            }// if-else 
    
            delete ajax;
        }// if
        
    }// function


    // evaluate json string
    var obj = fnEvaluateJSON(jsonParams);

    // send request
    var url = "../AjaxProcessing.aspx?Requestor=Common&RequestType=dynamicpopup&controlpath=" + controlPath;
    url += "&UID=" + uid;
    
    for (var i = 0; i < obj.parameters.length; i++){
        url += "&" + obj.parameters[i].key + "=" + obj.parameters[i].value;
    }// for
    
    if (turnOffCache){
        url += "&date=" + new Date().getTime();
    }// if
    
    //url += "&proc=" + storedproc;
    //url += "&where=" + whereclause;
    //url += "&field=" + bindingfield;
    
    ajax.open("Get", url, true);
    ajax.send(null);
    
}


/***
Title: fnSaveTracking();
Author: Yeng Yang
Description: This function saves a credit tracking record.
***/
function fnSaveTracking(jsonObj, imageId){

    // get uid from query string
    var uid = GetQueryString(parent.document.URL, "UID");
    
    // set ajax callback
    var ajax = createAjaxHandle();
    ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText)
        {
            var response = ajax.responseText;   
            if (response == "ERROR SAVING"){
                alert("Error Saving Record");
                trackingSaved = false;
            }else{
                trackingSaved = true;
                
            }// if-else
            
            delete ajax;
        }// if
        
    }// function

    // send request
    var url = "../AjaxProcessing.aspx?UID=" + uid
    url += "&Requestor=CreditTracker&RequestType=savetracking";
    url += "&jsonobj=" + escape(jsonObj);   
    ajax.open("Get", url, true);
    ajax.send(null);
    
    trackingValueChanged = false;    
    
    // set status image
    fnSetStatusImage(jsonObj, imageId);
}

/*
Title: fnSetStatusImage()
Author: Yeng Yang
Description: This function sets a tracking status image.
*/
function fnSetStatusImage(jsonObj, imageId){

    // get uid from query string
    var uid = GetQueryString(parent.document.URL, "UID");
    
    // set ajax callback
    var ajax = createAjaxHandle();
    ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200 && ajax.responseText)
        {
            var response = ajax.responseText;  
            var img = document.getElementById(imageId); 
            if (response.length > 0 && response != "ERROR" && img){
               img.src = "http://" + document.location.host + response;
               img.onmouseout = function(){ this.src = response;};
            }// if
            
            delete ajax
        }// if
    }// function

    // send request
    var url = "../AjaxProcessing.aspx?Requestor=CreditTracker&RequestType=statusimage";
    url += "&UID=" + uid;
    url += "&jsonobj=" + escape(jsonObj);   
    ajax.open("Get", url, true);
    ajax.send(null);
}