function AjaxAutoComplete(urlString, tagName) {
    var m_isIE;
    var m_req;
    var m_dropDown;
    var m_inputElementId;
    var m_inputElement;
    var m_menuPopup;
    var m_rootTagName;
    var m_url;
    var m_selectedIndex = 0;
    var m_searchQueryParam;
	var m_dependElement;
	var m_dependQueryParam;

    m_url = urlString;
    m_rootTagName = tagName;
    /**
     * function initialize()
     * create the container DIV and assign input handlers
     */
    this.initialize = initialize;
	
	function initialize(inputElement, searchQueryParam, dependElement, dependQueryParam) {
		browser=navigator.appName;
		if(browser=='Microsoft Internet Explorer') {
			m_isIE=1;
		}
        // create drop down
        m_inputElement = document.getElementById(inputElement);
		m_searchQueryParam = searchQueryParam;
		if(dependElement) {
			m_dependElement = document.getElementById(dependElement);
			m_dependQueryParam = dependQueryParam;
		}
        m_menuPopup = document.createElement('DIV');
        m_menuPopup.id = 'menu-popup';
        m_menuPopup.className='autoCompleteShow';
        m_menuPopup = m_inputElement.parentNode.insertBefore(m_menuPopup, m_inputElement.nextSibling);
        m_menuPopup.style.left = getLeft(m_inputElement) + "px";
        m_menuPopup.style.top = getTop(m_inputElement) + m_inputElement.offsetHeight + "px";

		// create a drop-down table
		m_dropDown = document.createElement('table');
		m_dropDown.id = 'suggestions';
		m_dropDown.className = 'autoComplete';
		
		m_menuPopup.appendChild(m_dropDown);

        m_inputElement.onkeyup=autoComplete;
        m_inputElement.onkeydown=handleKeyEvent;
        m_inputElement.onblur=stopCompletionDelayed;
        //m_inputElement.onfocus=autoComplete;
    }

    /**
     * function initRequest()
     * Initialize the AJAX request
     */
    function initRequest() {
        if (window.XMLHttpRequest) {
            m_req = new XMLHttpRequest();
        } 
        else if (window.ActiveXObject) {
            m_req = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }

    /**
     * function processRequest()
     * handle AJAX callback
     */
    function processRequest() {
        if (m_req.readyState == 4) { // Complete
            if (m_req.status == 200) { // OK response
                parseMessages(); // parse response XML
            }
            else if (m_req.status == 204) {
                clearDropdown();
            }
        }
    }

    /**
     * function autoComplete()
     * handles the user keyboard input
     */
    function autoComplete(evt) {
        if (!evt) { 
            evt = window.event;
        }
        if(evt.keyCode == 37 || evt.keyCode == 38 ||
            evt.keyCode == 39 || evt.keyCode == 40 ||
			evt.keyCode == 13 || evt.keyCode == 9) {
        // arrow keys - no need to call server
            return;
        }
        
        var type = escape(m_inputElement.value);
        
        if(type.length == 0) {
			clearDropdown();
            m_menuPopup.className='autoCompleteHide';
            return;
        }
        // make AJAX call
        initRequest();
        m_req.onreadystatechange = processRequest;
        var finalUrl = m_url + "&" + m_searchQueryParam +"=" + escape(m_inputElement.value);
		if(m_dependElement != null) {
			finalUrl = finalUrl + "&" + m_dependQueryParam + "=" + escape(m_dependElement.value);
		}
        m_req.open("GET", finalUrl, true);
        m_req.send(null);
		m_menuPopup.className='autoCompleteShow';
    }

    /**
     * function stopCompletion()
     * hide the drop-down when the user selects an entry or clicks outside the drop-down
     */
	this.stopCompletion = stopCompletion;
    function stopCompletion() {
        clearDropdown();
        m_menuPopup.className='autoCompleteHide';
    }

    /**
     * function initialize()
     * hide the drop-down after a short delay
     */
    function stopCompletionDelayed() {
        window.setTimeout(stopCompletion, 300);
    }

    /**
     * function initialize()
     * parse the response (in XML) gotten from the server
     * and create the drop-down list
     */
    function parseMessages() {
        clearDropdown();
        var response = m_req.responseXML;
        if(response != null) {
            var rootElement = response.getElementsByTagName(m_rootTagName).item(0);
            if(rootElement != null)
            {
                if(rootElement.childNodes.length)
                {
                    for (loop = 0; loop < rootElement.childNodes.length; loop++) {
                        var name = rootElement.childNodes[loop].firstChild.nodeValue;
                        appendRow(name, loop);
                    }
                    m_selectedIndex = rootElement.childNodes.length;
					//m_menuPopup.className='autoCompleteShow';
                }
            }
        }
    }

    /**
     * function clearDropDown()
     * clear the drop-down list
     */
    function clearDropdown() {
		//m_menuPopup.className='autoCompleteHide';
        if (m_dropDown) {
            /*while (m_dropDown.firstChild) {
                    m_dropDown.removeChild(m_dropDown.firstChild);
            }*/
			for (loop = m_dropDown.childNodes.length -1; loop >= 0 ; loop--) {
				m_dropDown.removeChild(m_dropDown.childNodes[loop]);
				//m_dropDown.deleteRow(loop);
			}
        }
    }

    /**
     * function initialize()
     * dynamically create the drop-down list
     */
    function appendRow(name, index) {
        var nameCell;
		var row = m_dropDown.insertRow(m_dropDown.rows.length);
		nameCell = row.insertCell(0);

        nameCell.onclick = function() {
            m_inputElement.value = name;
            stopCompletion();
        }
        nameCell.onmouseover = function() {
            if(m_dropDown) {
                resetRowClassName();
            }
            this.className='mouseOver';
			//m_inputElement.value = name;
            m_selectedIndex = index;
        }
        nameCell.className = '';
        nameCell.appendChild(document.createTextNode(name));
    }

    /**
     * function handleKeyEvent()
     * handle keyboard events
     */
    function handleKeyEvent(evt) {
        if (!evt) { 
            evt = window.event;
        }
        
        if(!evt || !m_dropDown) return;
        numRows = 0;
        if(evt.keyCode == 38 || evt.keyCode == 40) {
            resetRowClassName(); // reset highlight on hover
        }
        switch(evt.keyCode) {
			case 13: case 9:// Enter key
				m_inputElement.value=m_dropDown.rows[m_selectedIndex].firstChild.innerHTML;
				stopCompletion();
				stopEvent(evt);
				return false;
            case 40:	// arrow down
                ++m_selectedIndex;
                numRows=m_dropDown.rows.length;

                if(m_selectedIndex>=numRows) {
                    m_selectedIndex = 0;
                }
                m_dropDown.rows[m_selectedIndex].firstChild.className='mouseOver';
				//m_inputElement.value=m_dropDown.rows[m_selectedIndex].firstChild.innerHTML;
                break;
            case 38:	// arrow up
                if (m_selectedIndex >= 1) {
                    --m_selectedIndex;
                }
                else {
                    m_selectedIndex = numRows-1;
                }
                m_dropDown.rows[m_selectedIndex].firstChild.className='mouseOver';
				//m_inputElement.value=m_dropDown.rows[m_selectedIndex].firstChild.innerHTML;
        }
    }

    /**
     * function resetRowClassName()
     * reset highlighted entry in the drop-down list
     */
    function resetRowClassName() {
        numRows=m_dropDown.rows.length;
        for (loop = numRows-1; loop >= 0 ; loop--) {
			m_dropDown.rows[loop].firstChild.className='';
        }
    }

	function addEvent(obj,event_name,func_name){
		if (obj.attachEvent){
			obj.attachEvent("on"+event_name, func_name);
		}else if(obj.addEventListener){
			obj.addEventListener(event_name,func_name,true);
		}else{
			obj["on"+event_name] = func_name;
		}
	}

	// Stop an event from bubbling up the event DOM
	function stopEvent(evt){
		if(!evt.stopPropagation)
		{
			evt.cancelBubble = true;
		}
		if (evt.cancelable) {
			evt.stopPropagation();
			evt.preventDefault();
		}
	}


    function getLeft(element){
        var targetLeft = 0;
        if (element.offsetParent) {
            while (element.offsetParent) {
            targetLeft += element.offsetLeft;
                element = element.offsetParent;
            }
        } else if (element.x) {
            targetLeft += element.x;
        }
        if(m_isIE) {
            targetLeft += 6;
        }
        return targetLeft;
    }
	
    function getTop(element){
        var targetTop = 0;
        if (element.offsetParent) {
            while (element.offsetParent) {
            targetTop += element.offsetTop;
                element = element.offsetParent;
            }
        } else if (element.y) {
            targetTop += element.y;
        }
        if(m_isIE) {
            targetTop += 4;
        }
        return targetTop;
		alert(targetTop);
    }
}