///////////////////////////////////////////////////////////////////////////////
// javascript module
// name: KeyListWnd.js
// author: W.Bergmueller, conplementAG
// CreateDate: 25.Feb. 2008
//
// rj2652: übrige Kommentare entfernt, wegen Problemen mit empirix - OneSight-Messungen
//
// usage of suggest list is explained in document livelink91/cgi/cssuggest/doku/KeyListWnd?Doku.doc
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// global variables
///////////////////////////////////////////////////////////////////////////////
// timestamp of last keystroke
var _timeStamp = 0;
// flag, indicates if timer is already active
var _timerActive = false;
// timer id for intervall timer that checks time elapsed sind last keypress
var _timerID = 0;
// id of the search input text field, default is id of current SLS header,  may be set with init function
var _searchInputID = "query";
// id of the search data text field, default is querydata, may be set with init function
var _searchDataID = "querydata";
// icon path for icons in the suggestlist popupd div, should be set with init function
var _iconPath = "icons";
// GUI string for back button, must be set with init function
var _backStr = "back";
// GUI string for next button, must be set with init function
var _nextStr = "next"
// number of lines (=suggests), div height depends on this number, must be set with init function
var _lines = 5;
// region
var _region = "WW";
// language
var _lang = "de";
// oracleText
var _oracleText = "1";
// delay time, suggest list will pop up delayTime after last keypress
var _delay = 0;
// url to the data source of the search query
var _queryPath = "suggest2.asp";
// last requested query
var _lastQuery;
// use client protocol for server callbacks
var _useClientProtocol = true;
// use caching of responses on server
var _useCaching = true;
// limit for display text, longer texts will be clipped, length can be set with init function
var _maxTextLength = 40;
// target frame for the left link (arrow), that leads to the detail product view
var _detailTarget = "_blank";
// url path to the detail product view
var _productPath = "http://support.automation.siemens.com/$region$/view/$lang$/";
// maximum height of suggest window
var _maxHeight;
// width of suggest window
var _width;
// flag indictes if the window shall be have a fix bottom line if it shrinks due to few suggest items
var _alineBottom = false;
// window top position
var _topPos;
// window left position
var _leftPos;
// minimum text lenght after wich starts suggest list
var _minLength = 3;
// flag, if lupe icon shallbe present
var _showLupe = true;
// netmode is dummy param in data source interface for future use
var _netmode = 0;
// flag, indicates if the suggest list can be closed if input looses focus
var _canClose = true;
// aux nod ein diocument to hold xml response data for firefox
var _xmlDivFF;
// flag indicates, if list shall be opened on focus (default true, explicit false after onSelectMLFB)
var _openOnFocus = true;
// flag indicates, if data source shall provide the reduced result set (only complete mlfbs) for NL
var _reducedResultSet = false;
// flag indictaes if the suggest list has been closed by the close button
// i.e. it will not be displayed on focus but only after new input
var _windowClosed = false;

// cursor keys control
// current position if highlight bar, top line = 0
var _cursorPos = -1;
// actual number of line displayed currently
var _numberOfLines = 0;
// is back button available
var _backAvailable = false;
// is next button available
var _nextAvailable = false;
// current page number
var _currentPage = 0;
// internal mnemo code for cursor keys: up, down, pageUp, pageDown, pos1, end
var _cursorCmd = "";

var _enableErrMsg = false;
///////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
// functions for external call when this module is used

///////////////////////////////////////////////////////////////////////////////
// initializes the suggest popup div
// params:
// left: left position of div in px
// top: top position of div in px
// width: width of div in px
// lines: number of lines (=suggests)
// headerStr: GUI string for the header bar
// backStr: GUI string for the back button
// nextStr: GUI string for the next button
// delay: delay time in msec  for popup
// lang: current language
// region: current region
// createDiv: flag, if div shall be created
// containerID: if div shall be inserted into an existing tag, provide id here, else div will be inserted into document
///////////////////////////////////////////////////////////////////////////////
function initKeyListWnd(left, top, width, lines, headerStr, backStr, nextStr, delay, lang, region, createDiv)
{
	_lines = lines;
	_backStr = backStr;
	_nextStr = nextStr;
	_delay = delay;
	_lang = lang;
	_region = region
	_topPos = top;
	_leftPos = left;
	_width = width;
	// try to set the text length according to div width
	_maxTextLength = Math.round((width-50)/6) - 1;
	if (_maxTextLength < 1)
		_maxTextLength = 1;
		

	_maxHeight = calcDivHeight(lines, true);
	var height = _maxHeight;
	var str = "<div id='divKeyList' class='lsList' onMouseDown='onMouseDownDiv();' style='top: " + top + "px; left: " + left + "px; width: " + width + "px; height: " + height + "px; position: absolute; display: none;'>";
	str += "<div id='divKeyListHeader' class='lsPopUpTitleBar' >";
	str += "<img src='" + _iconPath + "/winClose.gif' class='lsPopUpTitleBar' height='13' width='13' align='right'";
	str += " border='0' onclick='closeList()'> <span class='lsPopUpTitleBar'>" + headerStr + "</span>";
	str += "</div>";
	str += "<div id='divKeyListKeys' class='lsKeyList'></div>";
	str += "</div>";
	
	if (createDiv == null)
		createDiv = true;
		
	if (createDiv)
	{
		var containerDiv =	document.createElement("DIV");
		containerDiv.innerHTML = str;
		document.body.appendChild(containerDiv);
	}

	// div for xml data, for firefox	
	_xmlDivFF =	document.createElement("DIV");
	_xmlDivFF.style.display = "none";
	_xmlDivFF.innerHTML = "<test></test>";
	document.body.appendChild(_xmlDivFF);
	
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// initializes the id of the search input field
// optional function if id differs from default params:
// id: id of input element for search field
///////////////////////////////////////////////////////////////////////////////
function initSearchInputID(id)
{
	_searchInputID = id;
	
	try
	{
		var txt = document.getElementById(_searchInputID);
		txt.autoComplete = "off";	
	}
	catch(ex)
	{
	}
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// initializes the id of the search data field
// optional function if id differs from default params:
// id: id of input element for search field
///////////////////////////////////////////////////////////////////////////////
function initSearchDataID(id)
{
	_searchDataID = id;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// initializes the icon path that will be inserted into the html fraction of the 
// suggest div popup
// params:
// path: path to icon folder
///////////////////////////////////////////////////////////////////////////////
function initIconPath(path)
{
	_iconPath = path;
}		
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// initializes the query path of the ajax search request
// params:
// queryPath: url for the internal suggest query without params
///////////////////////////////////////////////////////////////////////////////
function initQueryPath(queryPath)
{
	_queryPath = queryPath;
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// sets the flag for using the clients protocol
// params:
// enable: if true use client protocol
///////////////////////////////////////////////////////////////////////////////
function initUseClientProtocol(useClientProtocol)
{
    _useClientProtocol = parseBool(useClientProtocol);
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// sets the max text length for the display text
// params:
// maxTextLength: max number of chars to be displayed in the suggest list line
///////////////////////////////////////////////////////////////////////////////
function initMaxTextLength(maxTextLength)
{
	_maxTextLength = maxTextLength
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// sets the frame target for the detail product view link
// params: 
// detailTarget: target attribute for the detail link (<a> tag) in a suggest line
///////////////////////////////////////////////////////////////////////////////
function initDetailTarget(detailTarget)
{
	_detailTarget = detailTarget;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// sets the url path for the detail product view link
// params: 
// productPath: path into the support web, that displays a detailed product,
// mlfb will be added to the path
///////////////////////////////////////////////////////////////////////////////
function initProductPath(productPath)
{
	_productPath = productPath;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// set the aline flag
// params:
// enable: if true aline at bottom, if false aline at top
///////////////////////////////////////////////////////////////////////////////
function initAlineBottom(enable)
{
    _alineBottom = parseBool(enable);
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// inits the min input text lenght after which the suggest list starts
///////////////////////////////////////////////////////////////////////////////
function initMinLength(len)
{
	_minLength = len;
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// set the show lupe flag
// params:
// enable: if true show lupe icon, if false show only arrow and text
///////////////////////////////////////////////////////////////////////////////
function initShowLupe(enable)
{
    _showLupe  = parseBool(enable);
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// set the reduced result set flag
// params:
// enable: if true query only for complete mlfb
///////////////////////////////////////////////////////////////////////////////
function initReducedResultSet(enable)
{
    _reducedResultSet = parseBool(enable);
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// set netmode
// params:
// netmode: 1 internet, 2 intranet
///////////////////////////////////////////////////////////////////////////////
function initNetmode(netmode)
{
	_netmode = netmode;
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// set netmode
// params:
// oracleText: [0;1]
///////////////////////////////////////////////////////////////////////////////
function initOracleText(oracleText) {
    _oracleText = oracleText;
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// set the errmsg flag. This flag is default false for production.
// The flag should be set to true only for development purpose.
///////////////////////////////////////////////////////////////////////////////
function initEnableErrMsg(enable)
{
    _enableErrMsg = parseBool(enable);
}
///////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
// optional event handler for blur event of text input field
// if this handler is hooked the suggest list will be closed when input looses focus
///////////////////////////////////////////////////////////////////////////////
function onBlurSearchInput(ev)
{
	if (_canClose)
	{
		showList(false);
	}
	else
	{
			// set back focus, so with that the next mouse click outside the list
			// the input looses again focus and fires the blur event 
			// a direct call of setTextFocus would be fine with IE, but is too early for FF.
			// So, to be sure that the focus is set after the field has lost it, set it with delay
			window.setTimeout("setTextFocus()", 200);

	}
		
	_canClose = true;
	
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// sets the focus to the search input field
///////////////////////////////////////////////////////////////////////////////
function setTextFocus()
{
	var txt = document.getElementById(_searchInputID);
	txt.focus();
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// sets the value of an element
///////////////////////////////////////////////////////////////////////////////
function setElementValue(id, val)
{
	var elem = document.getElementById(id);
	if (elem)
	    elem.value = val;
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// gets the value of a named item element
///////////////////////////////////////////////////////////////////////////////
function getNamedItemValue(item, id)
{
    if ((item == null) || (item.attributes == null))
        return "";
    
	var elem = item.attributes.getNamedItem(id);
	if (elem)
	    return elem.value;
}
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
//	event handler for focus event of input field.
//  reactivates the suggest list if there was already somtehing 
///////////////////////////////////////////////////////////////////////////////
function onFocusSearchInput()
{
	if (_openOnFocus && !_windowClosed && !isListVisible())
		showList(true);
		
	_openOnFocus = true;	
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for keypress event,
// suppress default return action in firefox
///////////////////////////////////////////////////////////////////////////////
function onKeyPressSearchInput(ev)
{
    var event = ev;
    if (ev == null)
        event = window.event;

    if (ev.keyCode == 13)
        return false;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// start the interval timer that checks the time elapsed sind last keystroke
///////////////////////////////////////////////////////////////////////////////
function startKeyTimer(ev)
{
    var event = ev;
    if (ev == null)
        event = window.event;

    if (ev == null)
        return;
                
//    alert(event.keyCode);

    if (event.keyCode == 13)        // return
    {
        if (_cursorPos < 0) // nothing selected yet
        {
			document.forms[0].submit();
			return false;
		}

        // if a full qualified mlfb with product link is available, goto product

        // 1. try product link with support usage
        var targetLink = document.getElementById("aLinkMLFB_" + _cursorPos);
        if (targetLink != null)
        {
           // alert("cs product");
            var url = targetLink.href
            window.open(url, _detailTarget);
            return false;
        }
        
        // 2. try search link with support usage
        targetLink = document.getElementById("aLinkSearch_" + _cursorPos);
        if (targetLink != null)
        {
            //alert("cs search");
            var url = targetLink.href
            var str = url.split("'");
            var mlfb = str[1];

            onSearchEx(mlfb);
            return false;
        }
        
        // 3. try product link with newsletter usage
        targetLink = document.getElementById("aLinkSelectMLFB_" + _cursorPos);
        if (targetLink != null)
        {
            //alert("nl product");

            var url = targetLink.href
            var str = url.split("'");
            var mlfb = str[1];
            var text =  unescape(str[3]);
            var dataID =  str[5];

            onSelectMLFB(mlfb, text, dataID);
            return false;
        }
        
        //alert("??");
    }
    else if (event.keyCode == 33)    // page up
    {
        if (_backAvailable)
        {
            if (_cursorPos < 0)
                _cursorPos = 0;

            _cursorCmd = "pageUp";
            onPrevPage(_currentPage, false);

            // cursor display will be updated in callback after load
        }
    }
    else if (event.keyCode == 34)    // page down
    {
        if (_nextAvailable)
        {
            if (_cursorPos < 0)
                _cursorPos = 0;
                
            _cursorCmd = "pageDown";
            onNextPage(_currentPage, false);

            // cursor display will be updated in callback after load
        }
    }
    else if (event.keyCode == 35)    // end
    {
        if (_nextAvailable)
        {
            _cursorCmd = "end";
            onLastPage(_currentPage, false);

            // cursor display will be updated in callback after load
        }
    }
    else if (event.keyCode == 36)    // pos1
    {
        if (_backAvailable)
        {
            _cursorCmd = "pos1";
            onFirstPage(_currentPage, false);

            // cursor display will be updated in callback after load
        }
    }
    else if (event.keyCode == 38)  // cursor up
    {
        if (_cursorPos > 0)
        {
            trMouseOut(_cursorPos);

            _cursorPos--;

            trMouseOver(_cursorPos);
        }
        else
        {
            if (_backAvailable)
            {
                _cursorCmd = "up";
                onPrevPage(_currentPage, false);

                // cursor display will be updated in callback after load
            }
        }
    }
    else if (event.keyCode == 40)  // cursor down
    {
        if (_cursorPos < _numberOfLines - 1 && _numberOfLines != 0)
        {
            trMouseOut(_cursorPos);

            _cursorPos++;

            trMouseOver(_cursorPos);
        }
        else
        {
            if (_nextAvailable)
            {
                _cursorCmd = "down";
                onNextPage(_currentPage, false);

                // cursor display will be updated in callback after load
            }
        }
        
    }
    else    // char for search string
    {
        _timeStamp = new Date().getTime();

	    var txt = document.getElementById(_searchInputID);
    	
	    if (!_timerActive && txt.value.length >= _minLength)
	    {
	        _timerActive = true;
		    _timerID = window.setInterval("onTimer()", _delay);
	    }
	    else
	    {
		    showList(false);
	    }
	}
	
	// suppress default key event handling
	return false;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// internal function, not intended to be called by using webpages


///////////////////////////////////////////////////////////////////////////////
// set the highlight bar after a page change when it has been caused by a cursor 
// key. This function is only called from the callback after a reload, not on a 
// position change within a page.
///////////////////////////////////////////////////////////////////////////////
function updateCursorPos()
{
//    alert(_cursorPos);
    
    if (_cursorCmd == "up")
    {
        // with a page up at the first position, the cursor shall be set at the last
        // position of the provious page
        _cursorPos = _numberOfLines - 1;
        trMouseOver(_cursorPos);
    }

    if (_cursorCmd == "down")
    {
        // With a page down at the last position, the cursor shall be set at the first
        // position of the next page.
        _cursorPos = 0;
        trMouseOver(_cursorPos);
    }

    if (_cursorCmd == "pageUp")
    {
        // with a page up at the first position, the cursor shall be set at the last
        // position of the provious page
        trMouseOver(_cursorPos);
    }

    if (_cursorCmd == "pageDown")
    {
        // With a page down at the last position, the cursor shall be set at the first
        // position of the next page.
        trMouseOver(_cursorPos);
    }

    if (_cursorCmd == "pos1")
    {
        // With a page down at the last position, the cursor shall be set at the first
        // position of the next page.
        _cursorPos = 0;
        trMouseOver(_cursorPos);
    }

    if (_cursorCmd == "end")
    {
        // with a page up at the first position, the cursor shall be set at the last
        // position of the provious page
        _cursorPos = _numberOfLines - 1;
        trMouseOver(_cursorPos);
    }
    
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// convert a string to a bool value
///////////////////////////////////////////////////////////////////////////////
function parseBool(sValue)
{
    var bValue;
    switch (String(sValue).toLowerCase())
    {
        case "true":
            bValue = true;
            break;
        case "false":
            bValue = false;
            break;
        default:
            bValue = false;
            break;
    }

    return bValue;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// close list and set the clos flag, i.e. it will not be displayed on focus
// but only after new input
///////////////////////////////////////////////////////////////////////////////
function closeList()
{
	_windowClosed = true;
	showList(false);
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// load suggest items into div and display it
// params:
// bShow: true= show div, false= hide div
///////////////////////////////////////////////////////////////////////////////
function showList(bShow)
{
	// initial load with page 1
	var divWnd = document.getElementById("divKeyList");

	if (bShow)
	{
		_windowClosed = false;
		
		if (updateSuggestList(1))
		{
		}
		else
		{
			divWnd.style.display = "none";
		}
	}
	else
	{
		divWnd.style.display = "none";
	}
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// performs actions after text update:
// notify client of new position
// set position flags
// display div
// This functtion will be called by the ready state callback of the ajax call
///////////////////////////////////////////////////////////////////////////////
function completeListUpdate(result)
{
    var divList = document.getElementById("divKeyListKeys");
	var divWnd = document.getElementById("divKeyList");

	var leftPos = null;
	var topPos = null;
	
   	if (result == "")
    {
		divWnd.style.display = "none";
        return;
    }
    else if (result == "outdated response")
    {
		// do nothing on outdated response 
		// => if divWnd is currently invisible it will stay invisible
		// => if divWnd is currently visible it will stay visible
		
        // divWnd.style.display = "none";
        // divWnd.style.display = "block";
        return;
    }
    else
    {
        divList.innerHTML = result;
    	divWnd.style.display = "block";
    }

    // display again highlight bar if page change has been caused by cursor key 
    updateCursorPos();
    
    
	try
	{
		// optional callback for webpage
		leftPos = onGetSuggestLeftPosition();
	}
	catch(ex)
	{
		// exception may occur if callback is not implemented
		// => windows appears at initial position
	}
	
	try
	{
		// optional callback for webpage
		topPos = onGetSuggestTopPosition();
	}
	catch(ex)
	{
		// exception may occur if callback is not implemented
		// => windows appears at initial position
	}
	
	var newPos = false;

	if (leftPos != null)
	{
		_leftPos = leftPos;
		newPos = true;
	}
	if (topPos != null)
	{
		_topPos = topPos;
		newPos = true;
	}
	
	if (newPos)
		setDivPosition(_leftPos, _topPos);
		
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// updates the content of the suggest list
// launches a query and fills the result inot the div
// params:
// pageNo: pagenumber of the result set
// return: true if at least one item found, false if nothing found
///////////////////////////////////////////////////////////////////////////////
function updateSuggestList(pageNo)
{
	// get query from control
	var txt = document.getElementById(_searchInputID);
	var query  = txt.value; 
	
	// clean up query by trimming and compressing
	query = trim(query);
	query = compress(query);
	
	//alert('updateSuggestList::trimmed query (with token XXX): ' + query + 'XXX');
	
	// is queries length at least the  minimum length 
	if (query.length < _minLength)
	{
		//alert('updateSuggestList::min length check: query too short => no work');
		return false;
	}
	
	// is query different from last query
	if (_lastQuery == query)
	{
		//alert('updateSuggestList::last query check: no change => no work');
		// return true to keep suggest list displayed in UI
		return true;
	}
		
	// set last requested query
	_lastQuery = query;
		
	var url = makeQueryURL(pageNo, query);
	loadSuggestInfos(url);
	
	return true;
}
///////////////////////////////////////////////////////////////////////////////

function trim (val)
{
	return val.replace(/^\s+/, '').replace(/\s+$/, '');
}

function compress (val)
{
	while (val.search('  ') != -1)
	{
		val = val.replace('  ', ' ');
		//alert('compress::double blank check: found and replaced');
	}

	return val;
}

///////////////////////////////////////////////////////////////////////////////
// calcs the height of the div
// if there are not enough items found to fill the provided space,
// the div will be shrinked down to the needed height
// params:
// numberOfLines: number of lines that need to be displayed
// hasFooter: flag if footer must be displayed
///////////////////////////////////////////////////////////////////////////////
function calcDivHeight(numberOfLines, hasFooter)
{
//alert(numberOfLines);
	if (hasFooter)
		numberOfLines = numberOfLines + 2;	// header and footer
	else
		numberOfLines = numberOfLines + 1; // only header
		
	var height = (numberOfLines) * 18;
	
	return height;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// changes the current height of the div to the desired height.
// if the alineBottom flag is set, the div will be moved down, 
// so that the bottom line keeps fix
// params:
// height: new height
///////////////////////////////////////////////////////////////////////////////
function adjustDivHeight(height)
{
	// attention: 
	// if the event onGetSuggestTopPosition() is implemented, adjustDivHeight has no effect!!!
	
	var divWnd = document.getElementById("divKeyList");

	divWnd.style.height = height + "px";
	
	if (_alineBottom)
	{
		// if window is smaller than max height, move it downward,
		// so that the bottom line keeps fix
		currentTopPos = _topPos + (_maxHeight - height);
		divWnd.style.top = currentTopPos + "px";
//	alert(height + ", " + _maxHeight + ", " + currentTopPos);
		
	}
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// changes the current position of the div
// params:
// left: left position
// top:  top position
///////////////////////////////////////////////////////////////////////////////
function setDivPosition(left, top)
{
	var divWnd = document.getElementById("divKeyList");

	divWnd.style.left = left + "px";
	divWnd.style.top = top + "px";
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// checks if the suggest list is visible
///////////////////////////////////////////////////////////////////////////////
function isListVisible()
{
	var divWnd = document.getElementById("divKeyList");

	if (divWnd.style.display == "block")
		return true;
	else
		return false;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// call function for interval timer,
// displays suggest list after delay time
///////////////////////////////////////////////////////////////////////////////
function onTimer()
{
	var now = new Date().getTime();
	
	if (_timerActive && now - _timeStamp > _delay)
	{
		_timerActive = false;
		window.clearInterval(_timerID);
		showList(true);
	}
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for mouse down of the suggestlist div
///////////////////////////////////////////////////////////////////////////////
function onMouseDownDiv()
{
	// reset canClose flag, so the blur event will not close the list	
	_canClose = false;
	
	// normally the list will be reactivated if the user returns to the input field.
	// But after a click into the list the focus will be set back to the input field automatically.
	// in this case the list shall not be displayed again.
	_openOnFocus = false;
	
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for glass icon in suggest list,
// redirects to extended search page
// params:
// searchStr: string that will be inserted as search string into the search input field
///////////////////////////////////////////////////////////////////////////////
function onSearchEx(searchStr)
{
    setElementValue(_searchInputID, searchStr);
    //setElementValue(_searchDataID, "");
	
	// fire event for client
	try
	{
		onClickLupe();
	}
	catch(ex)
	{
		// if no event handler is implemented it is still ok
	}
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for item select in newsletter mode (no lupe)
// params: 
// mlfb: MLFB
// text: short description of mlfb
// dataID: internal CS dataID - only set for mlfb clusters
///////////////////////////////////////////////////////////////////////////////
function onSelectMLFB(mlfb, text, dataID)
{
    setElementValue(_searchInputID, mlfb);
    setElementValue(_searchDataID, mlfb + "|" + text + "|" + dataID);

	showList(false);
	
	// fire event for client
	try
	{
		onClickMLFB(mlfb, text);
	}
	catch(ex)
	{
		// if no event handler is implemented it is still ok
	}
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for first icon in suggest list footer
// fills div with suggest items of first page
///////////////////////////////////////////////////////////////////////////////
function onFirstPage(mouse)
{
    // don't show cursor bar after mouse cklick
    if (parseBool(mouse))
        _cursorCmd = "";
        
	updateSuggestList(1);
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for prev icon in suggest list footer,
// fills div with suggest item of prev page
// params:
// currentPage: current page
///////////////////////////////////////////////////////////////////////////////
function onPrevPage(currentPage, mouse)
{
    // don't show cursor bar after mouse cklick
    if (parseBool(mouse))
        _cursorCmd = "";

    updateSuggestList(currentPage - 1);
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for last icon in suggest list footer,
// fills div with suggest item of last page
///////////////////////////////////////////////////////////////////////////////
function onLastPage(mouse)
{
    // don't show cursor bar after mouse cklick
    if (parseBool(mouse))
        _cursorCmd = "";

	updateSuggestList(-1);
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// event handler for next icon in suggest list footer,
// fills div with suggest item of next page
// params:
// currentPage: current page
///////////////////////////////////////////////////////////////////////////////
function onNextPage(currentPage, mouse)
{
    // don't show cursor bar after mouse cklick
    if (parseBool(mouse))
        _cursorCmd = "";

	updateSuggestList(currentPage+1);
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// makes up the query url that provides the suggest items
// params:
// pageNo: queryresult can be splitted into pages, define page to be provided
// query: search string
///////////////////////////////////////////////////////////////////////////////
function makeQueryURL(pageNo, query)
{
	var url;

	// url encode
	query = encodeURIComponent(query);
	
	if (_queryPath != "")
	{
		url = _queryPath.replace("$region$", _region);
		if (_queryPath.indexOf("?") > 0)
			url = url + "&page=";	
		else	
			url = url + "?page=";
	}
	else
	{
		url = "suggest2.asp?page=";
	}
		
	if (url.toLowerCase().indexOf("netmode") > 0)
		url = url + pageNo + "&lang=" + _lang + "&query=" + query + "&pageSize=" + _lines + "&region=" + _region	
	else
		url = url + pageNo + "&lang=" + _lang + "&query=" + query + "&pageSize=" + _lines + "&netmode=" + _netmode + "&region=" + _region

	if (_reducedResultSet)
		url = url + "&prodnl=" + 1
	else
		url = url + "&prodnl=" + 0
	
	if (_useCaching)
		url = url + "&useCache=true"
	else
	    url = url + "&useCache=false"

	url = url + "&oracleText=" + _oracleText;
		
	//url = "suggest" + pageNo + ".xml";
	
	// use client protocol (for browswer security reason)
	if (_useClientProtocol)
	{
		//alert("Url before client protocol usage: " + url);
		
		url = url.replace("http:", "");
		url = url.replace("https:", "");

		//alert("window.location.protocol: " + window.location.protocol);
		
		url = window.location.protocol + url;

		//alert("Url after client protocol usage: " + url);
	}
		
	return url;	
}
///////////////////////////////////////////////////////////////////////////////

	
///////////////////////////////////////////////////////////////////////////////
// callback for mouseover event of table row
// sets style with selection color
// params:
// number: line number, ids of table rows are automatically generated and contain the line number
///////////////////////////////////////////////////////////////////////////////
function trMouseOver(number)
{
    var tr = document.getElementById("trList_" + number);
	if (tr != null)
	    tr.className = "lsKeyListKeySelect";

	var spanM = document.getElementById("spanMLFB_" + number);
	if (spanM != null)
	    spanM.className = "lsKeyListKeySelect";

	var spanT = document.getElementById("spanTxt_" + number);
	if (spanT != null)
	    spanT.className = "lsKeyListKeySelect";	
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// callback for mouseover event of table row
// sets style with standard color
// params:
// number: line number, ids of table rows are autimaticall generated and contain the line number
///////////////////////////////////////////////////////////////////////////////
function trMouseOut(number)
{
	var tr = document.getElementById("trList_" + number);
	if (tr != null)
	    tr.className = "lsKeyListKey";	

	var spanM = document.getElementById("spanMLFB_" + number);
	if (spanM != null)
	    spanM.className = "lsKeyListMLFB";
		
	var spanT = document.getElementById("spanTxt_" + number);
	if (spanT != null)
	    spanT.className = "lsKeyListText";
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// checks if a point is located within a div element
// params:
// divID: id of the div element to be checked
// x: x-coordinate of point
// y: y-coordinate of point
///////////////////////////////////////////////////////////////////////////////
function isPointInDiv(divId, x, y)
{

	var divWnd = document.getElementById("divKeyList");
	// read current position and size-
	var divLeft = parseInt(divWnd.style.left.replace("px", ""));
	var divTop = parseInt(divWnd.style.top.replace("px", ""));
	var divWidth = parseInt(divWnd.style.width.replace("px", ""));
	var divHeight = parseInt(divWnd.style.height.replace("px", ""));

	var divRight = divLeft + divWidth;
	var divBottom = divTop + divHeight;
	if ( (x > divLeft) && (x < divRight) )
	{
		if ( (y > divTop) && (y < divBottom) )
			return true;
	}
	
	return false;
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// extracts query from response xml
// data: xml object
///////////////////////////////////////////////////////////////////////////////
function extractQuery(data)
{
	if (data == null)
	{
		return "browser does not support XML";
	}
	
	var rootElement = data.getElementsByTagName("suggestList");

	return getNamedItemValue(rootElement[0], "query");
}

///////////////////////////////////////////////////////////////////////////////
// compiles the html fragment that is loaded into the div in order to display 
// suggest list
// using dom model of IE
// params:
// data: xml object
///////////////////////////////////////////////////////////////////////////////
function compileSuggestListIE(data)
{
	var hasFooter = false;
	_numberOfLines = 0

	if (data == null)
	{
		return "browser does not support XML";
	}
	
	var str = "<table width='100%' cellpadding='0' cellspacing='0' ID='tabKeyList' class='lsKeyList'>";
	
	// read all items tags from xml and walk through item list
	var results = data.getElementsByTagName("item");
	
	// nothing found => return empty string
	_numberOfLines = results.length;

	if (_numberOfLines == 0)
	{
		return "";
	}
	
	for (var i=0; i < results.length; i++)
	{
		var item = results[i];
		var innerText;
		
		var mlfb = getNamedItemValue(item, "mlfb");
		var isProduct = getNamedItemValue(item, "isProduct");
		var dataID = getNamedItemValue(item, "dataID");

		// read text from inner text
		for (var j = 0; j < item.childNodes.length; j++)
		{
			innerText = item.childNodes[j].nodeValue;
		}
		
		// insert table row for each suggest item
		str += compileSuggestLine(i, mlfb, innerText, isProduct, dataID);
		
	}
	// read list attributes for pager buttons
	var list = data.getElementsByTagName("suggestList");	
	if (list.length > 0)
	{
		_currentPage   = parseInt(list(0).attributes.getNamedItem("page").value);
		_backAvailable = parseBool(list(0).attributes.getNamedItem("back").value.toLowerCase());
		_nextAvailable = parseBool(list(0).attributes.getNamedItem("next").value.toLowerCase());
	}

	if (_backAvailable == true || _nextAvailable == true)
	{
		hasFooter = true;
		str += compileSuggestFooter(_currentPage, _backAvailable, _nextAvailable);
	}
	
	str += "</table>";
	
	
	// adjust div height to actual results
	var height;
	height = calcDivHeight(_numberOfLines, hasFooter);
	//window.prompt("", str);
	adjustDivHeight(height);
	
	
	return str;
}
///////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
// compiles the html fragment that is loaded into the div in order to display 
// suggest list
// using dom model of FF
// params:
// data: xml object
///////////////////////////////////////////////////////////////////////////////
function compileSuggestListFF(data)
{
	var page;

	var hasFooter = false;
	_numberOfLines = 0;
	
	if (data == null)
	{
		return "browser does not support XML";
	}
	var str = "<table width='100%' cellpadding='0' cellspacing='0' ID='tabKeyList' class='lsKeyList'>";
	
	// read all items tags from xml and walk through item list
	var results = data.getElementsByTagName("item");
	
	// nothing found => return empty string
	_numberOfLines = results.length;
	if (_numberOfLines == 0)
	{
		return "";
	}
	
	for (var i=0; i < results.length; i++)
	{
		var item = results.item(i);
		var innerText;
		
		var mlfb = getNamedItemValue(item, "mlfb");
		var isProduct = getNamedItemValue(item, "isProduct");
		var dataID = getNamedItemValue(item, "dataID");

		// read text from inner text
		for (var j = 0; j < item.childNodes.length; j++)
		{
			innerText = item.childNodes[j].nodeValue;
		}
		// insert table row for each suggest item
		str += compileSuggestLine(i, mlfb, innerText, isProduct, dataID);
		
	}
	// read list attributes for pager buttons
	var list = data.firstChild;
	_currentPage   = parseInt(list.attributes.getNamedItem("page").value);
	_backAvailable = parseBool(list.attributes.getNamedItem("back").value.toLowerCase());
	_nextAvailable = parseBool(list.attributes.getNamedItem("next").value.toLowerCase());

	if (_backAvailable == true || _nextAvailable == true)
	{
		hasFooter = true;
		str += compileSuggestFooter(_currentPage, _backAvailable, _nextAvailable);
	}
	
	str += "</table>";
	
	// adjust div height to actual results
	var height;
	height = calcDivHeight(_numberOfLines, hasFooter);
	//window.prompt("", str);
	//alert(numberOfLines + ", " + height + ", " + hasFooter);
	adjustDivHeight(height);
	
	return str;
}


///////////////////////////////////////////////////////////////////////////////
// compiles html fragment that displays the footer (paging) in the suggest list
// params:
// currentPage: current page number
// back: true = display back button
// next: true = display next button 
///////////////////////////////////////////////////////////////////////////////
function compileSuggestFooter(currentPage, back, next)
{
	var textWidth = (_width - 80)/2;
	
	var str = "<tr class='lsKeyListFooter'>";
	
	if (back == true)
	{
		str += "<td width='15'>";
		str += 	"<a href='javascript:onFirstPage(true);'>";
		str += "<img src='" + _iconPath + "/icon_start_000000.gif' border='0'>";
		str += "</a>";
		str += "</td>";

		str += "<td width='15'>";
		str += "<a href='javascript:onPrevPage(" + currentPage + ", true);'>";
		str += "<img src='" + _iconPath + "/icon_zurueck_000000.gif'  border='0'>";
		str += "</a>";
		str += "</td>";

		str += "<td align='center' width='" + textWidth + "' >";
		str += "<a class='lsLink' href='javascript:onPrevPage(" + currentPage + ", true);'>";
		str += "<span class='lsKeyListFooterBar" + "' >" + _backStr + "</span>";
		str += "</a></td>";
	}
	else
	{
		str += "<td width='15'><span class='lsKeyListFooterBar'>&nbsp;</span></td>";

		str += "<td width='15'><span class='lsKeyListFooterBar'>&nbsp;</span></td>";

		str += "<td align='center' width='" + textWidth + "' ><span class='";
		str += "lsKeyListFooterBarDisabled";
		str += "' >" + _backStr + "</span></td>";
	}
	
	str += "<td width='20'><span class='lsKeyListFooterBar' >|</span></td>";
	
	if (next == true)
	{
		str += "<td align='center' width='" + textWidth + "' >";
		str += "<a class='lsLink' href='javascript:onNextPage(" + currentPage + ", true);'>";
		str += "<span class='lsKeyListFooterBar'>" + _nextStr + "</span>";
		str += "</a></td>";

		str += "<td width='15'>";
		str += "<a href='javascript:onNextPage(" + currentPage + ", true);'>";
		str += "<img src='" + _iconPath + "/icon_vor_000000.gif'  border='0'>";
		str += "</a>";
		str += "</td>";

		str += "<td width='15' align='right'>";
		str += "<a href='javascript:onLastPage(true);'>";
		str += "<img src='" + _iconPath + "/icon_ende_000000.gif'  border='0'>";
		str += "</a>";
		str += "</td>";
	}
	else
	{
		str += "<td align='center' width='" + textWidth + "' >";
		str += "<span class='lsKeyListFooterBarDisabled'>" + _nextStr + "</span></td>";

		str += "<td width='15'><span class='lsKeyListFooterBar'>&nbsp;</span></td>";

		str += "<td width='15'><span class='lsKeyListFooterBar'>&nbsp;</span></td>";
	}
	
	str += "</tr>";
	
	return str;
	
}
///////////////////////////////////////////////////////////////////////////////


///////////////////////////////////////////////////////////////////////////////
// builds one table row in the suggest list
// params: 
// number: line count
// mlfb: mlfb of suggest item
// text: display text of suggest item
///////////////////////////////////////////////////////////////////////////////
function compileSuggestLine(number, mlfb, text, isProduct, dataID)
{
	if (text == null)
		text = "";
		
	if (mlfb == null)
		mlfb = "";
		
    if (dataID == null)
		dataID = "";
		
	var displayText;
	// clip display text if wider than div width
	displayText = text.substring(0, _maxTextLength);
	if (text.length > _maxTextLength)
		displayText += "...";
	
	// content row
	var str = "<tr id='trList_" + number + "' onmouseover='trMouseOver(" + number + ");'  onmouseout='trMouseOut(" + number + ");' class='lsKeyListKey'>";

	if (_showLupe)
	{
		// usage for support
		// set product view url: for mlfb clusters use dataID instead of mlfb
		var productUrl;
		if (dataID == "")
		    productUrl = _productPath + mlfb;
		else
		    productUrl = _productPath + dataID;
		    
		productUrl = productUrl.replace("$region$", _region);
		productUrl = productUrl.replace("$lang$", _lang);
		
		if (isProduct == "1") // = fully qualified mlfb
		{
		    // link to detail page
		    str += "<td colspan='6'><a id='aLinkMLFB_" + number + "' class='lsLink' href='" + productUrl +  "' target='" + _detailTarget + "'>";
		    str += "<img src='" + _iconPath + "/icon_link_intern_003399.gif' border='0'>";
		    str += "<span id='spanMLFB_" + number + "' class='lsKeyListMLFB'>" + mlfb + "&nbsp;&nbsp;</span>";
		    str += "<span id='spanTxt_" + number + "' class='lsKeyListText'>" + displayText + "</span>";
		    str += "</a></td>";
		}
		else
		{
		    // no detail link possible
            str += "<td colspan='6'>";
		    str += "<img src='" + _iconPath + "/icon_blank.gif'  border='0'>";
		    str += "<span id='spanMLFB_" + number + "' class='lsKeyListMLFB'>" + mlfb + "&nbsp;&nbsp;</span>";
		    str += "<span id='spanTxt_" + number + "' class='lsKeyListText'>" + displayText + "</span>";
            str += "</td>";
		}

        // link to extended search
		str += "<td align='right'><a id='aLinkSearch_" + number + "' href=\"javascript:onSearchEx('" + mlfb + "')\"><img src='" + _iconPath + "/icon_lupe_003399.gif' border='0'></a></td>";
		str += "</tr>";
	}
	else
	{
		// usage for newsletter
		text = text.replace(/'/g, "\\'");
		text = text.replace(/"/g, "\\'");
		str += "<td colspan='7'><a id='aLinkSelectMLFB_" + number + "' class='lsLink' href=\"javascript:onSelectMLFB('" + mlfb + "', '" + text + "', '" + dataID + "')\" >";
		str += "<img src='" + _iconPath + "/icon_link_intern_003399.gif' border='0'>";
		str += "<span id='spanMLFB_" + number + "' class='lsKeyListMLFB'>" + mlfb + "&nbsp;&nbsp;</span>";
		str += "<span id='spanTxt_" + number + "' class='lsKeyListText'>" + displayText + "</span>";
		str += "</a></td>";
	}
	
	// separator line 
	str += "<tr class='lsListSep'>";
	str += "<td colspan='7'></td>";
	str += "</tr>";
		
	return str;
}
///////////////////////////////////////////////////////////////////////////////



///////////////////////////////////////////////////////////////////////////////
// loads an xml with the current suggest list from the url,
// makes a html fragment from it and
// inserts it into the suggest div
// params: 
// url: url for the data source
///////////////////////////////////////////////////////////////////////////////
function loadSuggestInfos(url)
{
	var request; // = new ActiveXObject("Msxml2.XMLHTTP.4.0");
	// browser fork for request object
	if (window.XMLHttpRequest) 
	{
		// FF
		request=new XMLHttpRequest();
	} 
	else if (window.ActiveXObject) 
	{
		// IE
		try	
		{
			request = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch(e)
		{
			try	
			{
				request=new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch(e)
			{
				request = false;
			}
		}
	}

	try
	{
	    // read xml from data source
//		alert(url);
		// synchronous call
		request.open("GET", url , true);
//		request.overrideMimeType('text/xml');

		request.onreadystatechange =
		function(evt)
		{
		    try
		    {
		        if (request.readyState == 4)
		        {
		            // process data and insert html
		            var xmlDoc
		            var result;
		            var responseQuery;
		            
		            result = "";
		            
		            // browser fork for creation of xmldom
		            if (window.ActiveXObject)	// IE
		            {
		                xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		                xmlDoc.loadXML(request.responseText);
		                
		                // check if resoponse is for the last requested query
						responseQuery = extractQuery(xmlDoc);
						if (compareCaseInsensitive(_lastQuery, responseQuery))
						{
						    result = compileSuggestListIE(xmlDoc);
						}
						else {
						    result = "outdated response";
						}
						
						//alert('_lastQuery: ' + _lastQuery + ' | responseQuery: ' + responseQuery);
		            }
		            else  // FF
		            {
		                var listPos = request.responseText.indexOf("<suggestList");
		                _xmlDivFF.innerHTML = request.responseText.substring(listPos);
		                
		                // check if resoponse is for the last requested query
						responseQuery = extractQuery(_xmlDivFF);
						if (compareCaseInsensitive(_lastQuery, responseQuery))
						{
						    result = compileSuggestListFF(_xmlDivFF);
						}
						else {
						    result = "outdated response";
						}
		            }

					//alert("loadSuggestInfos::responseQuery: " + responseQuery);

		            completeListUpdate(result);
		        }
		    }
		    catch (e4)
		    {
		        throw e4;
		    }
		}; 

		request.send(null); 

	}
	catch(e3)
	{
	    if (_enableErrMsg)
		    alert(e3.message);
	}
				

}
///////////////////////////////////////////////////////////////////////////////
function compareCaseInsensitive(val, valref)
{
	return (val.toLowerCase() == valref.toLowerCase());
}

///////////////////////////////////////////////////////////////////////////////
// end of module
///////////////////////////////////////////////////////////////////////////////


