var lookup_xmlReq;//XMLHttpRequest object
var jg_lookup;//jsGraphics object used to draw the floating data box
var lookup_key;//key string in the lookup field entered by user

var lookup_ie_offset = 0;//left box corner offset for possible IE browsers eg: bobb/chart/display.php, in most cases no offset exists
var lookup_ns_offset = 0;//left box corner offset for possible NS browsers eg: bobb/chart/display.php, in most cases no offset exists

//var lookup_char_width = 7;//width of character in pixels
var lookup_char_height = 15;//height of character in pixels
var lookup_font_size = 11; //size of font
//var lookup_font_type = "Verdana";//type of font
var lookup_font_type  = "Verdana";

//var lookup_symbol_width = 60;//pixel space allocated for symbol per lookup box row
var lookup_name_width = 200;//pixel space allocated for name per lookup box row
var lookup_box_pixel_width = 300;//drop down lookup box width in pixels

var lookup_box_color = "#ffffff";//color of box background(grey)#d7d7d7
var lookup_highlight_color = '#D6F7FF';//color of highlighted text 3399FF
var lookup_text_color = '#000000'; //color of text (black)

var highlight_index = -1;//index of the highlighted hit in the lookup box set to -1 when no hit is highlighted

var lookup_symbol = new Array();//stores symbols
var lookup_name = new Array();//stores the names of the symbols
var lookup_level = new Array();//stores the levels of symbols

var lookup_max_search = 30;//maximum number of hits to be displayed from xml file

var lookup_field;//field object pointing to the lookup field text box
var lookup_boxCorner = {left:0, top:0};//x, y coordinates of the lookup box upper left corner

var lookup_submit = 1;//submit flag set when form submits on lookup symbol selection, reset to 0 when selection doesn't submit

//Key pressing events handlers

/***********************************************
* Disable "Enter" key in Form script- By Nurul Fadilah(nurul@REMOVETHISvolmedia.com)
* This notice must stay intact for use
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/
var counter;
counter = 0;
//http://www.dynamicdrive.com/dynamicindex16/disableenter.htm
function handleEnter (field, event, flag) {//handles events when enter or tab is pressed in text box
	lookup_submit = flag;//initialize submit flag
	var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;
	lookup_field = field;
	//enter or tab is pressed
	if ((keyCode == 13)||(keyCode==9)){
		
		//fill in form with selected option
		if (highlight_index != -1)//when a symbol is already highlighted
			fill(lookup_symbol[highlight_index]);//display that symbol
		
		boxClear();//clear lookup box
		
		if ((lookup_submit == 1)&&(keyCode == 13))//when submit flag is set, then submit form on enter
			lookup_field.form.submit();//submit form
			
		//move to the next form field
		var i;
		for (i = 0; i < field.form.elements.length; i++)
			if (field == field.form.elements[i])
				break;
		
		i = (i + 1) % field.form.elements.length;
		if (i!=0)//if end of form, then submit
		{
			field.form.elements[i].focus();
			return false;//do not process enter
		}
	}else{
		if (keyCode == 27){//escape key pressed
			boxClear();//clear box
			lookup_field.value = lookup_key;//text box value to key
		//}else if ((charCode != 37)&&(charCode != 39)){ //37:left arrow, 39: right arrow are ignored
		}else if ((keyCode != 37)&&(keyCode != 39)&&(keyCode != 38)&&(keyCode != 40)){ //37:left arrow, 39: right arrow are ignored
			importLookupXML(field);//when another key is pressed such as an alphanumeric character, import xml
		}
	}
}      


//http://www.severnsolutions.co.uk/twblog/archive/2003/09/14/keypressevents
function checkKeyPressed(field, evt, flag)//main function that is called when a key is pressed in text box, takes the appropriate action depending on the key pressed
{
	lookup_field = field;
	lookup_submit = flag;//initialize submit flag
	evt = (evt) ? evt : (window.event) ? event : null;
	if (evt)
	{
	    var charCode = (evt.charCode) ? evt.charCode :
	                   ((evt.keyCode) ? evt.keyCode :
	                   ((evt.which) ? evt.which : 0));
		
	    if (charCode == 40){ //down key pressed
			downAction();//move down
			
			if (highlight_index != -1 && lookup_symbol.length>0)//when a symbol is already highlighted
				lookup_field.value = lookup_symbol[highlight_index];//display that symbol
				
		}else if ((charCode == 38)&&(highlight_index != -1)){ //up key pressed
			upAction();//move up
			
			if (highlight_index != -1 && lookup_symbol.length>0)//when a symbol is already highlighted
				lookup_field.value = lookup_symbol[highlight_index];//display that symbol
				
		}
		//else if (charCode == 27){//escape key pressed
		//	boxClear();//clear box
		//	lookup_field.value = lookup_key;//text box value to key
		//}else if ((charCode != 37)&&(charCode != 39)){ //37:left arrow, 39: right arrow are ignored
		//	importLookupXML(field);//when another key is pressed such as an alphanumeric character, import xml
		//}
	}    
}

//Navigation Functions
function downAction()//when down key is pressed
{	
	if (highlight_index ==-1)//when no option is highlighted
		highlight(0);//highlight first option
	else if (highlight_index != lookup_name.length - 1){//for all other highlighted options except the last one
		unhighlight(highlight_index);//unhighlight them
		highlight(highlight_index + 1);//highlight the next option
	}
}

function upAction()//when up key is pressed
{
	if (highlight_index == 0){//when first option is already highlighted
		unhighlight(highlight_index);//unhighlight it
		highlight_index = -1;//reset highlight_index
	}else{
		unhighlight(highlight_index);//otherwise unhighlight last option
		highlight(highlight_index - 1);//highlight previous option
	}
}

function XMLnewRequest()
{	
	//Get an XMLHttpRequest object in a portable way and load it in xmlDoc gloabl variable
	lookup_xmlReq = false;
	// For Safari, Firefox, and other non-MS browsers
	if (window.XMLHttpRequest) {
	    try {
		    lookup_xmlReq = new XMLHttpRequest();
	    } catch (e) {
			lookup_xmlReq = false;
	    } 
	} else if (window.ActiveXObject) {
	    // For Internet Explorer on Windows
	    try {
			lookup_xmlReq = new ActiveXObject("Msxml2.XMLHTTP");
	    } catch (e) {
			try {
				lookup_xmlReq = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {
				lookup_xmlReq = false;
			}
	    }
	}

}

var counter = 0;
//XML main function
function importLookupXML(field)//import xml lookup file 
{	
	//lookup_field = field;//save the field object passed

	if (window.ActiveXObject) { //checking if browser is IE
		lookup_boxCorner.left = lookup_field.offsetLeft - lookup_ie_offset;//set left box corner location, account for possible IE offset for bobb/chart/display.php
	}
	else if (document.implementation && document.implementation.createDocument) { //for mozilla based browsers
		lookup_boxCorner.left = lookup_field.offsetLeft - lookup_ns_offset;//set left box corner location, account for possible NS/fiefox offset for bobb/chart/display.php
	}

	lookup_key = trimString(lookup_field.value.toString());//save the key entered by user
	
	if (lookup_key.length != 0){//when key length is greater than zero, use AJAX to call selectsymbol() when lookup.php is successully loaded
		
		var url = "/common/lookup.php?key="+escapeURL(lookup_key)
		
		if (lookup_xmlReq){// if there's a previous request, don't make another request
			lookup_xmlReq = false;
			//return;
		}
		XMLnewRequest();//get a new XMLHttpRequest object
		if(!lookup_xmlReq){	
			alert("Unable to stream data!");
			return;
		}
	
		// Asynchronous request, we put it out there but we
		// don't wait around for an answer
		lookup_xmlReq.onreadystatechange = function(){// state change function to detect news about request
			if (lookup_xmlReq.readyState == 4) {//a state of 4 means the entire response is ready to be used

				// Check for OK HTTP response code
				if (lookup_xmlReq.status != 200) {//200 is HTTP status code for success
					//alert("There was a communications error: " + lookup_xmlReq.responseText);
					return;
				}else{
					var data = lookup_xmlReq.responseXML;
					if(data){
						drawLookup(data);
					}else
						lookup_xmlReq = null;
				}
				lookup_xmlReq = null;
			}
		};

		lookup_xmlReq.open("POST", url, true);
		lookup_xmlReq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//expecting xml data to be returned from request
		lookup_xmlReq.send(null);//send request, no message is transmitted to web server in this case
	}	
	else
		boxClear();
}	

//Lookup Box related functions
function drawLookup(data)//process xml file and draw the lookup box
{
	boxClear();//clear any previously drawn  box
	highlight_index = -1;//reset highlight_index
	jg_lookup = new jsGraphics("lookupCanvas");//initialize the marker object
	
	var x = data.getElementsByTagName('hit');//find the xml node with tag name hit
	var htmltext;//store html text corresponding to each entry in lookup box

	lookup_symbol = [];//empty symbol array 
	lookup_name = [];//empty name array
	lookup_level = [];//empty name array
	
	for (i=0;i<x.length;i++)//for all hit nodes
	{
		lookup_symbol[i] = x[i].childNodes[0].firstChild.nodeValue;//get their symbol value (first child)
		lookup_name[i] = x[i].childNodes[1].firstChild.nodeValue;//get their name value (second child)
		lookup_level[i] = x[i].childNodes[2].firstChild.nodeValue;//get their level value (level child)
		
		if (i == lookup_max_search - 1)//when max search reached, stop retrieving data from xml file
			break;
	}
	
	//jg_lookup.setColor("#ffffff");//set color to white
	jg_lookup.setColor(lookup_box_color);//set color to grey for lookup box background
	jg_lookup.fillRect(lookup_boxCorner.left,lookup_boxCorner.top, lookup_box_pixel_width, lookup_name.length*lookup_char_height + 8);//fill rectangle for lookup box with selected color
	
	jg_lookup.setFont(lookup_font_type, lookup_font_size.toString()+"px");//set the font attributes
	jg_lookup.setColor(lookup_text_color);//set color to black for font
	
	for  (i=0;i<lookup_name.length;i++)//for all names
	{
		//set for each option the html, it is a hypertext with action to fill the corresponding symbol in text box when clicked, and when mouseover highlights the option and on mouseout event unhighlights it
		htmltext = "<div style=\"left:0px;width:280px;position:absolute;cursor:pointer\" id='hit" + i.toString() + "' onclick=\"javascript:fill('"+lookup_symbol[i]+"');\" onmouseover=\"highlight("+i.toString()+");\" onmouseout=\"unhighlight("+i.toString()+");\" >";
		
		//highlight in bold the matching characters with the key entered for the symbol and name
		//display the symbol and name in specified position to maintain uniform positioning with respect to each other
		//htmltext +="<div style=\"left:0px;position:relative\">"+ markKey(lookup_symbol[i], lookup_key) + " : " + markKey(lookup_name[i], lookup_key) +"</div>";
		
		htmltext +="<div style=\"left:0px;width:70px;position:absolute;\">"+ markKey(lookup_symbol[i], lookup_key) +" </div>";
		htmltext +="<div style=\"left:70px;width:165px;position:absolute;\"> " + markKey(lookup_name[i], lookup_key) +"</div>";
		htmltext +="<div style=\"margin-left:237px;width:35px;position:relative;\"> " + lookup_level[i] +"</div>";
		
		htmltext += "</div>";
		jg_lookup.drawString(htmltext, lookup_boxCorner.left + 11, lookup_boxCorner.top + 5 + i*lookup_char_height);//draw the html text as a single line option in the box
	}
	
	jg_lookup.setColor("#505050");//set color to black to draw the borders of the box
	jg_lookup.setStroke(1);//thickness of stroke
	
	jg_lookup.drawLine(lookup_boxCorner.left, lookup_boxCorner.top, lookup_boxCorner.left + lookup_box_pixel_width,lookup_boxCorner.top);//draw upper horizontal line
	
	jg_lookup.drawLine(lookup_boxCorner.left, lookup_boxCorner.top, lookup_boxCorner.left , lookup_boxCorner.top + lookup_name.length*lookup_char_height + 8);//draw left vertical line
	
	jg_lookup.drawLine(lookup_boxCorner.left + lookup_box_pixel_width, lookup_boxCorner.top, lookup_boxCorner.left  + lookup_box_pixel_width, lookup_boxCorner.top + lookup_name.length*lookup_char_height + 8);//draw right vertical line
	
	jg_lookup.drawLine(lookup_boxCorner.left, lookup_boxCorner.top + lookup_name.length*lookup_char_height + 8, lookup_boxCorner.left + lookup_box_pixel_width,lookup_boxCorner.top + lookup_name.length*lookup_char_height + 8);//draw lower horizontal line
	
	if ((lookup_name.length != 0) && (lookup_key.length != 0)){//when there is a key entry in box, display the lookup box
		hideSelects('hidden');//hide select menus for IE
		jg_lookup.paint();// display floating box
	}
}

function highlight(index)//highlight option corresponding to index
{
	unhighlight(highlight_index);//unhighlight last saved highlight_index
	highlight_index = index;//set new highlight_index to index
	tag = 'hit'+index.toString();//get tag of the option
	
	if (document.getElementById(tag))//lookup the element corresponding to that tag
		document.getElementById(tag).style.backgroundColor = lookup_highlight_color;//highlight it by setting the color to white
}

function unhighlight(index)//unhighlight option corresponding to index
{
	tag = 'hit'+index.toString();//get tag of the option
	if (document.getElementById(tag))//lookup the element corresponding to that tag
		document.getElementById(tag).style.backgroundColor  = lookup_box_color;//unhighlight it by setting the color to background box
}

function boxClear()//clear any lookup box
{
	if(jg_lookup) {
		jg_lookup.clear();//clear any lookup box
		hideSelects('visible');//show select menus for IE after clearing lookup box
	}
}	


function fill(symbol)//fill the symbol passed in the field text
{
	//document.form1.symbol.value = symbol;
	lookup_field.value = symbol;
	boxClear();//clear box when selection is made
	highlight_index = -1;//reset highlight_index
	//lookup_field.focus();//return focus to lookup field box
	if (lookup_submit == 1){ //when submit flag is set, then submit form on selection
		lookup_field.form.submit();//submit form
	}
}

//String processing functions
function markKey(myString, key)//mark the key string in the myString string passed
{	
	//key = trimString(key);
	var myStringProcessed = "";
	var myStringSplit = myString.split(" ");//split at spaces to different words and mark the key in each words
	
	if (key.indexOf(" ") == -1){//when there is no space in keyword, split name into single word sand compare to key
		for (var i = 0; i < myStringSplit.length; i++){
			myStringProcessed +=  markKeySingleWord(myStringSplit[i], key) + " ";//add the marked up html for each word and append in myStringProcessed after adding space character
		}
		
		myStringProcessed =  myStringProcessed.substring(0,myStringProcessed.length - 1);//remove last space character added
	}
	else//when keyword has a space within, compare without splitting 
		myStringProcessed = markKeySingleWord(myString, key);
	
	return myStringProcessed;//return marked up processed string
}

function markKeySingleWord(myString, key)//mark key string without splitting at spaces		
{	
	var key_start;
	var key_end;
	var myString_lower;
	var key_lower;
	
	//for uniform case insensitive comparison convert to lower case
	myString_lower = myString.toLowerCase();//convert to lower case the initial string
	key_lower = key.toLowerCase();//convert to liwer case the key string
	
	//only matches for beginning of word are marked up
	if(myString_lower.indexOf(key_lower) == 0){
		key_start = myString_lower.indexOf(key_lower);//get star index of key match
		key_end = key_start + key.length;//get the end index of key match
		myString = myString.substring(0,key_start) + "<b>" + myString.substring(key_start,key_end) + "</b>" + myString.substring(key_end,myString.length);//save the result in mystring after dividing it at key start and end and adding html tags for bold 
	}
	
	return myString;//return the marked up string
}

//function to trim leading and trailing spaces from a string
function trimString(str) {
	while (str.charAt(0) == ' ')//remove leading spaces
		str = str.substring(1);
	while (str.charAt(str.length - 1) == ' ')//remove trailing spaces
		str = str.substring(0, str.length - 1);
	return str;
}

//replace key characters that are illegal URL characters with their URL valid ones
function escapeURL(str)
{
	var escapeStr = str;
	escapeStr = escapeStr.replace('%','%25');//first time replace so that the escape characters below are not affected
	escapeStr = escapeStr.replace(' ','%20');
	escapeStr = escapeStr.replace('<','%3C');
	escapeStr = escapeStr.replace('>','%3E');
	escapeStr = escapeStr.replace('#','%23');
	escapeStr = escapeStr.replace('{','%7B');
	escapeStr = escapeStr.replace('}','%7D');
	escapeStr = escapeStr.replace('|','%7C');
	escapeStr = escapeStr.replace('\\','%5C');
	escapeStr = escapeStr.replace('^','%5E');
	escapeStr = escapeStr.replace('~','%7E');
	escapeStr = escapeStr.replace('[','%5B');
	escapeStr = escapeStr.replace(']','%5D');
	escapeStr = escapeStr.replace("'",'%60');
	escapeStr = escapeStr.replace(';','%3B');
	escapeStr = escapeStr.replace('/','%2F');
	escapeStr = escapeStr.replace('?','%3F');
	escapeStr = escapeStr.replace(':','%3A');
	escapeStr = escapeStr.replace('@','%40');
	escapeStr = escapeStr.replace('=','%3D');
	escapeStr = escapeStr.replace('&','%26');
	escapeStr = escapeStr.replace('$','%24');

	return escapeStr;
}

//http://www.shawnolson.net/a/1198/hide-select-menus-javascript.html
//By Shawn Olson
/*
Sometimes it is beneficial to hide select menus with JavaScript, especially on Internet Explorer. There may be times to do it in other browsers, but it is necessary to hide select menus on Internet Explorer in particular because select menus hover above all other objects in a window on Internet Explorer--which plays havoc with drop-down menus that drop-down underneath selects instead of over them. 

The hideSelects() function will hide all selects on a page (in all forms on the page) when 'hidden' is passed; conversely, it will display all select menus when 'visible' is passed into the function.
*/
function hideSelects(action) { 
	//documentation for this script at http://www.shawnolson.net/a/1198/hide-select-menus-javascript.html
	//possible values for action are 'hidden' and 'visible'
	if (action!='visible'){action='hidden';}
	//if (navigator.appName.indexOf("MSIE")) {
	if (window.ActiveXObject) { // for IE browsers only
		for (var S = 0; S < document.forms.length; S++){//for all forms
			for (var R = 0; R < document.forms[S].length; R++) {//for all fields in a form
				if (document.forms[S].elements[R].options) {//if it is a select menu
					document.forms[S].elements[R].style.visibility = action;//hide or show that select menu based on action passed
				}
			}
		} 
	}
}

document.documentElement.onclick = boxClear;
//end code 
