//
// Javascript class to load a list of Names from a service and populate a table with the values
// 11-Aug-2009 by Mark Abela
//
// Important: relies on clientSideRoutines.js and ffxEvents.js being loaded
//
// ToDo:
// Currently only caters for loading the entire list in a single go, can be modified to load list after initial characters typed.
//

// Args:
// targetCtrl - id of text input control in text
// resultsDiv - id of div (in text) to contain table with list of matches
// webSvc - the web service name in text
// webCall - webCall to make (no args)
//

ffxLookup = function(targetCtrl, resultsDiv, webSvc, webCall) {
	this.srchCtrlId = targetCtrl;
	this.resultsDivId = resultsDiv;
	this.curListPos = -1;
	this.srchList = null;
	this.webService = webSvc;
	this.webCall = webCall;
	this.queryPrefix = 'lsearch';
	this.MinChars = 1;  /* minimum characters before showing list */
	this.maxResults = 10;   /* maximum number of elements to show in the list */
	this.navigateURL = null;  /* Alternate page to navigate to on search, if null uses current page */
	this.onClickReg = false;   /* set to true when document.onclick registered */

	// Set the query string prefix, default is [?&]lsearch=a-value-here
	this.SetQueryPrefix = function(qs) {
		this.queryPrefix = qs;
	}

	// Set the minumum number of characters before the list is displayed
	this.SetMinChars = function(mch) {
		this.MinChars = Number(mch);
	}

	// Set the maximum number of results to show in the list
	this.SetMaxResults = function(mres) {
		this.maxResults = Number(mres);
	}

	// Set the navigate url if you want to navigate away from the active page
	// the default action is to navigate to the same page
	this.SetNavigateURL = function(surl) {
		this.navigateURL = surl;
	}

	ffxLookup.prototype.Bind = function(fnMethod) {
		var objSelf = this;

		// Return a method that will call the given method
		// in the context of THIS object.
		return (
        function() {
			return (fnMethod.apply(objSelf, arguments));
		}
        );
	}

	// Sets the value of the search text field
	this.SetSearchValue = function(val) {
		if (val.length > 0) {
			var srch = document.getElementById(this.srchCtrlId);
			if (srch != null) {
				srch.value = val;
			}
		}
	}

	// Initialise the data (all in one go in this implementation
	this.WebServiceGetData = function(fltr) {
		if ((this.srchList == null) && (eval('typeof ' + this.webService) != 'undefined')) {
			var scall = this.webService + '.' + this.webCall + '(\'' + fltr + '\', this.Bind(this.OnWSRequestComplete))';
			eval(scall);
		}
	}

	// Callback funtion assigns results (must contain Name attribute) to class variable
	this.OnWSRequestComplete = function(results) {
		this.srchList = results;
	}

	// Remove the list entries
	this.ClearResults = function() {
		this.curListPos = -1;
		// remove search results table
		var divResults = document.getElementById(this.resultsDivId);
		if (divResults != null) {
			var counter = divResults.childNodes.length;
			for (var i = counter - 1; i >= 0; i--) {
				divResults.removeChild(divResults.childNodes[i]);
			}
		}
	}

	// Search has been selected
	// set doSearch=true to navigate to the search
	this.ReplaceSearch = function(tcell, doSearch) {
  		try
                {

		var srch = document.getElementById(this.srchCtrlId);
                
		srch.value = tcell.firstChild.nodeValue;
                
		this.ClearResults();
		if (doSearch) {
			return this.DoSearchText(srch.value);
		}
		return true;
		}catch(err){ }
		return true;
	}

	// Do the search - adds the search text to URL query
	this.DoSearch = function() {
		var srch = document.getElementById(this.srchCtrlId);
            
		if (srch != null && srch.value.length > 0) {
			return this.DoSearchText(srch.value);
		}
		return true;
	}
       this.DoSearch2 = function() {
		var srch = document.getElementById(this.srchCtrlId);
            
		if (srch != null && srch.value.length > 0) {
			return this.DoSearchText2(srch.value);
		}
		return true;
}
this.DoSearch3 = function() {
    var srch = document.getElementById(this.srchCtrlId);

    if (srch != null && srch.value.length > 0) {
        return this.DoSearchText3(srch.value);
    }
    return true;
}

	this.DoSearchText = function(stxt) {
		var srch = document.getElementById(this.srchCtrlId);
		if (stxt.length > 0) {
			this.ClearResults();
			if (this.navigateURL == null) {
				return ffxSetUrlParam(this.queryPrefix, stxt);
			} else {
				location.href = this.navigateURL + (this.navigateURL.indexOf('?') == -1 ? '?' : '&') + this.queryPrefix + '=' + stxt.replace(/ /g, '-');
			}
		}
		return true;
	}

	this.DoSearchText2 = function(stxt) {
	  alert(stxt);
		var srch = document.getElementById(this.srchCtrlId);
		if (stxt.length > 0) {
			this.ClearResults();
			if (this.navigateURL == null) {
				return ffxSetUrlParam(this.queryPrefix, stxt);
			} else {
				location.href = this.navigateURL + (this.navigateURL.indexOf('?') == -1 ? '?' : '&') + this.queryPrefix + '=' + stxt.replace(/ /g, '*');
			}
		}
		return true;
}
this.DoSearchText3 = function(stxt) {
    var srch = document.getElementById(this.srchCtrlId);
    if (stxt.length > 0) {
        this.ClearResults();
        if (this.navigateURL == null) {
            return ffxSetUrlParam(this.queryPrefix, stxt);
        } else {
            location.href = this.navigateURL + (this.navigateURL.indexOf('?') == -1 ? '?' : '&') + this.queryPrefix + '=' + stxt.replace(/ /g, '-')  + '&clubNZOnly=1';
        }
    }
    return true;
}

	// search an array for the supplied value - case sensitive
	this.inArray = function(arr, val) {
		var inarr = false;
		for (var i = 0; !inarr && i < arr.length; i++) {
			inarr = (arr[i] == val);
		}
		return inarr;
	}

	// Show the selection list
	// fltr - the filter to apply to contents
	this.ShowResults = function(fltr) {
		if (this.srchList == null) { return; }

		// When the user clicks on the doc, close the list
		if (!this.onClickReg) {
			EventWorker.addHandler("document.onclick", this.Bind(this.ClearResults));
			this.onClickReg = true;
		}

		this.ClearResults();

		var divResults = document.getElementById(this.resultsDivId);
		var tbl = document.createElement('table');
		tbl.setAttribute('id', this.srchCtrlId + 'tbl');
		var tbody = document.createElement('tbody');
		var trow, tcell, tnode;
		var arr = [];

		// Add rows that start with the filter
		for (var i = 0; i < this.srchList.length && arr.length < this.maxResults; i++) {
			var ctext = this.srchList[i].Name;
			var idx = ctext.indexOf(fltr);
			if (idx == 0) {
				if (!this.inArray(arr, ctext)) {
					arr[arr.length] = ctext;
				}
			}
		}

		if (arr.length < this.maxResults) {
			// Add matching rows that contain the filter when there are fewer
			// than 10 (this.maxResults) matches
			// Show from ther matching text forward
			for (var i = 0; i < this.srchList.length && arr.length < this.maxResults; i++) {
				var ctext = this.srchList[i].Name;
				var idx = ctext.indexOf(' ' + fltr);
				if (idx > 0) {
					var stext = ctext.substring(idx + 1);
					if (!this.inArray(arr, stext)) {
						arr[arr.length] = stext;
					}
				}
			}
		}
		// Sort the list before adding rows
		arr.sort();
		for (var i = 0; i < arr.length; i++) {
			this.AddRow(tbody, arr[i]);
		}

		tbl.appendChild(tbody);
		divResults.appendChild(tbl);

	}

	this.AddRow = function(tbody, txt) {
		var trow, tcell, tnode;

		trow = document.createElement('tr');
		tcell = document.createElement('td');
		tcell.className = 'ffxLookupNormalCell';
		tcell.onmouseover = function() { this.className = 'ffxLookupHighlightCell'; };
		tcell.onmouseout = function() { this.className = 'ffxLookupNormalCell'; };
		// Todo call replace
		var onclickCallback = this.Bind(this.ReplaceSearch);
		tcell.onclick = function() { onclickCallback(this, true); };
		tnode = document.createTextNode(txt);
		tcell.appendChild(tnode);
		trow.appendChild(tcell);
		tbody.appendChild(trow);
	}


	this.ListDown = function(tbl, pos) {
		var newPos = pos;
		if (tbl != null && tbl.firstChild != null && tbl.firstChild.childNodes.length > 0) {
			if (pos == -1) {
				newPos = 0;
			}
			else if (pos < tbl.firstChild.childNodes.length - 1) {
				newPos = pos + 1;
			}
			if (pos != -1) {
				tbl.firstChild.childNodes[pos].firstChild.className = 'ffxLookupNormalCell';
			}
			tbl.firstChild.childNodes[newPos].firstChild.className = 'ffxLookupHighlightCell';
		}
		return newPos;
	}

	this.ListUp = function(tbl, pos) {
		var newPos = pos;
		if (tbl != null && tbl.firstChild != null && tbl.firstChild.childNodes.length > 0) {
			if (pos <= 0) {
				newPos = tbl.firstChild.childNodes.length - 1;
			}
			else {
				newPos = pos - 1;
			}
			if (pos != -1) {
				tbl.firstChild.childNodes[pos].firstChild.className = 'ffxLookupNormalCell';
			}
			tbl.firstChild.childNodes[newPos].firstChild.className = 'ffxLookupHighlightCell';
		}
		return newPos;
	}

	this.GetCurrentSelection = function(tbl, pos) {
		if (tbl != null && pos >= 0 && pos < tbl.firstChild.childNodes.length) {
			return tbl.firstChild.childNodes[pos].firstChild.firstChild.nodeValue;
		}
		return '';
	}

	this.getSrchKey = function(e) {
		var key = 0;
		var evt = (e) ? e : (window.event) ? window.event : null;
		if (evt) {
			key = (evt.charCode) ? evt.charCode : ((evt.keyCode) ? evt.keyCode : ((evt.which) ? evt.which : 0));
		}
		return key
	}

	this.OnEnterKey = function(e) {
		if (this.getSrchKey(e) == 13) {
			return this.DoSearchText(this.GetCurrentSelection(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos));
		}
	}

	this.OnKeyPress = function(inp, e) {
		// Up arrow = 38, Down arrow = 40
		var ky = this.getSrchKey(e);
		if (ky == 13) {
		    // Do the search when enter is pressed and tehre is at lease on character in the text input
			if (inp.value.length > 0) {
				return this.DoSearchText(inp.value);
			}
		}
		else if (ky == 40) { // Down
			this.curListPos = this.ListDown(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos);
			this.SetSearchValue(this.GetCurrentSelection(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos));
		}
		else if (ky == 38) { // Up
			this.curListPos = this.ListUp(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos);
			this.SetSearchValue(this.GetCurrentSelection(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos));
		}
		else {
			if (inp.value.length >= this.MinChars) {
				this.ShowResults(inp.value, this.srchList);
				document.onkeydown = this.Bind(this.OnEnterKey);
				if (document.layers) document.captureEvents(Event.KEYDOWN);
			}
			else {
				this.ClearResults();
			}
		}
	}
		this.OnKeyPress2 = function(inp, e) {
		// Up arrow = 38, Down arrow = 40
		var ky = this.getSrchKey(e);
		if (ky == 13) {
		    // Do the search when enter is pressed and tehre is at lease on character in the text input
			if (inp.value.length > 0) {
				return this.DoSearchText2(inp.value);
			}
		}
		else if (ky == 40) { // Down
			this.curListPos = this.ListDown(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos);
			this.SetSearchValue(this.GetCurrentSelection(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos));
		}
		else if (ky == 38) { // Up
			this.curListPos = this.ListUp(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos);
			this.SetSearchValue(this.GetCurrentSelection(document.getElementById(this.srchCtrlId + 'tbl'), this.curListPos));
		}
		else {
			if (inp.value.length >= this.MinChars) {
				this.ShowResults(inp.value, this.srchList);
				document.onkeydown = this.Bind(this.OnEnterKey);
				if (document.layers) document.captureEvents(Event.KEYDOWN);
			}
			else {
				this.ClearResults();
			}
		}
	}

}

