// JavaScript Document
var getFunctionsUrl = "../search/initSuggest.php?keyword=";
var phpHelpUrl = "http://www.fhs1988.org";
var httpRequestKeyword = "";
var userKeyword = "";
var suggestions = 0;
var suggestionMaxLength = 50;
var isKeyUpDownPressed = false;
var autocompletedKeyword = "";
var hasResults = false;
var timeoutId = -1;
var position = -1;
var oCache = new Object();
var minVisiblePosition = 0;
var maxVisiblePosition = 9;
var debugMode = true;
var xmlHttpGetSuggestions = createXmlHttpRequestObject();
window.onload = init;

function createXmlHttpRequestObject()
{
	var xmlHttp;
	try 
	{
		xmlHttp = new XMLHttpRequest();
	}
	catch(e)
	{
		var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
										"MSXML2.XMLHTTP.5.0",
										"MSXML2.XMLHTTP.4.0",
										"MSXML2.XMLHTTP.3.0",
										"MSXML2.XMLHTTP",
										"Microsoft.XMLHTTP");h
		for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++)
		{
			try
			{
				xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
			}
			catch (e) {}
		}
	}
	if (!xmlHttp)
	  alert("Error creating the XMLHttpRequest object.");
	else
	  return xmlHttp;
}

function init()
{
	var oKeyword = document.getElementById("keyword");
	if (oKeyword)
	{
	  oKeyword.setAttribute("autocomplete", "off");
	  oKeyword.value="";
	  oKeyword.focus();
	  setTimeout("checkForChanges()", 500);
	}
}

function addToCache(keyword, values)
{
	oCache[keyword] = new Array();
	
	// Add all the values to the keyword's entry in the cache
	for (i=0; i<values.length; i++)
	{
	  oCache[keyword][i] = values[i];
	}
}

function checkCache(keyword)
{
	if (oCache[keyword])
	  return true;
	
    // Logic to try and match shorter keywords removed - only match exact
	
	// If no match found
	return false;
}

function getSuggestions(keyword)
{	
    //alert ('in getSuggestions!');
	if (!isKeyUpDownPressed)
	{
		isInCache = checkCache(keyword);
		
		if (isInCache == true)
		{
		  httpRequestKeyword = keyword;
		  userKeyword = keyword;
		  displayResults(keyword, oCache[keyword]);
		}
		// if the keyword isn't in cache, make an HTTP request
		else
		{
		  if (xmlHttpGetSuggestions)
		  {
			 try
			 {
				if (xmlHttpGetSuggestions.readyState == 4 ||
					xmlHttpGetSuggestions.readyState == 0)
				{
				  httpRequestKeyword = keyword;
				  userKeyword = keyword;
				  xmlHttpGetSuggestions.open("GET",
											 getFunctionsUrl + encode(keyword), true);
				  xmlHttpGetSuggestions.onreadystatechange = handleGettingSuggestions;
				  xmlHttpGetSuggestions.send(null);
				}
				else
				{
				  userKeyword = keyword;
				  if (timeoutId != -1)
				    clearTimeout(timeoutId);
				  timeoutId = setTimeout("getSuggestions(userKeyword);", 500);
				}
			 }
			 catch (e)
			 {
				 displayError("Can't connect to server:\n" + e.toString());
			 }
		  }
		}
	}
}

function xmlToArray(resultsXml)
{
	// initiate the resultsArray
	var resultsArray = new Array();
	
	// loop through all the xml nodes retrieving the content
	for (i=0; i<resultsXml.length; i++)
	  resultsArray[i] = resultsXml.item(i).firstChild.data;
	
	// return the node's content as an array
	return resultsArray;
}

function handleGettingSuggestions()
{
	if (xmlHttpGetSuggestions.readyState == 4)
	{
		if (xmlHttpGetSuggestions.status == 200)
		{
			try
			{
				// process the servers response
				updateSuggestions();
			}
			catch (e)
			{
				displayError('in handleGettingSuggestions ' + e.toString());
			}
		}
		else
		{
			displayError("There was a problem retrieving the data:\n" +
						 xmlHttpGetSuggestions.statusText);
		}
	}
}

function updateSuggestions()
{
	// retrieve the server's suggestion
	var response = xmlHttpGetSuggestions.responseText;
	
	// DEBUG
	//alert ('response = ' + response);
	
	// server error?
	if (response.indexOf("ERRNO") >= 0
        || response.indexOf("error:") >= 0
		|| response.length == 0)
	    throw(response.length == 0 ? "Void server response." : response);
		
	// DEBUG	
	//alert ('About to retrieve document');

	// retrieve the document element
	var response = xmlHttpGetSuggestions.responseXML.documentElement;
	
	// initialize the new array of program names and urls
	nameArray = new Array();
	//urlArray = new Array();
	
	// DEBUG
    //alert ('document retrieved = ' + response);
	
	// check to see if we have any results for the searched keyword
	if (response && response.childNodes.length)
	{
		nameArray = xmlToArray(response.getElementsByTagName("name"));
	}
	if (httpRequestKeyword == userKeyword)
	{
	  // display the results array
	  displayResults(httpRequestKeyword, nameArray);
	}
	else
	{
       addToCache(httpRequestKeyword, nameArray);
	}
}

function displayNewResults(keyword, results_array)
{
    liveSearch = new LiveSearch(
       'http://www.fhs1988.org/classmates.php',
       document.getElementById('keyword'),
       '../search/programXML.php',
       '../search/search-results.xsl',
       {}
     );
}

function displayResults(keyword, results_array)
{
	displayNewResults(keyword, results_array);
	
	if (results_array.length > 0)
	  autocompleteKeyword();
	
	return;
}

function checkForChanges()
{
	var keyword = document.getElementById("keyword").value;
	if (keyword == "")
	{
	  hideSuggestions();
	  // reset the keywords
	  if (userKeyword != "")
	  {
		  userKeyword = "";
		  getSuggestions(keyword);
	  }
	   
	  userKeyword = "";
	  httpRequestKeyword = "";
	  // need a way to call this only if it changed from previous
	  //getSuggestions(keyword);
	}
	// set the timer for a new check
	setTimeout("checkForChanges()", 500);
	// check to see if there are any changes
	if ((userKeyword != keyword) &&
		 (autocompletedKeyword != keyword) &&
		 (!isKeyUpDownPressed))
	    // update the suggestions
	{
	    getSuggestions(keyword);
	}
}

function handleKeyUp(e)
{
  e = (!e) ? window.event : e;
  target = (!e.target) ? e.srcElement : e.target;
  if (target.nodeType == 3)
    target = target.parentNode;
  
  code = (e.charCode) ? e. charCode :
          ((e.keyCode) ? e.keyCode :
		  ((e. which) ? e.which : 0));
 
  if (e.type == "keyup")
  {
    isKeyUpDownPressed = false;

    if ((code < 13 && code != 8) ||
		(code >=14 && code < 32) ||
		(code >= 33 && code <=46 && code != 38 && code != 40) ||
		(code >= 112 && code <= 123))
	{
	  //alert ('ignoring!');
	}
	else
	{
	  // Processing "Enter"
	  if (code == 13)
	  {
	    if (position >= 0)
		{
		  //location.href = document.getElementById("a" + position).href;
		}
	  }
	  else if (code == 40)
	  {
		if (position >= 0 && position < suggestions -1)
		  oldTR.className = "";
		if (position < suggestions - 1)
		{
			newTR.className = "highlightrow";
			updateKeywordValue(newTR);
			position++;
		}
		e.cancelBubble = true;
		e.returnValue = false;
		isKeyUpDownPressed = true;
		if (position > maxVisiblePosition)
		{
		  maxVisiblePosition += 1;
		  minVisiblePosition += 1;
		}
	  }
	  else if (code == 38)
	  {
		
		if (position > 0)
		{
			newTR.className = "highlightrow";
			updateKeywordValue(newTR);
			position--;
			if (position < minVisiblePosition)
			{
		      maxVisiblePosition -= 1;
		      minVisiblePosition -= 1;
			}
		}
		else if (position ==0)
		  position--;
		
		e.cancelBubble = true;
		e.returnValue = false;
		isKeyUpDownPressed = true;
	  }
	}
  }
}

function updateKeywordValue(oTr)
{
  var oKeyword = document.getElementById("keyword");
}

function deselectAll()
{
}

function handleOnMouseOver(oTr)
{
	deselectAll();
	oTr.className = "highlightrow";
	position = oTr.id.substring(2, oTr.id.length);
}

function handleOnMouseOut(oTr)
{
	oTr.className = "";
	position = -1;
}

function encode(uri)
{
	if (encodeURIComponent)
	{
		return encodeURIComponent(uri);
	}
	
	if (escape)
	{ 
	  return escape(uri);
	}
}

function hideSuggestions()
{
}

function selectRange(oText, start, length)
{
	if (oText.createTextRange)
	{
		// IE
		var oRange = oText.createTextRange();
	}
	else
	{
		// FF/Opera
		if (oText.setSelectionRange)
		  oText.setSelectionRange(start, length);	  
	}
	oText.focus();
}

function autocompleteKeyword()
{
	// retrieve the keyword object
	var oKeyword = document.getElementById("keyword");
	position = 0;
	deselectAll();
	
	selectRange(oKeyword,httpRequestKeyword.length,oKeyword.value.length);
	autocompletedKeyword=oKeyword.value;
}

function displayError(message)
{
	alert("Error accessing server: " + (debugMode ? "\n" + message : ""));
}

//-------------------- mContentLoader.js
var net = new Object();

net.READY_STATE_UNINITIALIZED= 0;
net.READY_STATE_LOADING      = 1;
net.READY_STATE_LOADED       = 2;
net.READY_STATE_INTERACTIVE  = 3;
net.READY_STATE_COMPLETE     = 4;

net.ContentLoader = function( component, url, method, requestParams ) {
   this.component     = component;
   this.url           = url;
   this.requestParams = requestParams;
   this.method        = method;
}

net.ContentLoader.prototype = {

   getTransport: function() {
      var transport;
      if ( window.XMLHttpRequest )
         transport = new XMLHttpRequest();
      else if ( window.ActiveXObject ) {
         try {
            transport = new ActiveXObject('Msxml2.XMLHTTP');
         }
         catch(err) {
            transport = new ActiveXObject('Microsoft.XMLHTTP');
         }
      }
      return transport;
   },

   sendRequest: function() {

      var requestParams = []
      for ( var i = 0 ; i < arguments.length ;  i++ )
         requestParams.push(arguments[i]);

      var oThis = this;
      var request = this.getTransport();
      request.open( this.method, this.url, true );
      request.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded');
      request.onreadystatechange = function() { oThis.handleAjaxResponse(request) };
      request.send( this.queryString(requestParams) );
  },

  queryString: function(args) {

     var requestParams = [];
     for ( var i = 0 ; i < this.requestParams.length ; i++ )
        requestParams.push(this.requestParams[i]);
     for ( var j = 0 ; j < args.length ; j++ )
        requestParams.push(args[j]);

     var queryString = "";
     if ( requestParams && requestParams.length > 0 ) {
        for ( var i = 0 ; i < requestParams.length ; i++ )
           queryString += requestParams[i] + '&';
        queryString = queryString.substring(0, queryString.length-1);
     }
     return queryString;
  },

  handleAjaxResponse: function(request) {
     if ( request.readyState == net.READY_STATE_COMPLETE ) {
        if ( this.isSuccess(request) )
           this.component.ajaxUpdate(request);
        else
           this.component.handleError(request);
     }
  },

  isSuccess: function(request) {
    return  request.status == 0
        || (request.status >= 200 && request.status < 300);
  }

};

//-------------------- XSLT setup

function LiveSearch( pageURL, lookupField, xmlURL, xsltURL, options ) {
   this.pageURL      = pageURL;
   this.lookupField  = lookupField;
   this.xmlURL       = xmlURL;
   this.xsltURL      = xsltURL;
   this.setOptions(options);

   var oThis = this;
   lookupField.form.onsubmit = function() { oThis.doSearch(); return false; };
   this.initialize();
   oThis.doSearch();
}

LiveSearch.prototype = {

   	doSearch: function() {
    if ( XSLTHelper.isXSLTSupported() )
         this.doAjaxSearch();
    else
         this.submitTheForm();
   },

   setOptions: function(options) {
      this.options = options;

      if ( !this.options.loadingImage        ) this.options.loadingImage = 'http://www.fhs1988.org/images/loading.gif';
      if ( !this.options.bookmarkContainerId ) this.options.bookmarkContainerId = 'bookmark';
      if ( !this.options.resultsContainerId  ) this.options.resultsContainerId  = 'contents';
      if ( !this.options.bookmarkText        ) this.options.bookmarkText = 'Bookmark Search';
   },

   initialize: function() {
      var currentLocation  = document.location.href;
      var qIndex = currentLocation.indexOf('q=');
      if ( qIndex != -1 ) {
         this.lookupField.value = currentLocation.substring( qIndex + 2 );
      this.doSearch();
      }
   },

   doAjaxSearch: function() {
      this.showLoadingImage();
      var searchUrl = this.appendToUrl( this.xmlURL, 'keyword', this.lookupField.value );
      new XSLTHelper( searchUrl, this.xsltURL ).loadView( this.options.resultsContainerId );
      this.updateBookmark();
   },

   submitTheForm: function() {
      var searchForm = this.lookupField.form;
      searchForm.onsubmit = function() { return true; };
      searchForm.submit();
   },

   showLoadingImage: function() {
      var newImg = document.createElement('img');
	  newImg.setAttribute("class", "loading");
      newImg.setAttribute('src', this.options.loadingImage );
      document.getElementById(this.options.resultsContainerId).appendChild(newImg);
   },

   appendToUrl: function(url, name, value) {
      var separator = '?';
      if (url.indexOf(separator) > 0)
         separator = '&';

      return url + separator + name + '=' + value;
   },

   updateBookmark: function() {
      var container = document.getElementById(this.options.bookmarkContainerId);
      var bookmarkURL = this.appendToUrl( this.pageURL, 'q', this.lookupField.value );
      if ( container )
         container.innerHTML = '<a href="' + bookmarkURL + '" >' +
               this.options.bookmarkText + '</a>';
   }
}

//-------------------- mxsltHelper.js

function XSLTHelper( xmlURL, xslURL  ) {
   this.xmlURL = xmlURL;
   this.xslURL = xslURL;
}

XSLTHelper.isXSLTSupported = function() {
   return (window.XMLHttpRequest && window.XSLTProcessor ) ||
          XSLTHelper.isIEXmlSupported();
}

XSLTHelper.isIEXmlSupported = function() {
   if ( ! window.ActiveXObject )
      return false;
   try { new ActiveXObject("Microsoft.XMLDOM");  return true; }
   catch(err) { return false; }
}

XSLTHelper.prototype = {

   loadView: function(container) {
      if ( ! XSLTHelper.isXSLTSupported() )
         return;

      this.xmlDocument   = null;
      this.xslStyleSheet = null;
	  this.container = $(container);

      new Ajax.Request( this.xmlURL,
                        {onComplete: this.setXMLDocument.bind(this)} );
      new Ajax.Request( this.xslURL,
                        {method: "GET",
                        onComplete: this.setXSLDocument.bind(this)} );
   },

   setXMLDocument: function(request) {
      this.xmlDocument = request.responseXML;
      this.updateViewIfDocumentsLoaded();
   },

   setXSLDocument: function(request) {
      this.xslStyleSheet = request.responseXML;
      this.updateViewIfDocumentsLoaded();
   },

   updateViewIfDocumentsLoaded: function() {
      if ( this.xmlDocument == null || this.xslStyleSheet == null )
         return;
      this.updateView();
   },

   updateView: function () {
      if ( ! XSLTHelper.isXSLTSupported() )
         return;

     if ( window.XMLHttpRequest && window.XSLTProcessor )
         this.updateViewMozilla();
      else if ( window.ActiveXObject )
         this.updateViewIE();
   },

   updateViewMozilla: function() {
      var xsltProcessor = new XSLTProcessor();
      xsltProcessor.importStylesheet(this.xslStyleSheet);
      var fragment = xsltProcessor.transformToFragment(this.xmlDocument, document);

      this.container.innerHTML = "";
      this.container.appendChild(fragment);
   },

   updateViewIE: function(container) {
      this.container.innerHTML = this.xmlDocument.transformNode(this.xslStyleSheet);
   }
}