 
/**
 * Constructor for QuerySuggester.
 */
function QuerySuggester() {
    this.id = querySuggesters.length;
    querySuggesters[this.id] = this;
}

String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

QuerySuggester.prototype.useInlineSuggestion = true;                // Whether or not to display the first suggestion as marked text within the search-box
QuerySuggester.prototype.clearInlineSuggestionBeforeSubmit = true; // Whether or not to remove inline suggestions before submitting

// Public functions

/**
 * Initialize the query-suggester.
 *
 * @param suggestionUrl the url to fetch suggestions from, will append the query string to it
 * @param formId        the id of the form that should be submitted if the user clicks a suggestion
 * @param tooltipId     the id of the div used to display the suggestsions
 */
QuerySuggester.prototype.initialize = function(suggestionUrl, formId, tooltipId, queryId) {
    this.__enabled = new BackgroundLoader().isEnabled();
    if (this.__enabled) {
        this.__suggestionUrl = suggestionUrl;
        this.__form = this.byId(formId);
        if (!this.__form) {
            this.__enabled = false;
            this.debug("Couldn't find the form, disabling.");
        } else {
            this.__tooltip = this.byId(tooltipId);
            this.__queryId = queryId;
            this.__query = this.byId(queryId);
            if (this.__query) {
                var oldKeyUp = this.getFunctionBody(this.__query.onkeyup);
                var oldKeyDown = this.getFunctionBody(this.__query.onkeydown);
                var suggester = this;
                this.__query.onkeyup = function(e) { if (typeof e != "undefined") event = e; eval(oldKeyUp); suggester.keyUp(event, queryId); };
                this.__query.onkeydown = function(e) { if (typeof e != "undefined") event = e; eval(oldKeyDown); suggester.keyDown(event, queryId); };
            }
        }
    } else {
        this.debug("Unable to instantiate XMLHttpRequest, disabling.");
    }
};

/**
 * Set the id of the textarea where debug-output is written. Initially, there is no such
 * textarea assigned to the suggester.
 *
 * @param debugAreaID the id of the textarea to print debug messages to, or boolean false
                      to disable debugging
 */
QuerySuggester.prototype.setDebugAreaId = function(debugAreaId) {
    this.__debugAreaId = debugAreaId;
};

/**
 * Set the id of the input-field to do completion for. Not really neccessary to call, as
 * the id is sent to the key handling methods.
 *
 * @param queryId the id of the search box
 */
QuerySuggester.prototype.setQueryId = function(queryId) {
    this.__queryId = queryId;
    this.__query = this.byId(queryId);
};

// Overridable functions

/**
 * Returns the url to visit to obtain suggestions for a query. By default appends the
 * query to the suggestionUrl member. Override for different behavior.
 *
 * @param quer the query for which to fetch suggestions
 * @return the url that will return the suggestions
 */
QuerySuggester.prototype.getSuggestionUrl = function(query) {
    return this.__suggestionUrl + query;
};

/**
 * Called when the search form should be submitted (usually because of mouse clik on one
 * of the suggestions in the list). By default submits the form specified by the formId
 * parameter of the initialize() function. Override for different behavior.
 */
QuerySuggester.prototype.submitForm = function() {
    this.__form.submit();
};

// Input event handlers

/**
 * Event handler for key up events.
 */
QuerySuggester.prototype.keyUp = function(event, field) {
    if (!this.__enabled) return;
    else if (field != this.__queryId) this.setQueryId(field);
    if (event) {
        if (this.__timeout) {
            clearTimeout(this.__timeout);
            this.__timeout = false;
        }
        if (event.ctrlKey || event.altKey) {
            return;
        }
        var timeout = 100;
        this.__deletePressed = false;
        switch (event.keyCode) {
            case 9 : // Tab
            case 27 : // Escape
                this.hide();
                return;
            case 8 : // Backspace
            case 46 : // Delete
                this.__deletePressed = true;
                timeout = 200;
                break;
            case 13 : // Enter
            case 16 : // Shift
            case 17 : // Ctrl
            case 18 : // Alt
            case 20 : // Caps Lock
            case 33 : // Page up
            case 34 : // Page down
            case 35 : // End
            case 36 : // Home
            case 37 : // Arrow left
            case 38 : // Arrow up
            case 39 : // Arrow right
            case 40 : // Arrow down
            case 45 : // Insert
                return;
            default :
                timeout = 100;
                break;
        }
        this.__index = -1;
        var qc = this;
        this.__timeout = setTimeout(function() {qc.fetchAndDisplaySuggestions();}, timeout);
    }
};

/**
 * Some keys also require keyDown handlers, because they never give a key up event. For
 * instance, pressing the 'tab' key will typically cause focus to leave the search input
 * box, causing the key up event to be sent to another component.
 */
QuerySuggester.prototype.keyDown = function(event, field) {
    if (!this.__enabled) return;
    else if (field != this.__queryId) this.setQueryId(field);
    if (event && event.keyCode) {
        switch (event.keyCode) {
            case 9 : // Tab
                this.hide();
                break;
            case 13 : // Enter
                // if (this.__index == -1) this.clearInlineSuggestion();
                break;
            case 38 : // Up-arrow
                if (this.__index == 0) {
                  this.__query.value =  this.__oldquery;
                }
                if (this.__index >= 0) {
                  this.updateSuggestions(this.__index--, -2);
                }
                break;
            case 40 : // Down-arrow
                if (this.__index == -1) {
                  this.__oldquery = this.__query.value.trim();
                }
                if (this.__index < this.__terms.length - 1) this.updateSuggestions(this.__index++, -2);
                break;
        }
    }
};

QuerySuggester.prototype.mouseOver = function(index) {
    if (!this.__enabled) return;
    
    var previous = this.__mouseIndex >= 0 ? this.__mouseIndex : this.__index;
    this.__mouseIndex = index;
    this.updateSuggestions(-2, previous);
    //this.updateSuggestions(this._mouseIndex, previous)
};

QuerySuggester.prototype.mouseOut = function(index) {
    if (!this.__enabled) return;
    var previous = this.__mouseIndex;
    this.__mouseIndex = -1;
    this.updateSuggestions(-2, previous);
};
// Mihran Mod
QuerySuggester.prototype.mouseClick = function(index) {
    if (!this.__enabled) return;
    if (index >= 0) {
        
        this.__query.value = this.__terms[index].split('|')[0];
        this.hide();
        //this.submitForm();
    } else {
        this.hide();
    }
};

// Functions for retrieving suggestions

QuerySuggester.prototype.fetchAndDisplaySuggestions = function() {
    var val = this.__query.value;
     
    // Mihran set min chars to 4 before we do anything
    if (val.length >= 3) { 
       if (this.canHandleRanges()) {
           val = val.substring(0, this.getCaretPosition());
       }
       if (val.length == 0) {
           this.hide();
           this.__prev = val;
           return;
       } else {
           val = val.replace(new RegExp("\\\\", "g"), "\\\\");
       }
       this.__prev = val;
       if (this.__cache[val]) {
           this.debug("cache: " + val);
           this.displaySuggestions(this.__cache[val], this.__prev);
       } else {
           this.debug("query: '" + val + "'");
           this.fetchSuggestion(val);
       }
    } else { 
       this.noSuggestions();
    }
  
};

QuerySuggester.prototype.fetchSuggestion = function(query) {
    var qc = this;
    var bl = new BackgroundLoader();
    //this.debug("fetching: '" + query  + "'"); 
    bl.setLoadedCallback(function(content){qc.parseSuggestions(content);});
    bl.setErrorCallback(function(error){qc.debug("Couldn't get suggestions:\n" + error);});
    bl.loadUrl(this.getSuggestionUrl(query));
};

// Functions for displaying suggestions

QuerySuggester.prototype.parseSuggestions = function(matches) {
    if (matches == "") return;
    var params = eval(matches);
    if (params.length > 2) {
        this.__cache[params[0]] = params;
    }
    this.displaySuggestions(params, params.length > 2 ? params[0] : "");
};

QuerySuggester.prototype.displaySuggestions = function(matches, query) {
    //this.debug("matches length: '" + matches.length + "'");
    if (matches.length <= 2) {
        this.noSuggestions();
        return;
    }
    if (this.__tooltip && this.__query) {
        matches=this.processSuggestions(matches);
        this.buildSuggestionsHtml(matches);
        this.show();
        //this.showInlineSuggestions(query);
    }
};


QuerySuggester.prototype.toTitleCase = function(str) {
       //lowercase the whole string
       var ls = str.toLowerCase().split(' ');
       
       //loop through word array
       for (var i = 0; i < ls.length; i++) {
       //alert(ls[i]);
       //replace first letter with uppercase version
           ls[i] = ls[i].charAt(0).toUpperCase() + ls[i].slice(1);
       }
     //rejoin words and return the new string
     return ls.join(' ');
};

// Setter store forbostaver i hvert ord.
function capitalizeMe(val) {
	newVal = '';
	val = val.split(' ');
	for(var c=0; c < val.length; c++) {
	newVal += val[c].substring(0,1).toUpperCase() +
	val[c].substring(1,val[c].length) + ' ';
	}
	return newVal;
}

QuerySuggester.prototype.buildSuggestionRecord = function(record, terms, i) {
    var text="";

    var type=99;
    if (record.type != undefined) {
      type = record.type;
    }

		var redirect = "window.location='/fotballsoek/search.fast?s.sm.query="+terms+"&s.ac.sortBy=fotball'";
        text += "<div class=\"suggestionEntry\" id=\"tooltip_" + i + "\" onmouseover=\"mouseOver(" + this.id + "," + i + ")\" onmouseout=\"mouseOut(" + this.id + "," + i + ")\" >";
        
	        //start photo
	        if (record.pic != undefined) {
	        	text += "<table cellpadding=\"0\" cellspacing=\"0\" class=\"suggestionEntry_img\" width=\"30\"><tr><td><img src='" + record.pic + "' alt=' ' onclick=\"" + redirect + "\" /></td></tr></table>"
	        	//text += "<div class=\"suggestionEntry_img\"><img src='" + record.pic + "' alt=' ' onclick=\"" + redirect + "\" /></div>"
	        } else {
	        	text += "<div class=\"suggestionEntry_img\"></div>";
	        }
	        	//text += "<div class=\"suggestionEntry_img\"></div>";
		        text += "<div class=\"suggestionEntry_player\" onclick=\"" + redirect + "\">" + capitalizeMe(record.name) + "</div>"
			//text += "<div class=\"suggestionEntry_team\" onclick=\"" + redirect + "\">";
		        //if (record.info != undefined) {
			//		if(type == 2) { // Team(s)
			//			if (record.info.length > 19) {
			//				text += record.info.substring(0,19) + '..';
			//			} else {
			//				text += record.info;
			//			}
			//
			//		}
		        //}
	        //text += "</div>";

        text += "</div>\n";
        
        //this.debug("text: '" + text + "'");        
    return text;
};

QuerySuggester.prototype.processSuggestions = function(matches) {
    var text = "";
    var entries = (matches.length-2) / 2;
    var count=0
    var result = new Array();

    for (var i=0; i<entries; i++) {
      var id = matches[2+(i*2)];
      var tmpdata = matches[3+(i*2)];
      var rawdata = tmpdata.split('|')[1]
      var rawdata2 = rawdata.split('*')
      
      for (var k=0; k<rawdata2.length; k++) {
        values=rawdata2[k].split('#');
        result[count] = rawdata2[k];
        count++;
      }
    }
    result.sort(this.entryCompare); // sort by rank
    return result;
};

QuerySuggester.prototype.entryCompare = function(a, b) {  
  // sort on type, then ranking
  // type = 1 teams, 2 players, 3 query terms
  // sorting is query terms, players, teams
  recorda = QuerySuggester.prototype.buildRecord(a);
  recordb = QuerySuggester.prototype.buildRecord(b);
  typea = 0
  typeb = 0
  if (recorda.type == "1") typea = 1;
  if (recorda.type == "2") typea = 2;
  if (recorda.type == "3") typea = 3;
  if (recordb.type == "1") typeb = 1;
  if (recordb.type == "2") typeb = 2;
  if (recordb.type == "3") typeb = 3;

  if (typea == typeb) {
    if (parseInt(recorda.ranking) < parseInt(recordb.ranking)) return 1;
    if (parseInt(recorda.ranking) > parseInt(recordb.ranking)) return -1;
  } else {
    if (typea < typeb) return -1;
    if (typea > typeb) return 1;
  }
  return 0;
};

QuerySuggester.prototype.buildRecord = function(recordvalue) {
  var rawdata = recordvalue.split('#');
  var record={}
  for (var k=0; k<rawdata.length; k++) {
     entry=rawdata[k].split("%");
     record[ entry[0] ] =  entry[1];
  }
  return record;
};

// Mihran Mods
QuerySuggester.prototype.buildSuggestionsHtml = function(matches) {
    var text = "";
    
    var length = matches.length;
    this.__terms = new Array(length);

    var entries = matches.length
    var count=0
    var types = new Array();
    types[0] = 0;
    types[1] = 0;
    types[2] = 0;
    types[3] = 0;

    for (var i=0; i<entries; i++) {
/*
      var tmpdata = matches[i]
      var rawdata = tmpdata.split('#')
      
      var record={}
      for (var k=0; k<rawdata.length; k++) {
        entry=rawdata[k].split("%");
        record[ entry[0] ] =  entry[1];
      }
*/
      var record=this.buildRecord(matches[i]);
      type = parseInt(record.type);
      if (types[type] < this.__max[type]) {
        this.__terms[count] = record['value']
        text += this.buildSuggestionRecord(record, this.__terms[count], count);
        count++;
        types[type]++;
      }
    }
    this.__tooltip.innerHTML = text;
};


// Mihran Modes - split('|')[0]
QuerySuggester.prototype.showInlineSuggestions = function(query) {
    if (this.__terms.length > 0 && this.__query.value == query && !this.__deletePressed && this.useInlineSuggestion) {
        this.__original = this.__query.value;
        if (this.canHandleRanges()) {
            this.__query.value = this.__terms[0].split('|')[0];
            this.selectRange(this.__original.length, this.__query.value.length);
        }
    }
};

//Mihran Mo zhilin des - split('|')[0]

QuerySuggester.prototype.updateSuggestions = function(previousIndex, previousMouseIndex) {
    var previous = this.byId("tooltip_" + previousIndex);
    var previousMouse = this.byId("tooltip_" + previousMouseIndex);
    var current = this.byId("tooltip_" + this.__index);
    var currentMouse = this.byId("tooltip_" + this.__mouseIndex);
   
   
    
    if (previous) {
        if (previousIndex != this.__mouseIndex) {
            previous.className = "suggestionEntry";
        }
    }
    if (current) {
        current.className = "suggestionEntryHover";
        if (this.canHandleRanges()) {
            this.__query.value = this.__terms[this.__index];
//            this.selectRange(this.__original.length, this.__query.value.length);
        }
    }
    
    //this.debug("Current Mouse: '" + this.__mouseIndex + "'");
    //this.debug("Previous Mouse: '" + previousMouseIndex + "'");
    
    if (previousMouse && previousMouseIndex != this.__index) {
        previousMouse.className = "suggestionEntry";
        //currentMouse.className = "suugestionEntryHover";
    }
    if (currentMouse) {
        currentMouse.className = "suggestionEntryHover";
    }
};

/**
 * Called when the list of matches returned is empty. Default implementation will simply
 * hide the list of suggestions. Override for custom behavior.
 */
QuerySuggester.prototype.noSuggestions = function() {
    this.hide();
};

QuerySuggester.prototype.show = function() {
    if (this.__tooltip && this.__query) {
        this.__tooltip.style.left = this.findPosX(this.__query) + "px";
        this.__tooltip.style.top = (this.findPosY(this.__query) + this.__query.offsetHeight) + "px";
        this.__tooltip.style.width = (this.__query.offsetWidth -2) + "px";
        this.__tooltip.style.visibility = "visible";
	var column = byId('fotballsoek_luft');
	column.style.height = '170px';
    }
};

QuerySuggester.prototype.hide = function() {
    if (this.__tooltip) {
        this.__terms = new Array();
        this.__tooltip.innerHTML = "";
        this.__tooltip.style.visibility = "hidden";
	var column = byId('fotballsoek_luft'); 
	column.style.height = '0px';
    }
};

// Text-selection helper-functions

QuerySuggester.prototype.canHandleRanges = function() {
    return this.__query.createTextRange || this.__query.setSelectionRange;
};

QuerySuggester.prototype.selectRange = function(from, to) {
    if (this.__query.createTextRange) {
        var t = this.__query.createTextRange();
        t.moveStart("character", from);
        t.select();
    } else if (this.__query.setSelectionRange) {
        this.__query.setSelectionRange(from, to);
    } else {
        this.debug("Couldn't select range.");
    }
};

QuerySuggester.prototype.getCaretPosition = function() {
    if (document.selection) {
        var range = document.selection.createRange().duplicate();
        range.collapse(true);
        range.moveStart("character", -1000);
        return range.text.length;
    } else if (this.__query.setSelectionRange) {
        return this.__query.selectionStart;
    } else {
        this.debug("Couldn't find caret position.");
        return this.__query.value.length;
    }
};

QuerySuggester.prototype.clearInlineSuggestion = function() {
    if (this.__query && this.canHandleRanges() && this.clearInlineSuggestionBeforeSubmit) {
        this.__query.value = this.__query.value.substring(0, this.getCaretPosition());
    }
};

// General helper-functions

/**
 * Helper-function that extracts the body of a function, by converting it to a string, and
 * extracting the substring from after the first { to the last }. If the func argument
 * isn't a function, an empty string is returned.
 *
 * @param func the function whose body to extract
 * @return the body of func
 */
QuerySuggester.prototype.getFunctionBody = function(func) {
    var body = "";
    if (typeof func == "function") {
        body = func.toString();
        body = body.substring(body.indexOf("{") + 1, body.lastIndexOf("}"));
    }
    return body;
};

QuerySuggester.prototype.findPosX = function(obj) {
    var curleft = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curleft += obj.offsetLeft;
            obj = obj.offsetParent;
        }
    } else if (obj.x)
        curleft += obj.x;
    this.debug("curLeft: " + curleft);
    return curleft;
};

QuerySuggester.prototype.findPosY = function(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
        while (obj.offsetParent) {
            curtop += obj.offsetTop
            obj = obj.offsetParent;
        }
    } else if (obj.y) {
        curtop += obj.y;
    }
    this.debug("curtop: " + curtop);
    return curtop;
};

QuerySuggester.prototype.byId = function(id) {
    var element = document.getElementById ? document.getElementById(id) : false;
    return element && element != null ? element : false;
};

QuerySuggester.prototype.debug = function(message) {
    if (this.__debugAreaId) {
        var err = this.byId(this.__debugAreaId);
        if (err) {
            err.value += message + "\n";
        }
    }
};

// Private members

QuerySuggester.prototype.__suggestionUrl = false;   // The url to fetch suggestions from
QuerySuggester.prototype.__form = false;            // The form
QuerySuggester.prototype.__query = false;           // The query input field
QuerySuggester.prototype.__queryId = false;         // The id of the query input field
QuerySuggester.prototype.__tooltip = false;         // The tooltip div
QuerySuggester.prototype.__debugAreaId = false; //"debug";     // Text-area for debugging

QuerySuggester.prototype.__timeout = false;         // The current timeout
QuerySuggester.prototype.__prev = "";               // The previously sent term
QuerySuggester.prototype.__original = "";           // The term before panning into the suggestions
QuerySuggester.prototype.__index = -1;              // The index of the text cursor in the list of suggestions
QuerySuggester.prototype.__mouseIndex = -1;         // The position of the mouse in the list of suggestions
QuerySuggester.prototype.__terms = new Array();     // The list of suggestions
QuerySuggester.prototype.__cache = new Array();     // A result-cache
QuerySuggester.prototype.__enabled = false;
QuerySuggester.prototype.__deletePressed = false;   // Delete or backspace has been pressed


QuerySuggester.prototype.__max = new Array();
QuerySuggester.prototype.__max[1] = 2; // max teams
QuerySuggester.prototype.__max[2] = 2; // max players
QuerySuggester.prototype.__max[3] = 2; // max from querylog

// Global stuff


// Global array of all instantiated query-suggesters
var querySuggesters = new Array();

// Global mouse-handling function
function mouseOver(id, index) {
    if (id >= 0 && id < querySuggesters.length) {
        querySuggesters[id].mouseOver(index);
        //this.debug("mouseOver: '" + id + "'");
    }
}

// Global mouse-handling function
function mouseOut(id, index) {
    if (id >= 0 && id < querySuggesters.length) {
        querySuggesters[id].mouseOut(index);
    }
}

// Global mouse-handling function
function mouseClick(id, index) {
    if (id >= 0 && id < querySuggesters.length) {
        querySuggesters[id].mouseClick(index);
    } else if (id == -1 && index == -1) {
        for (var i = 0; i < querySuggesters.length; ++i) {
            querySuggesters[i].mouseClick(index);
        }
    }
}


