/*
 * Search Suggest Box
 *
 * a box that 
 * assumes a XML http request that returns a xml document
<root>
 <headerText>Suggestions for your search...</headerText>  
 <query type="brand" typeName="Manufacturer" >Suggest Query Term 1</query>
 <query type="name" typeName="Product Name" >Suggest Query Term 2</query>
</root>
 *
 * uses the util.js from bc_pmc for getXMLHttpRequest
 */

function SuggestBox() {

    var pRequest; // xml http request
    var pDiv; //the div for suggestbox layer
    var pDivIFrame; //an additional div for iframe trick (to be layed before IE input elements ) 
    var pDebug = false; 
    var pInstanceName = ""; //instance name of this object
    var pSearchURL = ""; // the url to retrieve suggests, including query parameter name
    var pQueryParamName = ""; // the query parameter for the query term 
    var pForm = "";
    var pQueryInput; //the user entered query term
    var pSuggest = new Array; //contains suggest query and type for submitting the result 
    var pLastQuery; //remember the last query term from the input
    var pCurrentSelection = -1; // suggest query term selection

    var submitted = false;

	//holds html code built from httprequest response
	var responseTextStart  = ''; 
    var responseTextHeader = '';  
    var responseTextRow    = '';
    var responseTextEnd    = '' 
    
    var self = this;
    
    this.init = function (searchURL, form, queryInput, instanceName) {
    
    	pForm = form;
    	pSearchURL = searchURL;
    	pQueryParamName = queryInput; 
    	pDivIFrame = $(
    			'<div class="suggestBoxIFrame">' +
    			'	<iframe scrolling="no" frameborder="0" width="100%" height="100%" src="javascript:false;"></iframe>' +
    			'</div>'); 
    	pDiv = $(
    			'<div class="suggestBox ' + instanceName + '">' +
   			 	'</div>');
	
    	$(document.body).append(pDiv);
    	$(document.body).append(pDivIFrame);
			
    	pInstanceName = instanceName;
    	    	
	    //initalize the html used to display inside the suggestBox div
	    //contains placeholders @...@ replaced from handleResponseXML() 
	    responseTextStart = '<table>'; 
//        responseTextHeader = '<tr><td class="suggestHeader" nowrap="nowrap">@HeaderText@</td></tr>';  
        responseTextHeader = '<tr><td class="suggestHeader" >@HeaderText@</td></tr>';  
        responseTextRow = '<tr class="suggestRow" id="'+ pInstanceName + '_@count@">' +
				'@SuggestQueryImage@' +
				'<td class="suggest">@SuggestQuery@</td></tr>';
//        		'<td class="suggest" nowrap="nowrap"><div>@SuggestQuery@</div></td></tr>';
		//fragments chosen later whether an image was provided or not
		responseTextWithImage    = '<td class="suggestImage"><img class="suggestImageView" src="@SuggestQueryImageURL@" /></td>';
		responseTextWithoutImage = '<td class="suggestImageMissing">&nbsp;</td>';
		responseTextNoImage      = '<td class="noSuggestImage">&nbsp;</td>';
		//
        responseTextEnd = '</table>';

    	//get query input field and set handlers
    	pQueryInput = queryInput;
    	pQueryInput.keyup(handleKeyPress);
    	pQueryInput.keydown(showLayer);
    	pQueryInput.click(showLayer);
    	pQueryInput.blur(hideLayer);
    	pForm.submit(handleSubmit);
    	
    	//set handler that closes the suggest box when clicked elsewhere
    	var self = this;
    	$(document).mousedown(function() { self.hideLayerOutsideCall(); });    	
    };
    
    this.handleClick = function () {
        //todo handle the types like brand
    	if (pSuggest[pCurrentSelection] != undefined) {
    			$(pQueryInput).val(pSuggest[pCurrentSelection][0]);
    			pForm.submit();
    	}
    };

    this.handleMouseOver = function (pos) {
    	var selEl = getRow(pos);
    	deselect();
    	if (selEl != null) {
    		highlight(selEl);
    		pCurrentSelection = pos;
    	}
    };

    this.handleMouseOut = function (pos) {
    	var selEl = getRow(pos);
    	if (selEl != null) {
    		deselect(selEl);
    		pCurrentSelection = -1;
    	}
    };
    
    function handleSubmit() {
        submitted = true;
        hideLayer();
        //todo handle the types like brand
        if (pSuggest[pCurrentSelection] != undefined) {
            $(pQueryInput).val(pSuggest[pCurrentSelection][0]);
        }
    }; 

    function handleKeyPress(evt) {
        evt = evt ? evt : event ? event : null;
        var keyCode = evt.keyCode;
        if (keyCode == 38) {
            moveSelection("up");
        } else if (keyCode == 27) {
            hideLayer();
        } else if (keyCode == 40) {
            moveSelection("down");
        } else {
            var query = pQueryInput.val();
            if ((query == "") || (query.length < 3))
            {
                clearSuggestBox();
                pLastQuery = query;
                return null;
            }
            if (pLastQuery != query)
            {
                startAjaxRequest(query);
            } else {
            	showLayer();
            }
            pLastQuery = query;
        }
    }; 

    function moveSelection(direction) {
        var pos = pCurrentSelection;
        if (direction == "up") {
            pos--;
        } else {
            pos += 1;
        }
        if (pos < 0) {
            deselect();
            pQueryInput.focus();
            pCurrentSelection = -1;
        } else {
            var selEl = getRow(pos);
            if (selEl != null) {
                deselect();
                highlight(selEl);
                pCurrentSelection = pos;
            }
        }
        var query = pQueryInput.val();
        pQueryInput.val('');
        pQueryInput.focus();
        pQueryInput.val(query);
    };

    function startAjaxRequest(query) {
        
        var requestURL = pSearchURL + encodeURIComponent(query);
        
      	pRequest = getXmlHttpRequest();
        pRequest.open("GET", requestURL, true);
        pRequest.onreadystatechange = callbackAjaxRequest;
        pRequest.send(null);
        
    };
    
    this.hideLayerOutsideCall = function () {
        hideLayer();
    };

    function hideLayer() {
    	
    	if ($.browser.msie && $.browser.version=="6.0") {
            $(pDiv).css("display", "none");
            $(pDivIFrame).css("display", "none");
    	} else {
            $(pDiv).fadeOut();
    	}
    };

    function showLayer() {
    	    	
        if (pDiv != null && pSuggest != null && pSuggest.length >= 3 && pQueryInput.val().length >=3) {

        	// move suggest box to Position (under the input field)
        	var input_object = pQueryParamName;
			// horizontal positioning now manually fixed in order to match right border of body
        	var input_pos = $(input_object).offset();
        	
        	// boxengasse.css(#website:width) minus boxengasse_ish.css(.suggestBoxHeader:width)
        	// = 1000px - 364px
        	var left = ($('#SearchBar').offset().left + $('#SearchBar').width()) - $(pDiv).width();
			var div_top = input_pos.top + $(input_object).outerHeight(true);			
			$(pDiv).css("top", div_top + "px");
			//$(pDiv).css("left", input_pos.left + "px");
			$(pDiv).css("left", left + "px");
	     	
			if ($.browser.msie && $.browser.version=="6.0") {
				$(pDiv).css("display", "block");	
	        	//position and resize IFrame behind the box
	     		$(pDivIFrame).css("top", div_top + "px"); 
	     		//$(pDivIFrame).css("left", input_pos.left + "px");
	     		$(pDivIFrame).css("left", left + "px");
	     		$(pDivIFrame).width($(pDiv).outerWidth());
	     		$(pDivIFrame).height($(pDiv).outerHeight());
			} else {			
				$(pDiv).fadeIn();
			}
        }
    };

    function callbackAjaxRequest() {
        if (submitted == false) {
            if (pRequest.readyState == 4) {
                if ((pRequest.status != 200) || (pRequest.responseXML == null)) {
                    hideLayer();
                    if (pDebug) {
                        alert("Error (" + pRequest.status + "): " + pRequest.statusText + " response: " + pRequest.responseText);
                    }
                } else {
                    handleResponseXML(pRequest.responseXML);
                }
            }
        }
    };

    function fireSuggestCompleted(suggestBoxIsVisible) {
        if (typeof onSuggestCompleted == "function") {
            onSuggestCompleted(suggestBoxIsVisible);
        }
    };

    function handleResponseXML(responseDocument) {

        pCurrentSelection = -1;
         
        var i = 0;
        var element;
		var images = 0;

        $(pDiv).html("");

        var table = $(responseTextStart + responseTextEnd);
        $(pDiv).append(table);
        
		// [#2322] ----------
		// ignore headerText according to latest design proposal
        var headerTextNode = null;
		// in order to get the former behavior just uncomment following line:
        //var headerTextNode = responseDocument.getElementsByTagName("headerText")[0]; 
		// [#2322] ----------
        if(headerTextNode != null && headerTextNode.firstChild != null && headerTextNode.firstChild.data)
        {
        	table.append(responseTextHeader.replace("@HeaderText@", headerTextNode.firstChild.data));
        }
        
        //get the query parts        
        var queries = responseDocument.getElementsByTagName("query");
        for(var i=0;i<queries.length; i++)
        {
        	pSuggestParts = new Array;
        	suggestQuery = queries[i].firstChild.data;
        	if(suggestQuery != null)
        	{
	        	pSuggestParts[0] = suggestQuery; 
    	    	pSuggestParts[1] = queries[i].getAttribute("type");
    	    	pSuggest[i] = pSuggestParts;

    	    	var typeName = queries[i].getAttribute("typeName");
    	    	var highlightedQueryTerm = suggestQuery.replace(new RegExp("(" + pQueryInput.val() + ")", "ig"), '<span class="suggestContent">$1</span>');    	    	
    	    	var responseTextRowReplaced = responseTextRow.replace(/@count@/g, i);
    	    	responseTextRowReplaced = responseTextRowReplaced.replace("@SuggestQuery@", highlightedQueryTerm);
				var responseTextForImage;

				// check if image mode is enabled
				var showImageEnabled = queries[i].getAttribute("show-image");
				if(showImageEnabled == null || showImageEnabled == "false") {
					// if suggest image mode is not enabled, use table data template stored in responseTextNoImage
					responseTextForImage = responseTextNoImage;
				} else {			
					// if a value for image URL was provided, insert URL and set display style for all image table data afterwards
					var imageURL = queries[i].getAttribute("image");
					if(imageURL != null) {
						images++;
						// if an URL was provided, use table data template stored in responseTextWithImage and insert URL
						responseTextForImage = responseTextWithImage.replace("@SuggestQueryImageURL@", imageURL);
					} else {
						// if no URL was provided, use table data template stored in responseTextWithoutImage
						responseTextForImage = responseTextWithoutImage;
					}
				}
				
				// insert above chosen template into table row
				responseTextRowReplaced = responseTextRowReplaced.replace("@SuggestQueryImage@", responseTextForImage);				

				var entry = $(responseTextRowReplaced);
    	    	table.append(entry);

    	    	// store index at element for reference in closures
    	    	entry[0].index = i;
                entry.mouseover(function() {
                	self.handleMouseOver(this.index);
                });
                entry.mouseout(function() {
                	self.handleMouseOut(this.index);
                });
                entry.mousedown(function() {
                	self.handleClick();
                });
    
        	}
        }
        
/**
 * removed due to #2445
 * 
        if(!images)
		{
			// if no single one image URL was provided, completely hide table data column 
			$(".suggestImageMissing").hide();
		}		
*/
		if (pSuggest.length >= 1 && queries.length >= 1 && pQueryInput.val().length >= 3) {
            showLayer();
            fireSuggestCompleted(true);
        } else {
        	$(pDiv).html("");
            hideLayer();
            fireSuggestCompleted(false);
        }
    };

    function highlight(selEl) {
        selEl.className = "suggestHighlight";
    };

    /* deselects an element
       or all if null element is passed  
    */
    function deselect(selEl) {
    	if(selEl != null) {
    		selEl.className="suggestRow";	
    	}
    	else {
	        for (var i in pSuggest) {
	            selEl = getRow(i);
	            if (selEl != null) {
	                selEl.className="suggestRow";
	            }
	        }
    	}
    };

    function getRow(pos) {
        var selEl;
        selEl = document.getElementById(pInstanceName + "_" + pos);
        return selEl;
    };
	
	function clearSuggestBox() {
		hideLayer();
        pDiv.innerHTML = "";
        fireSuggestCompleted(false);
	}
}; 

