/*

Javascript code for use on OHDB website
Author: Oliy Hine
Unauthorised use of this code is prohibited

*/

var ID;

function NamedArray( name, array )
{
	this.name = name;
	this.array = array;
}

NamedArray.prototype.getName = function(){
	return this.name;
}

NamedArray.prototype.getArray = function(){
	return this.array;
}

function displayHelp()
{
	var helpBoxId = "help";
	showhide( helpBoxId );
}


function gMapUnload()
{
	// detect if gmap div is on the page and unload map when page closed if it exists
	var pageMap = document.getElementById( "gmap" );
	
	if ( pageMap )
	{
		// map exists, unload
		// assume that the GMaps javascript is available
		GUnload();
	}
}

function showhide( id )
{
	el = document.getElementById( id );
	if ( el )
	{
		if ( el.style.display == 'none' )
		{
			el.style.display = '';
			return true;
		}
		else
		{
			el.style.display = 'none';
			return false;
		}
	}

}

function show( id )
{
	el = document.getElementById( id );
	if ( el )
	{
		el.style.display = '';
	}
}

function hide( id )
{
	el = document.getElementById( id );
	if ( el )
	{
		el.style.display = 'none';
	}
}

function highlight( id )
{
	el = document.getElementById( id );
	if ( el )
	{
	
		if ( el.style.backgroundColor != '' )
		{
			el.style.backgroundColor = '';
			el.style.border = '';
		}
		else
		{
			el.style.backgroundColor  = '#fff88f';
			el.style.border = '1px solid black';
		}
	}
}

function appendHTMLToDiv( sourceDiv, targetDiv )
{
	sourceDiv = document.getElementById( sourceDiv );
	targetDiv = document.getElementById( targetDiv );
	
	if ( ( sourceDiv ) && ( targetDiv ) )
	{
		targetDiv.innerHTML += sourceDiv.innerHTML;
	}
}



function writeAllCheckboxes( field, string_box, results_div, selected_results_div, content_array, selected_content_array, submit_field_name )
{
	var isMutable = true;
	try
	{
		isMutable = eval( field + "Mutable" );
	} catch ( e ) {}
	
	var filteredInterestsDiv = document.getElementById( results_div );
	var content_array_name = content_array.getName();
	var content_array = content_array.getArray();
	var selected_content_array_name = selected_content_array.getName();
	var selected_content_array = selected_content_array.getArray();
	var filterString = "";
	

	var filteredListIndices = arrayFind( content_array, filterString );

	if ( filteredListIndices.length > 0 )
	{

		var filteredList = arrayIntersect( content_array, filteredListIndices );

		filteredInterestsDiv.innerHTML = "";

		var filteredListValueToIndex = [];
		var filteredListDisplay = [];

		for ( var i in filteredList )
		{
			filteredListValueToIndex[ filteredList[ i ] ] = i;
			filteredListDisplay.push( filteredList[ i ] );
		}

		filteredListDisplay.sort();

		for ( var i = 0; i < filteredListDisplay.length; i++ )
		{
			contentName = filteredListDisplay[ i ];
			contentId = filteredListValueToIndex[ contentName ];

			filteredInterestsDiv.innerHTML += "<input onclick=\"javascript:copyItemBetweenArrays( " + content_array_name + ", '" + contentId + "', " + selected_content_array_name + " ); refreshCheckboxes( '" + field + "' );\" type=\"checkbox\" value=\"" + contentId + "\" />" + contentName + "<br/>\n";
		}

		// check it doesn't already exist in selected array
		var selectedListIndices = arrayMatch( selected_content_array, filterString );
		if ( selectedListIndices.length > 0 )
		{
			// already in selected interests
		}
		else
		{
			// check it isn't displayed in the filtered list already
			var filteredListIndices = arrayMatch( filteredList, filterString );
			if ( filteredListIndices.length > 0 )
			{
				// is already display above, do nothing
			}
			else
			{
				if ( isMutable )
				{
					filteredInterestsDiv.innerHTML += "<p class=\"smalltext\"><a href=\"javascript:addToNewValueToArray( '" + field + "' );\">Add \"" + ucFirst( filterString ) + "\" to your selection</a>.</p>";	
				}
			}
		}

	}
	else
	{
		filteredInterestsDiv.innerHTML = "";

		// nothing found
		// check it doesn't already exist in selected array
		var selectedListIndices = arrayMatch( selected_content_array, filterString );
		if ( selectedListIndices.length > 0 )
		{
			// already in selected interests
			filteredInterestsDiv.innerHTML += "<p class=\"smalltext\">You have already selected the value \"" + ucFirst( filterString ) + "\"</p>";
		}
		else
		{
			filteredInterestsDiv.innerHTML = "<p class=\"smalltext\">The value \"" + ucFirst( filterString ) + "\" is not in the database.</p>";
			if ( isMutable )
			{
				filteredInterestsDiv.innerHTML += "<p class=\"smalltext\"><a href=\"javascript:addToNewValueToArray( '" + field + "' );\">Add \"" + ucFirst( filterString ) + "\" to your selection</a>.</p>";
			}
		}
	}

}



function writeSpecifiedFilteredCheckboxes( field, string_box, results_div, selected_results_div, content_array, selected_content_array, submit_field_name, filterLength )
{
	var isMutable = true;
	try
	{
		isMutable = eval( field + "Mutable" );
	} catch ( e ) {}
	
	var filterString = document.getElementById( string_box ).value;
	var filteredInterestsDiv = document.getElementById( results_div );
	var content_array_name = content_array.getName();
	var content_array = content_array.getArray();
	var selected_content_array_name = selected_content_array.getName();
	var selected_content_array = selected_content_array.getArray();
	
	if ( filterString.length > filterLength )
	{
		var filteredListIndices = arrayFind( content_array, filterString );
		
		if ( filteredListIndices.length > 0 )
		{
		
			var filteredList = arrayIntersect( content_array, filteredListIndices );

			filteredInterestsDiv.innerHTML = "";

			var filteredListValueToIndex = [];
			var filteredListDisplay = [];

			for ( var i in filteredList )
			{
				filteredListValueToIndex[ filteredList[ i ] ] = i;
				filteredListDisplay.push( filteredList[ i ] );
			}

			filteredListDisplay.sort();

			for ( var i = 0; i < filteredListDisplay.length; i++ )
			{
				contentName = filteredListDisplay[ i ];
				contentId = filteredListValueToIndex[ contentName ];

				filteredInterestsDiv.innerHTML += "<input onclick=\"javascript:copyItemBetweenArrays( " + content_array_name + ", '" + contentId + "', " + selected_content_array_name + " ); refreshCheckboxes( '" + field + "' );\" type=\"checkbox\" value=\"" + contentId + "\" />" + contentName + "<br/>\n";
			}
			
			// check it doesn't already exist in selected array
			var selectedListIndices = arrayMatch( selected_content_array, filterString );
			if ( selectedListIndices.length > 0 )
			{
				// already in selected interests
			}
			else
			{
				// check it isn't displayed in the filtered list already
				var filteredListIndices = arrayMatch( filteredList, filterString );
				if ( filteredListIndices.length > 0 )
				{
					// is already display above, do nothing
				}
				else
				{
					if ( isMutable )
					{
						filteredInterestsDiv.innerHTML += "<p class=\"smalltext\"><a href=\"javascript:addToNewValueToArray( '" + field + "' );\">Add \"" + ucFirst( filterString ) + "\" to your selection</a>.</p>";	
					}
				}
			}
			
		}
		else
		{
			filteredInterestsDiv.innerHTML = "";
		
			// nothing found
			// check it doesn't already exist in selected array
			var selectedListIndices = arrayMatch( selected_content_array, filterString );
			if ( selectedListIndices.length > 0 )
			{
				// already in selected interests
				filteredInterestsDiv.innerHTML += "<p class=\"smalltext\">You have already selected the value \"" + ucFirst( filterString ) + "\"</p>";
			}
			else
			{
				filteredInterestsDiv.innerHTML = "<p class=\"smalltext\">The value \"" + ucFirst( filterString ) + "\" is not in the database.</p>";
				if ( isMutable )
				{
					filteredInterestsDiv.innerHTML += "<p class=\"smalltext\"><a href=\"javascript:addToNewValueToArray( '" + field + "' );\">Add \"" + ucFirst( filterString ) + "\" to your selection</a>.</p>";
				}
			}
		}
		
	}
	else
	{
		//filteredInterestsDiv.innerHTML = "<p class=\"smalltext\">Type the first few letters into the box above</p>";
		filteredInterestsDiv.innerHTML = "";
	}
}

function writeSpecifiedSelectedCheckboxes( field, string_box, results_div, selected_results_div, content_array, selected_content_array, submit_field_name )
{
	var selectedResultsDiv = document.getElementById( selected_results_div );
	var content_array_name = content_array.getName();
	var content_array = content_array.getArray();
	var selected_content_array_name = selected_content_array.getName();
	var selected_content_array = selected_content_array.getArray();
		
	selectedResultsDiv.innerHTML = "";

	// test to see if there are any elements in this array (length doesn't work on associative arrays)
	var selected_contents_exist = false;
	for ( var elems in selected_content_array )
	{
		selected_contents_exist = true;
	}

	if ( selected_contents_exist )
	{
		var selectedListValueToIndex = [];
		var selectedListDisplay = [];
	
		for ( var i in selected_content_array )
		{
			selectedListValueToIndex[ selected_content_array[ i ] ] = i;
			selectedListDisplay.push( selected_content_array[ i ] );
		}
	
		selectedListDisplay.sort();
	
		for ( var i = 0; i < selectedListDisplay.length; i++ )
		{
			contentName = selectedListDisplay[ i ];
			contentId = selectedListValueToIndex[ contentName ];

			selectedResultsDiv.innerHTML += "<input checked=\"checked\" onclick=\"copyItemBetweenArrays( " + selected_content_array_name + ", '" + contentId + "', " + content_array_name + " ); refreshCheckboxes( '" + field + "' );\" type=\"checkbox\" name=\"" + submit_field_name + "[]\" value=\"" + contentId + "\" />" + contentName + "<br/>\n";
		}
	}
	else
	{
		selectedResultsDiv.innerHTML += "<p class=\"smalltext\">You have not selected any values. Please select from the list on the left</p>";
	}
}





function refreshCheckboxes( field )
{
	writeSelectedCheckboxes( field );
	writeFilteredCheckboxes( field );
}


function viewAllCheckboxes( field )
{
	switch( field )
	{
		case "interests":
		{
			writeAllCheckboxes( 'interests', 'interest_filter', 'filtered_interests_div', 'selected_interests_div', named_interest_array, named_selected_interests_array, 'interests' );
			return;
		}
		case "universities":
		{
			writeAllCheckboxes( 'universities', 'universities_filter', 'filtered_universities_div', 'selected_universities_div', named_universities_array, named_selected_universities_array, 'universities' );
			return;
		}
		case "industries":
		{
			writeAllCheckboxes( 'industries', 'industries_filter', 'filtered_industries_div', 'selected_industries_div', named_industries_array, named_selected_industries_array, 'industries' );
			return;
		}
		case "courses":
		{
			writeAllCheckboxes( 'courses', 'courses_filter', 'filtered_courses_div', 'selected_courses_div', named_courses_array, named_selected_courses_array, 'courses' );
			return;
		}
	}
}


function writeFilteredCheckboxes( field )
{
	switch( field )
	{
		case "interests":
		{
			writeSpecifiedFilteredCheckboxes( 'interests', 'interest_filter', 'filtered_interests_div', 'selected_interests_div', named_interest_array, named_selected_interests_array, 'interests', 2 );
			return;
		}
		case "universities":
		{
			writeSpecifiedFilteredCheckboxes( 'universities', 'universities_filter', 'filtered_universities_div', 'selected_universities_div', named_universities_array, named_selected_universities_array, 'universities', 0 );
			return;
		}
		case "industries":
		{
			writeSpecifiedFilteredCheckboxes( 'industries', 'industries_filter', 'filtered_industries_div', 'selected_industries_div', named_industries_array, named_selected_industries_array, 'industries', 0 );
			return;
		}
		case "courses":
		{
			writeSpecifiedFilteredCheckboxes( 'courses', 'courses_filter', 'filtered_courses_div', 'selected_courses_div', named_courses_array, named_selected_courses_array, 'courses', 0 );
			return;
		}
	}
}


function writeSelectedCheckboxes( field )
{
	switch( field )
	{
		case "interests":
		{
			writeSpecifiedSelectedCheckboxes( 'interests', 'interest_filter', 'filtered_interests_div', 'selected_interests_div', named_interest_array, named_selected_interests_array, 'interests' );
			return;
		}
		case "universities":
		{
			writeSpecifiedSelectedCheckboxes( 'universities', 'universities_filter', 'filtered_universities_div', 'selected_universities_div', named_universities_array, named_selected_universities_array, 'universities' );
			return;
		}
		case "industries":
		{
			writeSpecifiedSelectedCheckboxes( 'industries', 'industries_filter', 'filtered_industries_div', 'selected_industries_div', named_industries_array, named_selected_industries_array, 'industries' );
			return;
		}
		case "courses":
		{
			writeSpecifiedSelectedCheckboxes( 'courses', 'courses_filter', 'filtered_courses_div', 'selected_courses_div', named_courses_array, named_selected_courses_array, 'courses' );
			return;
		}
	}
}



function addToNewValueToArray( field )
{
	switch( field )
	{
		case "interests":
		{
			addToNewValueToSpecifiedArray( 'interests', 'interest_filter', interest_array, selected_interests_array );
			return;
		}
		case "universities":
		{
			addToNewValueToSpecifiedArray( 'universities', 'universities_filter', universities_array, selected_universities_array );
			return;
		}
		case "industries":
		{
			addToNewValueToSpecifiedArray( 'industries', 'industries_filter', industries_array, selected_industries_array );
			return;
		}
		case "courses":
		{
			addToNewValueToSpecifiedArray( 'courses', 'courses_filter', courses_array, selected_courses_array );
			return;
		}
	}
}

function addToNewValueToSpecifiedArray( field, string_box, content_array, selected_content_array )
{

	var filterString = ucFirst( document.getElementById( string_box ).value );
	var newContent = [];
	newContent[ filterString ] = filterString;
	
	content_array[ filterString ] = filterString;
	copyItemBetweenArrays( content_array, filterString, selected_content_array );
	
	refreshCheckboxes( field );

}


function copyItemBetweenArrays( sourceArray, arrayIndex, targetArray )
{
	targetArray[ arrayIndex ] = sourceArray[ arrayIndex ];
	delete sourceArray[ arrayIndex ];
	
}

function arrayIntersect( mainArray, intersectingArray )
{
	var returnArray = [];

	for ( var i = 0; i < intersectingArray.length; i++ )
	{
		mainArrayIndex = intersectingArray[ i ];
		returnArray[ mainArrayIndex ] = mainArray[ mainArrayIndex ];
	}

	return returnArray;
}

// match entries in an array (case insensitive)
function arrayMatch( searchArray, searchStr )
{
  var returnArray = [];
  for ( var i in searchArray )
  {
      if ( searchArray[ i ].toLowerCase() == searchStr.toLowerCase() )
      {
	returnArray.push(i);
      }
  }

  return returnArray;
}

// find similar entries in an ar ray (case insensitive)
function arrayFind( searchArray, searchStr )
{
  var returnArray = [];
  for ( var i in searchArray )
  {
      if (searchArray[i].toLowerCase().indexOf( searchStr.toLowerCase() ) > -1 ) {
	returnArray.push(i);
      }
  }

  return returnArray;
}

function ucFirst( newString )
{
	return newString.substr( 0,1 ).toUpperCase() + newString.substr( 1,newString.length );
}

var numberOfFileUploadBoxes = 1;

function addFileUploadBox()
{
	var fileContainerId = "fileUploadContainer";
	var fileContainer = document.getElementById( fileContainerId );
	
	if ( fileContainer )
	{
		numberOfFileUploadBoxes++;
		fileContainer.innerHTML += '\n<input name="file' + numberOfFileUploadBoxes + '" type="file" id="fileUpload' + numberOfFileUploadBoxes + '" />';
	}
}


function confirmSendNewsletter( isInProgress, batchNum, totalRecipients, batchSize )
{
	if ( isInProgress )
	{
		alert( "This newsletter is currently being processed and cannot be sent again until this has completed.\n"
		+ ( batchNum * batchSize ) + " mails have been processed, with " + ( totalRecipients - (batchNum * batchSize) ) + " remaining at a rate of " + batchSize + " per hour "
		+ "(Approximately " + ( Math.round( ( ( totalRecipients - (batchNum * batchSize) ) / batchSize ) + 0.5 ) ) + " hours remaining)." );
		return false;
	}
	else
	{
		return true;
	}
}

function cancelSendNewsletter( isInProgress, batchNum, totalRecipients, batchSize )
{
	if ( isInProgress )
	{
		return confirm( "This newsletter is currently being processed and has already been sent to \n"
		+ ( batchNum * batchSize ) + " recipients, with " + ( totalRecipients - (batchNum * batchSize) ) + " remaining\n\n"
		+ "Are you sure you wish to cancel?" );
	}
	else
	{
		return true;
	}
}

function confirmSelectRecipientsAndSend( isInProgress, batchNum, totalRecipients, batchSize )
{
	if ( isInProgress )
	{
		alert( "This newsletter is currently being processed and cannot be sent again until this has completed.\n"
		+ ( batchNum * batchSize ) + " mails have been processed, with " + ( totalRecipients - (batchNum * batchSize) ) + " remaining at a rate of " + batchSize + " per hour "
		+ "(Approximately " + ( Math.round( ( ( totalRecipients - (batchNum * batchSize) ) / batchSize ) + 0.5 ) ) + " hours remaining)." );
		return false;
	}
	else
	{
		return confirm("This will send the newsletter to all " + totalRecipients + " mailinglist recipients and will take up to " 
		+ ( Math.round( ( totalRecipients / batchSize ) + 0.5 ) ) + " hours to complete, at a rate of " + batchSize + " per hour.\n\n Are you sure you wish to continue?" );
	}
}


function getTotalNumberOfSelectedRecipients( recipientBox, groupsAndTotals )
{
	var total = 0;
	for ( var i = 0; i < recipientBox.options.length; i++ )
	{
		total += groupsAndTotals[ recipientBox.options[i].value ];
	}
	return total;
}



// -------------------------------------------------------------------
// moveSelectedOptions(select_object,select_object[,autosort(true/false)[,regex]])
//  This function moves options between select boxes. Works best with
//  multi-select boxes to create the common Windows control effect.
//  Passes all selected values from the first object to the second
//  object and re-sorts each box.
//  If a third argument of 'false' is passed, then the lists are not
//  sorted after the move.
//  If a fourth string argument is passed, this will function as a
//  Regular Expression to match against the TEXT or the options. If 
//  the text of an option matches the pattern, it will NOT be moved.
//  It will be treated as an unmoveable option.
//  You can also put this into the <SELECT> object as follows:
//    onDblClick="moveSelectedOptions(this,this.form.target)
//  This way, when the user double-clicks on a value in one box, it
//  will be transferred to the other (in browsers that support the 
//  onDblClick() event handler).
// -------------------------------------------------------------------
function moveSelectedOptions(from,to) {
	// Unselect matching options, if required
	if (arguments.length>3) {
		var regex = arguments[3];
		if (regex != "") {
			unSelectMatchingOptions(from,regex);
			}
		}
	// Move them over
	if (!hasOptions(from)) { return; }
	for (var i=0; i<from.options.length; i++) {
		var o = from.options[i];
		if (o.selected) {
			if (!hasOptions(to)) { var index = 0; } else { var index=to.options.length; }
			to.options[index] = new Option( o.text, o.value, false, false);
			}
		}
	// Delete them from original
	for (var i=(from.options.length-1); i>=0; i--) {
		var o = from.options[i];
		if (o.selected) {
			from.options[i] = null;
			}
		}
	if ((arguments.length<3) || (arguments[2]==true)) {
		sortSelect(from);
		sortSelect(to);
		}
	from.selectedIndex = -1;
	to.selectedIndex = -1;
	}


// -------------------------------------------------------------------
// hasOptions(obj)
//  Utility function to determine if a select object has an options array
// -------------------------------------------------------------------
function hasOptions(obj) {
	if (obj!=null && obj.options!=null) { return true; }
	return false;
	}


// -------------------------------------------------------------------
// sortSelect(select_object)
//   Pass this function a SELECT object and the options will be sorted
//   by their text (display) values
// -------------------------------------------------------------------
function sortSelect(obj) {
	var o = new Array();
	if (!hasOptions(obj)) { return; }
	for (var i=0; i<obj.options.length; i++) {
		o[o.length] = new Option( obj.options[i].text, obj.options[i].value, obj.options[i].defaultSelected, obj.options[i].selected) ;
		}
	if (o.length==0) { return; }
	o = o.sort( 
		function(a,b) { 
			if ( (parseInt(a.value)) < (parseInt(b.value)) ) { return -1; }
			if ( (parseInt(a.value)) > (parseInt(b.value)) ) { return 1; }
			return 0;
			} 
		);

	for (var i=0; i<o.length; i++) {
		obj.options[i] = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
		}
	}

// -------------------------------------------------------------------
// selectAllOptions(select_object)
//  This function takes a select box and selects all options (in a 
//  multiple select object). This is used when passing values between
//  two select boxes. Select all options in the right box before 
//  submitting the form so the values will be sent to the server.
// -------------------------------------------------------------------
function selectAllOptions(obj) {
	if (!hasOptions(obj)) { return; }
	for (var i=0; i<obj.options.length; i++) {
		obj.options[i].selected = true;
		}
	}
