/*
	Title: PredictiveSearchive Search (AJAX) [Version 2]
	Description: AJAX search assistance scripts
	Author: Nick Payne, James Hartcher
	Created: 30/08/2005
	Modified: 11/12/2006
	
	Copyright © 2005/6 Internet Design Studios Pty Ltd, All Rights Reserved
	www.idstudios.com.au
*/

/*
--------------------------------------------------------------------------------
	Properties
--------------------------------------------------------------------------------
*/
// Declare variables to give them global scope
var objSearchData 	= null // XML Request
var objResults 		= null // Results List

/*
--------------------------------------------------------------------------------
	Main
--------------------------------------------------------------------------------
*/
// PredictiveSearch input
function PredictiveSearch(evt) {

	// Get event and target
	evt = getEvent(evt)
	var target = getTarget(evt)
	
	// Get search terms
	var include = null //getSelected(document.frmSearch.radInclude)
	var type = null //getSelected(document.frmSearch.radSearchType)
	var criteria = target.value
	
	// Capture keypress
	var key = getKey(evt)
	
	// Handle different presses
	switch(key) {
		case null:
			// Don't need to get any data
			return false
			break
		case "BACKSPACE":
			// Remove last character from value
			criteria = criteria.slice(0,-1)
			objResults.deSelect()
			break
		case "DOWN":
			// Select item in list
			objResults.select(1)
			return false
			break
		case "UP":
			// Select item in list
			objResults.select(-1)
			return false
			break
		case "ESC":
			// Clear list
			objResults.clear()
			objResults.ul.style.visibility = "hidden"
			break
		default:
			// Append key to end of criteria
			criteria += key
	}
	
	// Clear Results (no text)
	if (criteria == "") {
		// Clear list
		objResults.clear()
		objResults.ul.style.visibility = "hidden"
	}
	
	// Get the XML data
	objSearchData.query = ("Criteria=" + criteria)
	objSearchData.go()
	
	// Return success
	return true
}

/*
--------------------------------------------------------------------------------
	XML Response Handler
--------------------------------------------------------------------------------
*/
function DisplayResults(xmlResponse) {

	// Get nodelist
	var actorNodes 	= xmlResponse.getElementsByTagName("name");
	var ulResults 	= document.getElementById("ulResults")
	
	// Remove previous objResults
	objResults.clear()
	
	// Are there any objResults?
	if(actorNodes.length) {

		// Unhide if necessary
		var inpCriteria = document.getElementById("SearchCriteria")
		ulResults.style.width = inpCriteria.clientWidth
		ulResults.style.visibility = "visible"
					
		// Display objResults
		for(i = 0; i < actorNodes.length; i++) {
			objResults.addItem(actorNodes.item(i).firstChild.nodeValue)
		}

	} else {
		// Hide the list
		ulResults.style.visibility = "hidden"
	}

}

/*
--------------------------------------------------------------------------------
	LI Item event handlers
--------------------------------------------------------------------------------
*/
function liMouseOver(evt) {

	// Get event
	evt = getEvent(evt)
	
	// Get target
	var target = getTarget(evt)
	
	// Deselect anything else
	objResults.deSelect()
	
	// Highlight
	target.style.backgroundColor = "#0a246a"
	target.style.color = "#ffffff"
	
}

function liMouseOut(evt) {

	// Get event
	evt = getEvent(evt)
	
	// Get target
	if(evt.target) {
		target = evt.target
	} else if(evt.srcElement) {
		target = evt.srcElement
	}
	
	//window.alert(target.style.backgroundColor)
	
	target.style.backgroundColor = ""
	target.style.color = "#000000"
	
}

// Click event for items
function liClick(evt) {

	// Get event
	evt = getEvent(evt)
	
	// Get target
	if(evt.target) {
		target = evt.target
	} else if(evt.srcElement) {
		target = evt.srcElement
	}
	
	document.getElementById("SearchCriteria").value = target.firstChild.nodeValue
	document.getElementById("ulResults").style.visibility = "hidden"
}

/*
--------------------------------------------------------------------------------
	Helper Functions
--------------------------------------------------------------------------------
*/
// Get event which fired
function getEvent(evt) {
		if (!evt) {
			var evt = window.event // Handle IE
		}
		return evt
}

// Get the target of the event
function getTarget(evt) {
	// Cope with different browsers
	if(evt.target) {
		// Everything else
		target = evt.target
		
	} else if(evt.srcElement) {
		// IE
		target = evt.srcElement
		
	}
	// Return target
	return target
}

// Get the key pressed
function getKey(evt) {
	// Get key pressed
	if (evt.which) {
		code = evt.which
	} else if (evt.keyCode) {
		code = evt.keyCode
	}
	// Convert specific key strokes
	switch(code) {
		case 8:
			key = "BACKSPACE"
			break
		case 27:
			key ="ESC"
			break
		case 38:
			key = "UP"
			break
		case 40:
			key = "DOWN"
			break
		default:
			if(code > 48) {
				key = String.fromCharCode(code)
			} else {
				key = null
			}
	}
	// Convert keycode to string
	return key
}

// Get input selected from group of inputs
function getSelected(inputs) {
	// Loop through inputs
	for(i=0; i<inputs.length; i++) {
		// Is this the one?
		if(inputs.item(i).checked) {
			// Yes is it lets return the value
			return inputs.item(i).value
		}
	}
}

/*
--------------------------------------------------------------------------------
	Results List CLASS
--------------------------------------------------------------------------------
*/
// Results list class
function ResultsList(inpId, ulId) {

	// Properties
	this.inp = document.getElementById(inpId) // The input object
	this.ul = document.getElementById(ulId) // The list object
	this.selectedIndex = -1 // Item selected. -1 is none.
	this.selectedValue = null // Value of selected item.
	this.length = 0 // Number of items
	
	// Operations
	this.addItem = ResultsList_addItem // Adds a new item to the list
	this.clear = ResultsList_clear // Removes all items from array
	this.deSelect = ResultsList_deSelect // Deselect all items
	this.select = ResultsList_select // Scroll through list
	
}

// Add item to objResults list
function ResultsList_addItem(value) {

	// Add new item
	var li = document.createElement("li")
	var liText = document.createTextNode(value)
	this.ul.appendChild(li)
	this.ul.lastChild.appendChild(liText)
	
	// Set event handlers
	li.onmouseover = liMouseOver
	li.onmouseout = liMouseOut
	li.onclick = liClick
	
	// Advance length
	this.length ++
}

// Clear items from objResults list
function ResultsList_clear() {
	// Loop through items
	for(i = 0; i < this.length; i++) {
		// Remove
		this.ul.removeChild(this.ul.childNodes.item(0))
	}
	
	// Clear length
	this.length = 0
}

// Deselect all items. Used by ResultsList_select
function ResultsList_deSelect() {
	// Deselect index
	this.selectedIndex = -1
	this.selectedValue = null
	// Loop through each li
	for(i = 0; i < this.length; i++) {
		// Deselect item
		var li = this.ul.childNodes.item(i)
		li.style.backgroundColor = ""
		li.style.color = "#000000"
	}
}

// Provides functionality to scroll up and down through the PredictiveSearchion list
function ResultsList_select(direction) {

	// Save new index
	var index = this.selectedIndex + direction
	
	// Update the selected index
	if(index > -1 && this.length > 0 && index < this.length) {
		// Deselect all items
		this.deSelect()
		// Change the selected index
		this.selectedIndex = index
		 // Get the new li item
		var li = this.ul.childNodes.item(this.selectedIndex)
		// Change the background colour
		li.style.backgroundColor = "#0a246a"
		li.style.color = "#ffffff"
		// Update the input field
		this.selectedValue = li.firstChild.nodeValue
		this.inp.value = this.selectedValue
	}
}

/*
--------------------------------------------------------------------------------
	XML Request Class
--------------------------------------------------------------------------------
*/
// Constructor
function xmlRequest() {

	// Properties
	this.request 		= null // XmlHttpRequest
	this.uri 			= null // URI for request
	this.type 			= "GET" // Request type; i.e. "GET" or "POST"
	this.query 			= null // Querystring to POST or GET to URI
	this.responseXML 	= null // XML Response
	this.responseText 	= null // Text response
	this.handler		= null // Function to execute on receipt of response
	
	// Operations
	this.go 				= xmlRequest_go // Get data
	this.responseHandler 	= XMLRequest_Handler // Handle returned data
}

// Go get data
function xmlRequest_go() {

	// Check for running connections
	if (this.request != null && this.request.readyState != 0 && 
			this.request.readyState != 4) {
		// Cancel current request so we can initiate a new one
		this.request.abort()
	}
	
	// Instantiate new XML HTTP this.request object
	if (window.XMLHttpRequest) {
		// Mozilla, Safari
		this.request = new XMLHttpRequest()
		if (this.request.overrideMimeType) {
			this.request.overrideMimeType("text/xml");
		}
	} else if (window.ActiveXObject) { // IE
		try {
			this.request = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (error) {
			try {
				this.request = new ActiveXObject("Microsoft.XMLHTTP")
			} catch (error) {}
		}
	}
	if (!this.request) {
		// Didn't work at all we'll return false so this feature doesn't do anything
		this.request = null
		return false
	}
	
	// Assign handler
	var self = this // Required to overcome bug
	this.request.onreadystatechange = function() { // Allows us to pass xmlRequest
		XMLRequest_Handler(self)				 // object to function. Otherwise
													// we can't access it.
	}
	
	// What type of query is this
	if(this.type == "GET") {
		// Construct the query
		var uri = this.uri
		// Is there a querystring?
		if(this.query) {
			uri += "?" + this.query
		}
		// Get the XML data
		this.request.open("GET", uri)
		this.request.send(null)
	} else if (this.type == "POST") {
		// Get the XML data
		this.request.open("POST", this.uri)
		this.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
		this.request.send(this.query)
	} else {
		// Can't handle this type
		return false
	}
	
	// Return success
	return true
}

// Handles XML Response
function XMLRequest_Handler(caller) {
	// Check state
	if (caller.request.readyState == 4) {
		if(caller.request.status == 200) {
			// Execute user handler
			eval(caller.handler + "(caller.request.responseXML)")
		} else {
			// Failed to get xml data
			//window.alert("FAILURE")
		}
	}
	// Finished
	return true
}

/*
--------------------------------------------------------------------------------
	Page Load
--------------------------------------------------------------------------------
*/
// Onload initialise objects
function InitSearch() {
	objResults 				= new ResultsList("SearchCriteria", "ulResults") // Declare ResultsList object
	objSearchData 			= new xmlRequest() // Declare xmlRequest object
	objSearchData.uri 		= "../xml/website_search.asp"
	objSearchData.type 		= "POST"
	objSearchData.handler 	= "DisplayResults"
}
