  // FBTop.js
   
//change default loading behavior- ensure search_onload() gets called when the page is loaded
//this code will run on every page that includes FBTop.js
if(document.addEventListener)
	document.addEventListener("DOMContentLoaded", search_onload, false);
else 
	document.onreadystatechange = function() {
		if(document.readyState == "complete") {
			var orig_onload = document.body.onload;
			if(orig_onload != null)
				orig_onload(); //call the original onload function first
			document.body.onload = search_onload;
		}
	}

//avoid an infinite loop in firefox when hitting enter in the search box
var enterPressed = false;

//box showing our suggestions
var suggestionBox = null;
var documentLoaded = false;
var DEFAULT_TEXTBOX_VALUE = "Enter ISBN(s), or search by author, title (limited to 50 ISBNs)";
	
function search_onload() {
	documentLoaded = true;

	suggestionBox = new SuggestionBox(document.getElementById("searchBox"));
	
	if(document.getElementById("searchBox").value != DEFAULT_TEXTBOX_VALUE) {
		document.getElementById("searchBox").style.color = "#41585e";
		document.getElementById("searchBox").style.fontWeight = "bold";
		
		//remove beginning and trailing newlines from the searchbox- it looks nicer
		text = document.getElementById("searchBox").value;
		while(text.length > 0 && text[0] == '\n')
			text = text.substr(1, text.length - 1);
		while(text.length > 0 && text[text.length - 1] == '\n')
			text = text.substr(0, text.length - 1);
		document.getElementById("searchBox").value = text;
		
		showSuggestionBox();
	}
	
	//guarantee the suggestion query starts out blank
	document.getElementById("query").value = "";	
	document.body.onclick = bodyOnClick;
}

function searchBoxFocus() {
	if(document.getElementById("searchBox").value == DEFAULT_TEXTBOX_VALUE)
		document.getElementById("searchBox").value = "";
	document.getElementById("searchBox").style.color = "#41585e";
	document.getElementById("searchBox").style.fontWeight = "bold";
}

function searchBoxBlur() {
	if(document.getElementById("searchBox").value == "")
	{
		document.getElementById("searchBox").value = DEFAULT_TEXTBOX_VALUE;
		document.getElementById("searchBox").style.color = "#bbbbbb";
		document.getElementById("searchBox").style.fontWeight = "normal";
	}
}

function bodyOnClick(e) {
	if(!documentLoaded)
		return;
		
	if(!e)
		e = window.event;
		
	var result = suggestionBox.checkMouse(e.clientX, e.clientY);
	if(result == 0)
		suggestionBox.hide(); //hide if the textbox wasn't clicked
	else if(result == 2)
		suggestionBox.show(); //the textbox was clicked
		
}

//this will be called to update the suggestion box after .2 seconds
function onTimeout() {
	return suggestionBox.update(true);
}

function showSuggestionBox() {
	if(document.getElementById("searchBox").value.length > 0)
		suggestionBox.update(true);
}

//Used in search autosuggestions, submitting the ISBN box
function checkKeyUp(e) {
	var keyCode;
		
	if(window.event)
		keyCode = window.event.keyCode;
	else if(e.which)
		keyCode = e.which;
		
	//see if it's something to be concerned about, otherwise return
	if((keyCode < 48  && keyCode != 8  && keyCode != 9  && keyCode != 13 && keyCode != 32 && keyCode != 38 && keyCode != 40 && keyCode != 46) ||
	   (keyCode > 90  && keyCode < 96) || (keyCode > 111 && keyCode < 186))
			return;
  
	switch(keyCode)   
	{
		case 13: //enter key is pressed
			selected = suggestionBox.getSelectedElement();

			if(selected != null) //submit the selected suggestion
				selected.onclick();
			else //submit what's in the search box
				submitSearch();

			enterPressed = true;

			break;
		case 38: //up arrow is pressed
			if(suggestionBox.isVisible())
				suggestionBox.up();
			break;
		case 40: //down arrow is pressed
			if(suggestionBox.isVisible())
				suggestionBox.down();
			break;
		case 8: //backspace
			if(document.getElementById("searchBox").value.length > 2 && document.getElementById("searchBox").value.length < 25)
				suggestionBox.update(false);
			else
				suggestionBox.hide();
			break;
		case 9: //tab
			suggestionBox.hide();
			break;
		case 188: // Comma key is pressed
			if(!validateCommasEntered()){
				//window.alert("Reached max number of ',' to be entered in textarea");
			}

			break;
		default: //show autosuggest control
			if(!validateTextAreaCharacters()){
				//window.alert("Reached max number of characters to be entered in textarea");
			}
			
			suggestionBox.update(false);
			break;
	}
}

function validateCommasEntered(){
    var area = document.getElementById("searchBox");
        
    // our text in the textarea element
    var txt = area.value;

    // how many commas we have?
    var commas = txt.split(",").length;

    //var span = document.getElementById(_ticker);

    //var commas ++;
    if(commas > 49) {

      // grab last comma position
      var lastComma = txt.lastIndexOf(",");

      // delete all after last comma position
      area.value = txt.substring(0, lastComma);

      //it was count with + 1, so let's take that down
      commas--;

      return false; 

    } 
    else{
	return true; 
    }	

    if (txt == '') {
      commas = 0;

    }
    // show message
    //span.innerHTML = (max-commas);
}

var maxCharacters = 750;

function validateTextAreaCharacters(){
   
	if (document.getElementById("searchBox").value.length > 750){
		document.getElementById("searchBox").value = document.getElementById("searchBox").value.substring(0, 750);   
		alert("number of characters = " + document.getElementById("searchBox").value.length);
        	return false;
    	}
	else{
 	    return true;
	}
}

function submitSearch() {

	if(validateCommasEntered() && validateTextAreaCharacters()){

		if((document.getElementById("searchBox").value != DEFAULT_TEXTBOX_VALUE &&
			document.getElementById("searchBox").value.length > 2) || document.getElementById("query").value != "")
		{	
			
			document.forms['Search'].submit();
		}	
	}
}

/****************************
 **
 **  SuggestionBox definition
 **
 ****************************/

var TEXTBOX_OFFSET_X = 0;
var TEXTBOX_OFFSET_Y = 0;

var IMAGE = 0;
var TITLE = 1;
var AUTHOR = 2;
var ISBN = 3;

var MAX_NUM_RESULTS = 5;

//Constructor
function SuggestionBox(textbox) {
	this.textbox = textbox;
	this.layer = document.createElement("ul");
	this.layer.className = "suggestionbox";
	this.lastSearch = ""; //stores the last text searched for
	this.xPos;
	this.yPos;
	this.entries = [];
	this.search = null;
	this.currentTimeout = null; //for clearing a timeout
	
	this.isVisible = function() { return (this.layer.style.visibility == "visible"); };
	
	//initialize
	if(typeof XMLHttpRequest != "undefined")
		this.search = new XMLHttpRequest();
	else if(typeof ActiveXObject != "undefined") //for older browsers
		this.search = new ActiveXObject("Microsoft.XMLHTTP");
		
	//set layer left, right, and top position (absolute) on screen
	temp = this.textbox;
	x = 0;
	y = 0;
	while(temp.tagName != "BODY") {
		x += temp.offsetLeft;		
		y += temp.offsetTop;
		temp = temp.offsetParent;
	}
	this.xPos = x + TEXTBOX_OFFSET_X;
	this.yPos = y + this.textbox.offsetHeight + TEXTBOX_OFFSET_Y;
	this.layer.style.left = x + TEXTBOX_OFFSET_X;
	this.layer.style.top = y + this.textbox.offsetHeight + TEXTBOX_OFFSET_Y;
	
	this.layer.style.width = this.textbox.offsetWidth - TEXTBOX_OFFSET_X;
	
	//add suggestions
	for(var i = 0; i < MAX_NUM_RESULTS; i++) {
        entry = document.createElement("li");
        
        //entry structure:
        //       | Title
        // <IMG> | Author
        //       | 
        //       | ISBN: 
        
        table_main = document.createElement("table");
        tr_main = table_main.insertRow(0);
        td_main = tr_main.insertCell(0);
        
        image = document.createElement("img");
        image.width = 60;
        image.height = 70;
        image.style.margin = "2px 5px";
        td_main.appendChild(image);
        
        td_main = tr_main.insertCell(1);
        table = document.createElement("table");
        table.border = 0;
        table.cellspacing = 0;
        table.cellpadding = 0;
                
        //insert title, author, edition, blank line, and isbn
        td = table.insertRow(0).insertCell(0); 
		td.style.fontWeight = "bold";
		td.appendChild(document.createTextNode("")); 
        table.insertRow(1).insertCell(0).appendChild(document.createTextNode(""));        
        table.insertRow(2).insertCell(0).appendChild(document.createTextNode(""));     
        table.insertRow(3).insertCell(0).appendChild(document.createTextNode(""));            
        table.insertRow(4).insertCell(0).appendChild(document.createTextNode(""));
		
        td_main.appendChild(table);
        entry.appendChild(table_main);
        
        isbn = document.createElement("input");
        isbn.type = "hidden";
        entry.appendChild(isbn);
        
        entry.onmouseover = function() {
        	//remove the 'selected' status from the currently selected node
        	for(var i=0; i < this.parentNode.childNodes.length; i++)
				if(this.parentNode.childNodes[i].className == "selected")
					this.parentNode.childNodes[i].className = "";
			
        	this.className = "selected";
        };
        entry.onmouseout = function() { this.className = ""; };
        entry.onclick = function () {
        	document.getElementById("query").value = this.lastChild.value;
        	document.forms['Search'].submit();
        }
        
        this.layer.appendChild(entry);
	}
	
	this.layer.style.visibility = "hidden";
	
	document.body.appendChild(this.layer);
}

//Show function
SuggestionBox.prototype.show = function() {
	if(!this.isVisible() 			   && 
	    this.entries.length > 0  	   && 
	    this.textbox.value.length > 2  && 
	    this.textbox.value.length < 25) {
		
		if(this.textbox.value != this.lastSearch){
			this.update(true);
		}

		for(i = 0; i < this.entries.length; i++){
			this.layer.childNodes[i].style.visibility = "visible";
		}
	
		this.layer.style.visibility = "visible";
	}
}

//Hide function
SuggestionBox.prototype.hide = function() {
	
	if(this.isVisible()) {

		for(i = 0; i < this.layer.childNodes.length; i++){
			this.layer.childNodes[i].style.visibility = "hidden";
		}

		this.layer.style.visibility = "hidden";
	}
}

SuggestionBox.prototype.getSelectedIndex = function() {
	var i = 0;	
	while(i < this.layer.childNodes.length && 
		this.layer.childNodes[i].className != "selected"){

		//Increment index
		i++;
	}
	
	if(i == this.layer.childNodes.length){
		i = -1;
	}
	return i;
}

SuggestionBox.prototype.getSelectedElement = function() {
	index = this.getSelectedIndex();
	return (index != -1) ? this.layer.childNodes[index] : null;
}

//return 0: nothing clicked
//		 1: suggestion box clicked
//		 2: textbox clicked
SuggestionBox.prototype.checkMouse = function(x, y) {
	var result = 0; //this wasn't clicked
	
	if((x >= this.xPos) &&
	   (x <  this.xPos + this.layer.offsetWidth) &&
	   (y >= this.yPos) &&
	   (y <  this.yPos + this.layer.offsetHeight)){

		//suggestion box was clicked
   		result = 1; 
	}	
	else if((x >= this.xPos) &&
	   (x <  this.xPos + this.textbox.offsetWidth - TEXTBOX_OFFSET_X) &&
	   (y >= this.yPos - this.textbox.offsetHeight - TEXTBOX_OFFSET_Y) &&
	   (y <  this.yPos)){

		//textbox was clicked
	   	result = 2; 
	}
	
	return result;
}

SuggestionBox.prototype.update = function(updateNow) {
	if(updateNow)
		if(this.textbox.value.length > 2 && this.textbox.value.length < 25) {
			
			this.getSuggestions(this, this.textbox.value.toUpperCase());
			this.lastSearch = this.textbox.value;

			if(this.entries.length > 0){
				this.show();
			}
		}
		else
			this.hide();
	else {

		clearTimeout(this.currentTimeout);

		//get suggestions in .2 seconds, if no more keys are pressed
		var command = "onTimeout()";
		this.currentTimeout = setTimeout(command, 200);
	}
}

SuggestionBox.prototype.updateList = function() {
	//clear current list contents
	//while(this.layer.hasChildNodes())
	//	this.layer.removeChild(this.layer.lastChild);
	
	//if no results, hide and return
	if(this.entries.length == 0) {
		this.hide();
		return;
	}
	
	for(var i = 0; i < MAX_NUM_RESULTS; i++) {
		list_item = this.layer.childNodes[i];
		
		if(i < this.entries.length) {
			list_item.style.visibility = 'visible';
			
			//set image src
			list_item.firstChild.rows[0].cells[0].firstChild.src = this.entries[i][IMAGE];
			
			//set title, author, and isbn text
			rows = list_item.firstChild.rows[0].cells[1].firstChild.rows;
			rows[0].cells[0].firstChild.data = this.entries[i][1];
			rows[1].cells[0].firstChild.data = this.entries[i][2];
			rows[2].cells[0].firstChild.data = "Edition: " + this.entries[i][3];
			rows[4].cells[0].firstChild.data = "ISBN: " + this.entries[i][5];
			
			//set hidden isbn field
			list_item.lastChild.value = this.entries[i][5];
		}
		else{
			list_item.style.visibility = 'hidden';
		}
	}
	
	this.show();
}

//navigate up
SuggestionBox.prototype.up = function() {

	if(!this.isVisible()){
		return;
	}

	if(this.getSelectedIndex() >= 0){

		var index = this.getSelectedIndex();
		this.layer.childNodes[index].className = "";
		
		//if the top index is currently selected, going up selects no item
		if(index > 0){
			this.layer.childNodes[index - 1].className = "selected";
		}
	}
}

//navigate down
SuggestionBox.prototype.down = function() {

	if(!this.isVisible()){
		return;
	}

	if(this.getSelectedIndex() < this.entries.length - 1){

		var index = this.getSelectedIndex();
		if(index >= 0){
			this.layer.childNodes[index].className = "";
		}

		this.layer.childNodes[index + 1].className = "selected";
	}
}

//get suggestions
// obj: reference to the current suggestion box
// str: string to search for
SuggestionBox.prototype.getSuggestions = function(obj, str) {
	//browser too old or not enough characters to search for
	if(this.search == null || 
	  (this.textbox.value.length < 3 && document.getElementById("searchBox").value.length > 50)){
		return;
	}
	
	var request = this.search;

	if(request.readyState != 0)	{
		request.abort(); //end any already pending queries
		this.entries = [];
	}
	
	request.open("get", "/SuggestBooks?query=" + encodeURIComponent(str), true);
	request.setRequestHeader("Cache-Control", "no-store"); //must call setRequestHeader twice in IE
	request.setRequestHeader("Cache-Control", "no-store");
	
	request.onreadystatechange = function() {
		if(request.readyState == 4 && request.status == 200) {
			obj.entries = eval(request.responseText);
			obj.updateList();
		}
	};
    request.send(null);
}
