/* **************************************************************************************
 * JavaSrcipt Page for the Search.aspx
 * Version 1.0
 * Date 10/20/2006
 * .NET Framework 1.1
 *
 * Author: Stephen C. Baker
 *
 * Written for the Handel and Haydn Society as part of their On-Line Archival Database System.
 * This page contains the AJAX Javascript functions that call the .NET AjaxMethods class
 *
 * Revision No.     Date       Reason
 * ------------     --------   --------------------------------------------------------------
 *
 ****************************************************************************************** */

var newWindow = null;  //used for the popup print and help windows
var progressBar = null;  //var for progress bar - not used (so far)
var DataListConcertID = 0; //ID for the Session Holding the DataList
var MyWin = null;
var offImageArray = new Array();  //An array to hold the images for the 'onmouseout' events
var onImageArray = new Array();   //An array to hold the images for the 'onmouseover' events
var redirectToOld;  //Holds the value from determinIfRedirect for possible redirection
var OldSearchPage = "http://webgraphics.web108.discountasp.net/HandH/SearchOld.aspx";
var SorryPage = "http://webgraphics.web108.discountasp.net/HandH/Sorry.htm";
var locationDrops = new Array("drpStreet","drpCity","drpState","drpCountry");
var totalNumberOfRetries = 1;
var imageLib = new Array();
var ComposerArray = new Array();

function LoadThePageDefaults()
{

	if(redirectToOld == "do_dice")
	{
		location.href = SorryPage;
		document.loaction.href = SorryPage;
	}
	else if(redirectToOld == "true")
	{
		location.href = OldSearchPage;
		document.loaction.href = OldSearchPage;
	}

	//if(window.addEventListener)
	//	window.addEventListener("load",dhx_init_tabbars,false);
	//else if(window.attachEvent)
	//	window.attachEvent("onload",dhx_init_tabbars);

	//Get the verdict on the browser compatibility test
	//redirectToOld = determinIfRedirect();

	enableTooltips('Content');

	//Test for browser compatibility with the Ajax Search Page
	//If Browser is old, sends user to the Old Search Page
	//If the Browser is not suited for either, redirects the user to the Sorry.htm page.
	//Otherwise the user is directed the the Ajax Search Page.


	//If the browser supports document.image then pre-load all the button images for rollover
	if(document.images)
	{
		offImageArray["clear"] = new Image(150,50);
		offImageArray["popup"] = new Image(150,50);
		offImageArray["search"] = new Image(150,50);
		offImageArray["list"] = new Image(150,50);
		offImageArray["clear"].src = "images/ClearForm535287Button.gif";
		offImageArray["search"].src = "images/Search535287Button.gif";
		offImageArray["popup"].src = "images/PopUp535287Button.gif";
		offImageArray["list"].src = "images/ClearListboxes535287Butto.gif";

		onImageArray["clear"] = new Image(150,50);
		onImageArray["popup"] = new Image(150,50);
		onImageArray["search"] = new Image(150,50);
		onImageArray["list"] = new Image(150,50);
		onImageArray["clear"].src = "images/ClearFormMO535287Button.gif";
		onImageArray["search"].src = "images/SearchMO535287Button.gif";
		onImageArray["popup"].src = "images/PopUpMO535287Button.gif";
		onImageArray["list"].src = "images/ClearListboxesMO535287Butto.gif";
	}

	loadComposers();	//AJAX: loads the Composer dropdown list box
	loadPerformers();	//AJAX: loads the Performers dropdown listbox
	loadDirectors();	//AJAX: loads the Director dropdown listbox
	loadConcertHallsUsedInConcerts();

	document.Form1.hDateFunction.value = 1;
	document.Form1.hDateRange.value = 5;
	document.Form1.hCompositionArg.value = "Both";
	EndableDisableEndDates(document.Form1.hDateFunction.value);

	//AJAX: Loads the Concert Dates Dropdown listbox with the dates corresponding the
	//to 50 year date range seleced by the Date Range radio button
	loadDates(document.Form1.hDateRange.value);
	//Sets the Composer Name text box its previous value or to an empty string if never used
	setTextBox(document.Form1.hComposerName,document.Form1.txtComposerName);
	//Sets the Composition Name text box its previous value or to an empty string if never used
	setTextBox(document.Form1.hComposition,document.Form1.txtCompositionName);

	if(popupblocked == null)
	{
		warn = document.getElementById("PopUpWarning");
		warn.innerHTML = "<h5>You are using a Popup Blocker on your browser. Some features of this site may not function correctly.<br>Popups are used for the Help Pages and the Performer's Biographies <u>only</u>.</h5>";
	}
}

//Function to determin which redirect word to return.  So far...
//Netscape 4.x = 'no_dice' = go to Sorry.html
//Netscape to 7.01 = 'true' = go to old Search Page
//Netscape 7.2+, Firefox1.5+ and IE 5.5+ = 'false' = do not redirect
function determinIfRedirect()
{
	var appName = navigator.appName; //get browser name
	var appVersion = navigator.appVersion; //get browser version
	var userAgent = navigator.userAgent; //get browser user agent

	//if IE return 'true' (for now - needs work)
	if(appName.indexOf("Microsoft Internet Explorer") != -1)
		return "false";

	//If we are a Netscape browser
	if(appName.indexOf("Netscape") != -1)
	{
		var verNum = parseInt(appVersion); //get the version number.

		//if the version number is under 5, then it is 4.7 or 4.8, no dice
		if(verNum < 5)
			return "do_dice";
		else
			return "true";			
	}
	return "false";  //Got to here, go to New Browser
}

//Set the Textbox control to either an empty string or to the value in hField
function setTextBox(hField,txtBox)
{
	if(hField.value == undefined)  //if undefined set to empty string
		hField.value = "";
	txtBox.value = hField.value;
}

//Sets the Dropdown list box to zero of the value for the index is
//undefined, zero or the index value has no length (empty string).
//Otherwise sets the value of the index to the value contained in hField.
function setDropdown(hField,drp)
{
	if((hField.value == undefined) || (hField.value.length == 0) || (hField.value == 0))
	{
		hField.value = 0;
		drp.selectedIndex = 0;
	}
	else
	{
		drp.selectedIndex = getSelectedIndex(drp,hField.value);
	}
}

//Changes the value of what's in 'ele' to 'value'.
//Used to set the value of the hidden fields
function changehHiddenField(ele,val)
{
	ele.value = val;
}

//Returns the index of a Dropdown listbox collection to the idex corresponding
//to the value member that matches the argument 'val'
function getSelectedIndex(drp,val)
{
	var retVal = 0;  //default value id no match is found

	//iterate through all the Dropdown listbox members
	//until one of its value list item members matches the value in 'val'
	if(drp.tagName != "SELECT")
		LogActivity(drp.tagName,"Search.sapx");

	for(var i = 0; i < drp.length; i++)
	{
		if(drp[i].value == val)
		{
			retVal = i;  //match found, return index
			break;
		}
	}
	return retVal;
}

//Sets the value of the hidden text field, hUsedDate to the value of 'val'
function changeUsedDate(val)
{
	LogActivity("Change Used Date","Search.aspx");
	getTabber();
	document.Form1.hUsedDate.value = val;
}

//Clears the Composition listbox
function clearCompListbox()
{
	document.Form1.CompositionsSelect.selectedIndex = -1;
	document.Form1.hCompositionIds.value = "";
}

//A function to enable or disable the three 'After' date dropdown listboxs
//for day, month and year.  Sets the value from the hidden text field, hDateFunction.
//If set to 1 to 3 then set the indexes to 0 and disable otherwise enable
function EndableDisableEndDates(sel)
{
	document.Form1.hDateFunction.value = sel;

	if((sel >= 0) && (sel < 4))
	{
		document.Form1.hSelectAfterYear.value = 0;
		document.Form1.hSelectAfterMonth.value = 0;
		document.Form1.hSelectAfterDay.value = 0;
		document.Form1.SelectAfterDay.selectedIndex = 0;
		document.Form1.SelectAfterMonth.selectedIndex = 0;
		document.Form1.SelectAfterYear.selectedIndex = 0;
		document.Form1.SelectAfterYear.disabled = true;
		document.Form1.SelectAfterMonth.disabled = true;
		document.Form1.SelectAfterDay.disabled = true;

	}
	if(sel == 4)
	{
		document.Form1.SelectAfterYear.disabled = false;
		document.Form1.SelectAfterMonth.disabled = false;
		document.Form1.SelectAfterDay.disabled = false;
	}
}

//Get the value of the Composition Arguments which can be both excerpts and full pieces, only full
//pieces or excerpts only.  If these is a selected composer then the vlaues in the Composition
//Listbox will be set by that composer and the argument in CompositionArg.
function getCompByArgs()
{
	//Get radio button balue 'both', 'excerpts only, or 'no excerpts'
	document.Form1.hCompositionArg.value = getRadiocheckedValue(document.Form1.CompositionArg);

	//If a composer is selected, get all performed compositions by that composer.
	if(document.Form1.ComposerDropdown.selectedIndex != 0)
	{
		clearCompListbox()
		getCompByComposer(document.Form1.ComposerDropdown.options[document.Form1.ComposerDropdown.selectedIndex].value);
	}
}

//Get the 'value' property from the CompositionsSelect Multiple Select Listbox
//Creates a space delimited list of the IDs and stores these values in the hidden
//hCompositionIds textbox.
function getCompositionIds()
{

	var lstBox = document.Form1.CompositionsSelect;
	document.Form1.hCompositionIds.value = "";

	for(var i = 0; i < lstBox.length; i++)
	{
		if(lstBox[i].selected)
			document.Form1.hCompositionIds.value += lstBox[i].value + " ";
	}
}
function buildPerformerDetailWindow(value)
{
	LogActivity("Performer Details","Search.sapx");
	AjaxNamespace.AjaxMethods.PerformerDetails(value,callback_buildPerformerDetailWindow);
}

function callback_buildPerformerDetailWindow(res)
{
	var html = [];  //create an an empty object array


	//If we have a result, proceed
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var compArray = new Array(res.value.Tables[0].Rows.length);
		var composerArray = new Array(res.value.Tables[0].Rows.length);
		var PerformerName;

		html[html.length] = "<html><head><style type='text/css'> ";
		html[html.length] = "body {font-family: arial} ";
		html[html.length] = "img {border : solid; margin-left: 40px; margin-top: 20px; border-width: 4px; ";
		html[html.length] = "border-right-color: #849635; border-bottom-color: #849635; border-left-color: #535287; border-top-color: #535287; } ";
		html[html.length] = "h3 {text-align: center} ";
		html[html.length] = "p:first-letter {color: #849635; font-size:xx-large}"
		html[html.length] = "p {text-indent: 20px; font-family: arial}";
		html[html.length] = "</style></head><body>";
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
			if(i == 0)
			{
				if(popupblocked == null)
					html[html.length] = "<img src='../../images/performerImages/" + res.value.Tables[0].Rows[i].ImageName + "'>";
				else
					html[html.length] = "<img src='images/performerImages/" + res.value.Tables[0].Rows[i].ImageName + "'>";

				PerformerName = makeName(res,i,"performer")

				html[html.length] = "<h3>" + PerformerName + "</h3>";

				var bio = res.value.Tables[0].Rows[i].Biography
				bio = bio.replace(/\’/g, "&acute;");
				bio = bio.replace(/\'/g, "&acute;");
				bio = bio.replace(/\n/g, "<p></p>");

				html[html.length] = "<p>" + bio + "</p>";
				html[html.length] = PerformerName + " has performed for the Handel and Haydn Society in...<br><ul>";
			}
			compArray[i] = searchArray(compArray,res.value.Tables[0].Rows[i].CompName);
			if(compArray[i].length > 0)
				composerArray[i] = makeName(res,i,"composer");

		}

		for(k = 0; k < compArray.length; k++)
		{
			if(compArray[k].length > 0)
			{
				html[html.length] = "<li>\"" + compArray[k] + "\" by " +  composerArray[k]  + "</li>";
			}
		}
		if(popupblocked == null)
			html[html.length] = "<br><br><a href='../../Search.aspx'>Back to Search Page</a><br>";
		html[html.length] = "</ul></body></html>";
	}
	if(popupblocked == null)
	{
		LogActivity("Performer Details Seperate Window","Search.sapx");
		var PerformerFile = AjaxNamespace.AjaxMethods.WritePerformerFile(html.join(""),PerformerName);
		window.location = PerformerFile.value;
	}
	else
	{
		MyWin = window.open("","","width=700,hight=900,resizable=yes,location=no,status=no,menubar=no,scrollbars=yes");
		MyWin.document.write(html.join(""));
		MyWin.document.close();
		MyWin.focus();
	}
}

function buildPerformerDetailWindowShort(value)
{
	LogActivity("Performer Details Activated","Search.sapx");
	AjaxNamespace.AjaxMethods.PerformerDetails(value,callback_buildPerformerDetailWindowShort);
}

function callback_buildPerformerDetailWindowShort(res)
{
	var html = [];  //create an an empty object array


	//If we have a result, proceed
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var compArray = new Array(res.value.Tables[0].Rows.length);
		var composerArray = new Array(res.value.Tables[0].Rows.length);

		html[html.length] = "<html><head><style type='text/css'> ";
		html[html.length] = "body {font-family: arial} ";
		html[html.length] = "img {border : solid; margin-left: 40px; margin-top: 20px; border-width: 4px; ";
		html[html.length] = "border-right-color: #849635; border-bottom-color: #849635; border-left-color: #535287; border-top-color: #535287; } ";
		html[html.length] = "h3 {text-align: center} ";
		html[html.length] = "p {text-indent: 20px} ";
		html[html.length] = "</style></head><body>";
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
			if(i == 0)
			{
				html[html.length] = "<h3>" + makeName(res,i,"performer") + "</h3>";
				html[html.length] = "Has Performed for the Handel and Haydn Society in...<br><ul>";
			}
			compArray[i] = searchArray(compArray,res.value.Tables[0].Rows[i].CompName);
			if(compArray[i].length > 0)
				composerArray[i] = makeName(res,i,"composer");
		}

		for(k = 0; k < compArray.length; k++)
		{
			if(compArray[k].length > 0)
			{
				html[html.length] = "<li>\"" + compArray[k] + "\" by " +  composerArray[k]  + "</li>";
			}
		}
		html[html.length] = "</ul></body></html>";
	}
	MyWin = window.open("","","width=700,hight=900,resizable=yes,location=no,status=no,menubar=no,scrollbars=yes");
	MyWin.document.write(html.join(""));
	MyWin.document.close();
	MyWin.focus();

}

function searchArray(theArray,theValue)
{
	for(var i = 0; i < theArray.length; i++)
	{
		if(theArray[i] == theValue)
			return "";
	}
	return theValue;
}

function makeName(res,i,nameType)
{
	var displayName;

	if(nameType == "performer")
	{
		displayName = res.value.Tables[0].Rows[i].Title;
		if(res.value.Tables[0].Rows[i].FName != null)
			displayName += " " + res.value.Tables[0].Rows[i].FName;
		if(res.value.Tables[0].Rows[i].MName != null)
			displayName += " " + res.value.Tables[0].Rows[i].MName;
		displayName += " " + res.value.Tables[0].Rows[i].LName;
	}
	else
	{
		displayName = "";
		if(res.value.Tables[0].Rows[i].ComposerFirstName != null)
			displayName += " " + res.value.Tables[0].Rows[i].ComposerFirstName;
		if(res.value.Tables[0].Rows[i].ComposerMiddleName != null)
			displayName += " " + res.value.Tables[0].Rows[i].ComposerMiddleName;
		displayName += " " + res.value.Tables[0].Rows[i].ComposerLastName;
	}

	return displayName;
}

function buildPerformanceList(res)
{

}
function buildPrinterFriendlyHelp()
{
	LogActivity("Printer Friendly Results","Search.aspx");
	var theTable = document.getElementById("dlConcert");
	var newWinContent = "<html><head><link type=\"text/css\" media=\"print\" rel=\"stylesheet\" href=\"css\HandHOLDB.css\"></head><body><br><table>";
	newWinContent += theTable.innerHTML;
	newWinContent += "</table></body></html>";

	MyWin = window.open("","","width=700,hight=900,resizable=yes,location=no,status=yes,menubar=yes,scrollbars=yes");
	MyWin.document.write(newWinContent);
	MyWin.document.close();
	MyWin.focus();

}

/* ***************************** Rollover Functions ********************** */
//Sets the images button's src property to the image contained
//in the onImageArray value.  Called by javascript on aspx page
function imageOn(ele,imgName)
{
	if(document.images)
	{
		ele.src = onImageArray[imgName].src;
	}
}
//Sets the images button's src property to the image contained
//in the offImageArray value.  Called by javascript on aspx page
function imageOff(ele,imgName)
{
	if(document.images)
	{
		ele.src = offImageArray[imgName].src;
	}
}

/* *************************** AJAX Section ******************************* */
/* ************************************************************************
*  This section contains all the .NET AJAX Asychronous methods.
*  Each of these makes a call to the .NET Ajax methods in the AjaxNamespace
*  class, AjaxMethods.  They call a callback method to create and initialize
*  the HTML controls with the results of the .NET calls.
* ************************************************************************ */
/* *********************************************************************** */

//AJAX: Async: Sets the values of the list items in the Date Range Dropdown
//listbox. Selects the 50 year range according to the Radio Button value
//that's in 'value'.  Calls Asynchrounous .NET AJAX method, LoadDates() and
//JavaScript Ajax method, callback_LoadDates()
function loadDates(value)
{
	if(document.Form1.hDateRange.value != value)
	{
		document.Form1.hDateRange.value = value;
		document.Form1.hUsedDate.value = 0;
	}
	AjaxNamespace.AjaxMethods.LoadDates(value,callback_LoadDates);
}
//AJAX: Async: Takes the result of the AJAX: .NET method, LoadDates() and constructs the
//HTML options for the Date Range Dropdown listbox. Does this by iterating through the .NET
//DataSet's DataTable and extracting the DataRow's DataColumn value.
function callback_LoadDates(res)
{
	if(res.value.Tables[0].Rows.length == 0)
	{
		LogError("Unable to load Dates","Search/AJAX");
		alert("Unable to load Dates. Please try re-loading the page.");	
	}
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var html = [];  //create an an empty object array

		html[html.length] = "<option value='0'>none</option>"; //first array indexies becomes the first option

		//extract each DataSets DataColumn 'Value Date' and 'textDate' value and use these
		//as the list item's value and text field
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
			html[html.length] = "<option value='" + res.value.Tables[0].Rows[i].ValueDate + "'>" + res.value.Tables[0].Rows[i].txtDate + "</option>";

		//Append the html array to the 'DateDropdownDiv' after creating the Dropdown listbox control
		document.getElementById("DateDropdownDiv").innerHTML = "<select id='DateDropdown' class='DropDownWidth200' onchange='changeUsedDate(this.value)'>" + html.join("") + "</select>";

		//Set the Dropdown listbox index to the value in hUsedDate
		setDropdown(document.Form1.hUsedDate,document.Form1.DateDropdown);
	}
}

//AJAX: Async: Sets the values of the list items in the Composer Dropdown
//listbox. Calls Asynchrounous .NET AJAX method, LoadComposers() and
//JavaScript Ajax method, callback_LoadComposers()
function loadComposers()
{
	//alert("Inside loadComposers");
	AjaxNamespace.AjaxMethods.LoadComposers(callback_LoadComposers);
}
//AJAX: Async: Takes the result of the AJAX: .NET method, LoadComposers() and constructs the
//HTML options for the Composer Dropdown listbox. Does this by iterating through the .NET
//DataSet's DataTable and extracting the DataRow's DataColumn value.
function callback_LoadComposers(res)
{
	if(res.value.Tables[0].Rows.length == 0)
	{
		LogError("Unable to load Composers","Search/AJAX");
		alert("Unable to load Composers. Please try re-loading the page.");	
	}
	//If we have a result, proceed
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var html = [];  //create an an empty object array

		html[html.length] = "<option value='0' selected>none</option>";	//first array indexies becomes the first option

		//extract each DataSets DataColumn 'PersonID' and 'Name' value and use these
		//as the list item's value and text field
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
			html[html.length] = "<option value='" + res.value.Tables[0].Rows[i].PersonID + "'>" + res.value.Tables[0].Rows[i].Name + "</option>";
		}

		var innerHtml = "<input type='text' id='txtComposer' name='txtComposer' class='TextBoxWidth250' " +
		"onkeyup='autoComplete(this,this.form.ComposerDropdown,\"text\",true,true)'> " +
		"<br><select id='ComposerDropdown' class='DropDownWidth250' " +
		"onchange='this.form.txtComposer.value=this.options[this.selectedIndex].text;getCompByComposer(this.value);'>" + html.join("") + "</select>";

		//Append the html array to the 'ComposerListDiv' after creating the Dropdown listbox control
		document.getElementById("ComposerListDiv").innerHTML = innerHtml;

		//Set the Dropdown listbox index to the value in hComposerId
		setDropdown(document.Form1.hComposerId,document.Form1.ComposerDropdown);
	}
}

//AJAX: Async: Sets the values of the list items in the Performer Dropdown
//listbox. Calls Asynchrounous .NET AJAX method, LoadPerformers() and
//JavaScript Ajax method, callback_LoadPerformers()
function loadPerformers()
{
	AjaxNamespace.AjaxMethods.LoadPerformers(callback_LoadPerformers);
}
//AJAX: Async: Takes the result of the AJAX: .NET method, LoadPerformers() and constructs the
//HTML options for the Performers Dropdown listbox. Does this by iterating through the .NET
//DataSet's DataTable and extracting the DataRow's DataColumn value.
function callback_LoadPerformers(res)
{
	if(res.value.Tables[0].Rows.length == 0)
	{
		LogError("Unable to load Performers","Search/AJAX");
		alert("Unable to load Performers. Please try re-loading the page.");	
	}
	//If we have a result, proceed
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var html = [];	  //create an an empty object array

		html[html.length] = "<option value='0' selected>none</option>";	//first array indexies becomes the first option

		//extract each DataSets DataColumn 'PersonID' and 'Name' value and use these
		//as the list item's value and text field
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
			html[html.length] = "<option value='" + res.value.Tables[0].Rows[i].PersonID + "'>" + res.value.Tables[0].Rows[i].Name + "</option>";
		}

		var innerHtml = "<input type='text' id='txtPerformer' name='txtPerformer' class='TextBoxWidth200' onkeyup=\"autoComplete(this,this.form.PerformerDropdown,'text',true,false,'PerformerDropdown')\"><br>" +
		"<select id='PerformerDropdown' class='DropDownWidth200' onchange=\"this.form.txtPerformer.value=this.options[this.selectedIndex].text;ChangeDropdownHidden('PerformerDropdown')\">" + html.join("") + "</select>";

		//Append the html array to the 'PerformerListDiv' after creating the Dropdown listbox control
		document.getElementById("PerformerListDiv").innerHTML = innerHtml;

		//Set the Dropdown listbox index to the value in hPerformerDropdown
		setDropdown(document.Form1.hPerformerDropdown,document.Form1.PerformerDropdown);
	}
}

//AJAX: Async: Sets the values of the list items in the Director Dropdown
//listbox. Calls Asynchrounous .NET AJAX method, LoadDirectors() and
//JavaScript Ajax method, callback_LoadDirectors()
function loadDirectors()
{
	//alert("Inside loadDirectors()");
	AjaxNamespace.AjaxMethods.LoadDirectors(callback_LoadDirectors);
}
//AJAX: Async: Takes the result of the AJAX: .NET method, LoadDirectors() and constructs the
//HTML options for the Directors Dropdown listbox. Does this by iterating through the .NET
//DataSet's DataTable and extracting the DataRow's DataColumn value.
function callback_LoadDirectors(res)
{
	if(res.value.Tables[0].Rows.length == 0)
	{
		LogError("Unable to load Directors","Search/AJAX");
		alert("Unable to load Directors. Please try re-loading the page.");	
	}
	//If we have a result, proceed
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var html = [];	//create an an empty object array

		html[html.length] = "<option value='0' selected>none</option>";	//first array indexies becomes the first option

		//extract each DataSets DataColumn 'PersonID' and 'Name' value and use these
		//as the list item's value and text field
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
			html[html.length] = "<option value='" + res.value.Tables[0].Rows[i].PersonID + "'>" + res.value.Tables[0].Rows[i].Name + "</option>";
		}
		var innerHtml = "<input type='text' id='txtDirector' name='txtDirector' class='TextBoxWidth200' onkeyup=\"autoComplete(this,this.form.DirectorDropdown,'text',true,false,'DirectorDropdown')\"><br>" +
		"<select id='DirectorDropdown' class='DropDownWidth200' onchange=\"this.form.txtDirector.value=this.options[this.selectedIndex].text;ChangeDropdownHidden('DirectorDropdown')\">" + html.join("") + "</select>";
		//Append the html array to the 'DirectorListDiv' after creating the Dropdown listbox control
		document.getElementById("DirectorListDiv").innerHTML = innerHtml;

		//Set the Dropdown listbox index to the value in hDirectorDropdown
		setDropdown(document.Form1.hDirectorDropdown,document.Form1.DirectorDropdown);
	}
}

//AJAX: Async: Sets the values of the list items in the Concert Hall Dropdown
//listbox. Calls Asynchrounous .NET AJAX method, LoadConcertHalls() and
//JavaScript Ajax method, callback_LoadConcertHalls()
function loadConcertHalls()
{
	AjaxNamespace.AjaxMethods.LoadConcertHalls(callback_LoadConcertHalls);
}
//AJAX: Async: Takes the result of the AJAX: .NET method, LoadConcertHalls() and constructs the
//HTML options for the Concert Hall Dropdown listbox. Does this by iterating through the .NET
//DataSet's DataTable and extracting the DataRow's DataColumn value.
function callback_LoadConcertHalls(res)
{
	if(res.value.Tables[0].Rows.length == 0)
	{
		LogError("Unable to load Concert Halls","Search/AJAX");
		alert("Unable to load Concert Halls. Please try re-loading the page.");	
	}
	//If we have a result, proceed
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var html = [];	//create an an empty object array

		html[html.length] = "<option value='0' selected>none</option>";	//first array indexies becomes the first option

		//extract each DataSets DataColumn 'ConcertHallID' and 'HallName' value
		//and use these as the list item's value and text field
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
			html[html.length] = "<option value='" + res.value.Tables[0].Rows[i].ConcertHallID + "'>" + res.value.Tables[0].Rows[i].HallName + "</option>";
		}

		var innerHtml = "<input type='text' id='txtConcertHall' name='txtConcertHall' class='TextBoxWidth200' onkeyup=\"autoComplete(this,this.form.ConcertHallDropdown,'text',true,false,'ConcertHallDropdown')\"><br>" +
		"<select id='ConcertHallDropdown' class='DropDownWidth200' onchange=\"this.form.txtConcertHall.value=this.options[this.selectedIndex].text;ChangeDropdownHidden('ConcertHallDropdown')\">" + html.join("") + "</select>";

		//Append the html array to the 'ConcertHallListDiv' after creating the Dropdown listbox control
		document.getElementById("ConcertHallListDiv").innerHTML = innerHtml;

		//Set the Dropdown listbox index to the value in hConcertHallDropdown
		setDropdown(document.Form1.hConcertHallDropdown,document.Form1.ConcertHallDropdown);
	}
}

//AJAX: Async: Sets the values of the list items in the Concert Hall Dropdown
//listbox. Calls Asynchrounous .NET AJAX method, LoadConcertHalls() and
//JavaScript Ajax method, callback_LoadConcertHalls()
function loadConcertHallsUsedInConcerts()
{
	AjaxNamespace.AjaxMethods.LoadHallNamesUsedInConcerts(callback_LoadHallNamesUsedInConcerts);
}
//AJAX: Async: Takes the result of the AJAX: .NET method, LoadConcertHalls() and constructs the
//HTML options for the Concert Hall Dropdown listbox. Does this by iterating through the .NET
//DataSet's DataTable and extracting the DataRow's DataColumn value.
function callback_LoadHallNamesUsedInConcerts(res)
{
	if(res.value.Tables[0].Rows.length == 0)
	{
		LogError("Unable to load Concert Halls used in Concerts","Search/AJAX");
		alert("Unable to load Concert Halls. Please try re-loading the page.");	
	}
	//If we have a result, proceed
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var html = [];	//create an an empty object array

		html[html.length] = "<option value='0' selected>none</option>";	//first array indexies becomes the first option

		//extract each DataSets DataColumn 'ConcertHallID' and 'HallName' value
		//and use these as the list item's value and text field
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
			html[html.length] = "<option value='" + res.value.Tables[0].Rows[i].ConcertHallID + "'>" + res.value.Tables[0].Rows[i].HallName + "</option>";
		}

		var innerHtml = "<input type='text' id='txtConcertHall' name='txtConcertHall' class='TextBoxWidth200' onkeyup=\"autoComplete(this,this.form.ConcertHallDropdown,'text',true,false,'ConcertHallDropdown')\"><br>" +
		"<select id='ConcertHallDropdown' class='DropDownWidth200' onchange=\"this.form.txtConcertHall.value=this.options[this.selectedIndex].text;ChangeDropdownHidden('ConcertHallDropdown')\">" + html.join("") + "</select>";

		//Append the html array to the 'ConcertHallListDiv' after creating the Dropdown listbox control
		document.getElementById("ConcertHallListDiv").innerHTML = innerHtml;

		//Set the Dropdown listbox index to the value in hConcertHallDropdown
		setDropdown(document.Form1.hConcertHallDropdown,document.Form1.ConcertHallDropdown);
	}
}

//AJAX: Async: Sets the values of the list items in the Composition Listbox which
//is determined by the Composer_ID in hComposerId. Also gets the type of compositions as determined
//by the argument in CompositionArg ('both','no excerpts, excerpts only').
//Calls Asynchrounous .NET AJAX method, GetCompositionsByComposerForSearch() and
//JavaScript Ajax method, callback_GetCompositionsByComposerForSearch()
function getCompByComposer(value)
{
	clearCompListbox();
	LogActivity("Composer Select","Search.aspx");
	document.Form1.hComposerId.value = value;  //get the Composer ID
	var Arg =  getRadiocheckedValue(document.Form1.CompositionArg);	//get composition type
	AjaxNamespace.AjaxMethods.GetCompositionsByComposerForSearch(value,Arg,callback_GetCompositionsByComposerForSearch);
}
//AJAX: Async: Takes the result of the AJAX: .NET method, GetCompositionsByComposerForSearch()
//and constructs the HTML options for the CompositionsSelect Listbox. Does this by iterating
//through the .NET DataSet's DataTable and extracting the DataRow's DataColumn value.
//Since this is a multiple select listbox the function also iterates through all the values
//in hCompositionIds, setting any listbox listitems to true that have been previously selected
function callback_GetCompositionsByComposerForSearch(res)
{
	if(res.value.Tables[0].Rows.length == 0)
	{
		LogError("Unable to Get Compositions By Composer For Search","Search/AJAX");
		alert("Unable to Get Compositions By Composer For Search. Please try re-loading the page.");	
	}

	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		var html = [];	//create an an empty object array

		//extract each DataSets DataColumn 'CompID' and 'CompName' value
		//and use these as the list item's value and text field
		for(var i=0; i<res.value.Tables[0].Rows.length; i++)
		{
		    var CompStuff = res.value.Tables[0].Rows[i].CompName;

		    if(res.value.Tables[0].Rows[i].CompKey != null)
				CompStuff += ", in the key of " + res.value.Tables[0].Rows[i].CompKey;

		    if(res.value.Tables[0].Rows[i].CompOpus != null)
				CompStuff += ", " + res.value.Tables[0].Rows[i].CompOpus;

		    if(res.value.Tables[0].Rows[i].CompNName != null)
				CompStuff += " \"" + res.value.Tables[0].Rows[i].CompNName + "\"";

			html[html.length] = "<option value='" + res.value.Tables[0].Rows[i].CompID + "'>" + CompStuff + "</option>";
		}


		//Append the html array to the 'CompositionsDiv' after creating the Multiple Select Lstbox control
		document.getElementById("CompositionsDiv").innerHTML = "<select id='CompositionsSelect' class='putbehind' multiple size='6' onchange='getCompositionIds()'>" + html.join("") + "</select>";

		//Set the Multiple Select Lstbox indexes to the value in hCompositionIds
		if(document.Form1.hCompositionIds.value.length > 0)
		{
			var lstBox = document.Form1.CompositionsSelect;	//get the Listbox Control
			var anId = document.Form1.hCompositionIds.value.split(" "); //split the IDs from hCompositionIds

			//Check every ID agains the Composition ID in the Listbox.
			//If there are any matches, set that listitem's select property to true
			for(var i = 0; i < anId.length; i++)
			{
				for(var k = 0; k < lstBox.length; k++)
				{
					if(anId[i] == lstBox[k].value)
						lstBox[k].selected = true;
				}
			}
		}
	}
}

//Returns the value of a checked radio button. It iterates through all
//the listitems and returns the index if the one that is checked
function getRadiocheckedValue(ele)
{
	for(var i = 0; i < ele.length; i++)
	{
		if(ele[i].checked)
			break;
	}
	return ele[i].value;
}

//Returns the index of a radio button listbox based on the value
//of the checked item.  It iterates through all
//the listitems and returns the index if the one of the
//listitem's value property matches the function's 'val' value
function getRadioValueChecked(rad,val)
{
	for(var i = 0; i < rad.length; i++)
	{
		if(rad[i].value == val)
		{
			rad[i].checked = true;
			break;
		}
	}
}

/* ************************************************************************* */
/* ********************** Initializing Functions *************************** */
/* ************************************************************************* */

function LogActivity(msg,page)
{
	//alert("Log" + msg + " " + page);
	AjaxNamespace.AjaxMethods.LogActivity(msg,page)
}

function LogError(msg,page)
{
	//alert("Log" + msg + " " + page);
	AjaxNamespace.AjaxMethods.LogError(msg,page)
}

function MEF_LoadLocationDropdowns(id)
{
	if(id.value == 0)
	{
		for(i = 0; i < locationDrops.length; i++)
		{
			var drp = document.getElementById(locationDrops[i]);
			drp.selectedIndex = 0;
			//drp.disabled = false;
		}
	}
	else
	{
		AjaxNamespace.AjaxMethods.fillLocationBoxHallID(id.value,callback_LoadLocationDropdowns);
	}

}

function callback_LoadLocationDropdowns(res)
{
	var drp;
	var value;

	for(i = 0; i < locationDrops.length; i++)
	{
		drp = document.getElementById(locationDrops[i]);

		if(i == 0)
			value = res.value.Street;
		else if (i == 1)
			value = res.value.City;
		else if (i == 2)
			value = res.value.State;
		else if (i == 3)
			value = res.value.Country;
		else
			break;

		drp.selectedIndex = getSelectedIndex(drp,value);
	}
}
function MEF_ClearControls()
{
	var theForm = document.getElementById("MainEntryForm");
	var form = document.forms[0];

		var emptyTable = "<table class=\"SmallSS\" cellspacing=\"0\" cellpadding=\"3\" rules=\"cols\" bordercolor=\"#3333CC\" border=\"5\" id=\"dgPerformersUI\" bgcolor=\"White\">" +
						"<tr bgcolor=\"Black\">" +
						"<td><font color=\"White\"><b>Edit</b></font></td>" +
						"<td><font color=\"White\"><b>Title</b></font></td>" +
						"<td><font color=\"White\"><b><a href=\"javascript:__doPostBack(\'dgPerformersUI$_ctl2$_ctl0\',\'\')\"><font color=\"White\">Name</font></a></b></font></td>" +
						"<td><font color=\"White\"><b><a href=\"javascript:__doPostBack(\'dgPerformersUI$_ctl2$_ctl1\',\'\')\"><font color=\"White\">Role</font></a></b></font></td>" +
						"<td><font color=\"White\"><b><a href=\"javascript:__doPostBack(\'dgPerformersUI$_ctl2$_ctl2\',\'\')\"><font color=\"White\">Position</font></a></b></font></td>" +
						"<td><font color=\"White\"><b>Remove</b></font></td>" +
						"</tr><tr align=\"Center\" bgcolor=\"#999999\">" +
						"<td colspan=\"6\"><font color=\"Black\"><span>&lt;&lt; Previous</span>&nbsp;<span>Next &gt;&gt;</span></font></td>" +
						"</tr></table>";

	for(var i = 0; i < theForm.length; i++)
	{
		el = form.elements[i];
		if(el.type == 'text')
		{
			el.value = "";
		}
		else if(el.type == 'textarea')
		{
			el.value = "";
		}
		else if(el.type == 'select-one')
		{
			el.selectedIndex = 0;

			if((el.name == "drpCompName") || (el.name == "drpExcerptFrom"))
				el.length = 0;
		}
		else if(el.type == 'radio')
		{
			var rad = document.getElementById(el.name + "_0");
			rad.checked = true;
		}
	}
	AjaxNamespace.AjaxMethods.ClearPerformerDataSet()
}

function callback_LoadComposer(res)
{
	if(res != null && res.value != null && res.value.Tables != 0 && res.value.Tables.length == 1)
	{
		document.MainEntryForm.txtComposerFirstName.value = res.value.Tables[0].Rows[0].FName;
		document.MainEntryForm.txtComposerMiddleName.value = res.value.Tables[0].Rows[0].MName;
		document.MainEntryForm.txtComposerLastName.value = res.value.Tables[0].Rows[0].LName;
	}
}

function MEF_ClearComposition(degree)
{
	document.MainEntryForm.txtCompName.value = "";
	document.MainEntryForm.txtCompOtherName.value = "";
	document.MainEntryForm.txtKey.value = "";
	document.MainEntryForm.txtOpus.value = "";
	document.MainEntryForm.txtCompRevision.value = "";
	document.MainEntryForm.drpCompType.selectedIndex = 0;
	document.MainEntryForm.drpExcerptFrom.selectedIndex = 0;
	document.MainEntryForm.radExcerpts[0].checked = true;

	if(degree == "deep")
	{
		document.MainEntryForm.drpExcerptFrom.length = 0;
		document.MainEntryForm.drpCompName.length = 0;
	}
}

function MEF_ClearComposer()
{
	document.MainEntryForm.txtComposerFirstName.value = "";
	document.MainEntryForm.txtComposerMiddleName.value = "";
	document.MainEntryForm.txtComposerLastName.value = "";
}

function autoComplete(field, select, property, forcematch, composers, dropDownName)
{
	var found = false;

	for (var i = 0; i < select.options.length; i++)
	{
		if (select.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0)
		{
			found=true; break;
		}
	}
	if (found)
	{
		select.selectedIndex = i;
		if(composers == true)
			getCompByComposer(select.options[i].value)
		else
			ChangeDropdownHidden(dropDownName);
	}
	else
	{
		select.selectedIndex = -1;
	}
	if (field.createTextRange)
	{
		if (forcematch && !found)
		{
			field.value=field.value.substring(0,field.value.length-1);
			return;
		}
		var cursorKeys ="8;46;37;38;39;40;33;34;35;36;45;";
		if (cursorKeys.indexOf(event.keyCode+";") == -1)
		{
			var r1 = field.createTextRange();
			var oldValue = r1.text;
			var newValue = found ? select.options[i][property] : oldValue;

			if (newValue != field.value)
			{
				field.value = newValue;
				var rNew = field.createTextRange();
				rNew.moveStart('character', oldValue.length) ;
				rNew.select();
			}
		}
	}
}
