
var DEBUG = false;

//  Event handler for an XML HTTP request, used for:
//
//    1.  Adding an item to the marked list
//    2.  Removing an item from the marked list
//    3.  Retrieving the list of currently marked items
//
//  The second argument is the button or checkbox that was used to issue
//    the Add or Remove operation.  This needs to be enabled when the
//    operation has completed.  For the Retrieve request this is null.
//
function handle_server_response( request, buttonOrCheckbox )
{
	if ( DEBUG )
	alert( "State change for XMLHttpRequest:\n" +
	       "  Object state = " + request.readyState + "\n" +
	       "  Response status = " + request.status + "\n" +
	       "  Response text = '" + request.responseText + "'\n" );

	//  When a request has completed (state 4) and has been returned a valid
	//    document (HTTP status code 200) parse the response details from
	//    the text of the HTML document.
	//
	//  There should be a '<response>...</response>' tag which contains one or
	//    more tab-separated fields: the first gives the outcome of the
	//    request, and any additional fields are returned data.
	//
	if ( request.readyState == 4 && request.status == 200 &&
	     request.responseText.indexOf( "<response>" ) != -1 &&
	     request.responseText.indexOf( "</response>" ) != -1 )
	{
		//  Get the contents of the '<response>' tag
		var start = request.responseText.indexOf( "<response>" );
		var end = request.responseText.indexOf( "</response>" );
		var contents = request.responseText.substring( start + 10, end );
		//  Get the tab-separated fields
		var fields = contents.split( "\t" );

		if ( DEBUG )
		alert( "Fields in response are:\n    " +
		       fields.join( "\n    " ) );

		//  Get the outcome of the request
		var outcome = fields[ 0 ];

		//  Enable any button or checkbox that initiated the request
		if ( buttonOrCheckbox != null ) buttonOrCheckbox.disabled = false;

		//  Clear any progress message on the page, in any
		//    '<div id="mlprogress">' area.
		//
		var progressDiv = document.getElementById( "mlprogress" );
		if ( progressDiv )
		{
			progressDiv.innerHTML = "&nbsp;";
		}

		//  Remaining fields in the response are the identifiers of the
		//    items that were processed, prefixed with '+' or '-'
		//    according to whether they are now marked or unmarked
		var i;
		for ( i = 1; i < fields.length; i++ )
		{
			var indicator = fields[ i ].substring( 0, 1 );
			var checkboxId = fields[ i ].substring( 1 );
			if ( indicator == "+" )
			{
				//  Item is now marked
				highlight_item( checkboxId, true );
			}
			else if ( indicator == "-" )
			{
				//  Item is now unmarked
				highlight_item( checkboxId, false );
			}
		}

		//  Display any error messages for this outcome
		if ( outcome == "AddError" )
		{
			alert( "An error occurred while attempting to add an item " +
			       "to the Marked List" );
		}
		else if ( outcome == "RemoveError" )
		{
			alert( "An error occurred while attempting to remove an item " +
			       "from the Marked List" );
		}
		else if ( outcome.indexOf( "LimitReached=" ) == 0 )
		{
			//  Get the limit that was reached (after the '=' sign)
			var limit = outcome.substring( outcome.indexOf( "=" ) + 1 );
			alert( "Your Marked List is full, with " + limit + " items.\n" +
			       "please delete some items before adding more" );
		}

	}
}

//  Function to mark (or unmark) one or more items, by sending an
//    XMLHttpRequest to the server to add the items to (or remove them
//    from) the Marked List.
//
//  This is used when the user clicks the 'Add to Marked List' checkbox
//    to mark or unmark a single record; or the 'Mark/Clear all items'
//    checkbox to mark or unmark all the items on a page.
//
//  First argument is the checkbox which the user has clicked to initiate
//    the request.  This will be disabled while the request is being
//    processed, and enabled again when it is finished.  This prevents
//    the user from clicking on it several times.
//
//  Second argument is 'true' to mark the items; 'false' to unmark them
//
//  Third argument is an array of the items being marked; each item is
//    a single string (containing tab-separated 'name=value' pairs)
//    taken from the 'value' attribute of the 'Add to Marked List'
//    checkbox.
//
function mark_or_unmark_items( checkbox, isBeingMarked, itemArray )
{
	//  Disable the checkbox
	checkbox.disabled = true;
	
	//  Insert a progress message into the page, into any
	//    '<div id="mlprogress">' area.  Only applies when
	//    marking or unmarking more than one item
	//
	var progressDiv = document.getElementById( "mlprogress" );
	if ( progressDiv && itemArray.length > 1 )
	{
		progressDiv.innerHTML =
				"" + ( isBeingMarked ? "Marking " : "Clearing " ) +
				itemArray.length + " items ... ";
	}

	if ( DEBUG )
	alert ( "" + ( isBeingMarked ? "Marking " : "Unmarking " ) +
	        itemArray.length + " item(s) ..." );

	//  URL for the Marked List operations
	var url = "/saveditems/myArchive.do";

	//  Form the parameters in the body of the request:
	//
	//    action  = 'addToMarkedList' (if checkbox has been checked) or
	//              'removeFromMarkedList' (if it has been unchecked)
	//
	//    item1   = the string of tab-separated 'name=value' pairs that
	//              contain the details of the first record being added
	//              or removed.  Taken from the 'value' attribute of the
	//              'Add to Marked List' checkbox against the item.
	//
	//    item2   = the details of the second item being added
	//
	//    item3   = the details of the third item being added
	//
	//    ... and so on for subsequent items ...
	//
	var body = "action=" + ( isBeingMarked ? "addToMarkedList"
	                                       : "removeFromMarkedList" );
	var i;
	for ( i = 1; i <= itemArray.length; i++ )
	{
		body += "&items=" + escape( itemArray[ i - 1 ] );
	}

	//  Form the XML HTTP Request object used to send the request
	var request;
	if ( window.XMLHttpRequest )
	{
		//  Firefox, Safari and later versions of IE
		request = new XMLHttpRequest();
	}
	else if ( window.ActiveXObject )
	{
		//  IE 5.0 implementation
		request = new ActiveXObject( "Microsoft.XMLHTTP" );
	}

	if ( request )
	{
		//  Set the event handler for the response from the server.
		//    The response will indicate if the mark/unmark was successful,
		//    and the event handler will deal with this accordingly
		//
		request.onreadystatechange =
			function() { handle_server_response( request, checkbox ) };

		//  Send the request
		request.open( "POST", url, true );
		request.setRequestHeader( "Content-Type",
									"application/x-www-form-urlencoded" );
		request.setRequestHeader( "Content-Length", body.length );
		request.send( body );
	}
}

//
//  Function invoked when the user clicks the 'Select this record' checkbox
//    to add a record to the Marked List, or remove an already marked record.
//
//  The argument is the checkbox element which has been clicked.
//
//  The 'name' attribute is a unique identifier for the record, formed from
//    the area and the record ID, e.g. 'documents:Gerritsen-G123'.
//
//  The 'value' attribute is a tab-separated list of 'name=value' pairs which
//    contain all the necessary details of the record which are to be saved
//    in the Marked List.
//
function update_marked_list( checkbox )
{
	if ( DEBUG )
	alert ( ( checkbox.checked ? "Adding to " : "Removing from " ) +
	        "Marked List:\n" +
	        "item: '" + checkbox.id + "'\n" +
	        "with fields:\n    " +
	        checkbox.value.split( "\t" ).join( "\n    " ) );
	        
	var itemArray = new Array();
	itemArray[ 0 ] = checkbox.value;
	
	mark_or_unmark_items( checkbox, checkbox.checked, itemArray );
}

//  Function invoked when a page is initially loaded to check all the
//    'Add to Marked List' checkboxes for items that are already
//    in the Marked List.
//
//  This makes a request to the server to return the identifiers for all
//    items currently in the marked list.  When the response is received
//    all
//
function highlight_all_marked_items()
{
	//  Form the URL for the request, with one parameter:
	//
	//    action  - 'getMarkedListRecordIds'
	//
	var action = "getMarkedListRecordIds";
	var url = "/saveditems/myArchive.do" +
	          "?action=" + action;

	// window.status = "Checking for marked items on current page ...";

	//  Form the XML HTTP Request object used to send the request
	var request;
	if ( window.XMLHttpRequest )
	{
		//  Firefox, Safari and later versions of IE
		request = new XMLHttpRequest();
	}
	else if ( window.ActiveXObject )
	{
		//  IE 5.0 implementation
		request = new ActiveXObject( "Microsoft.XMLHTTP" );
	}

	if ( request )
	{
		//  Set the event handler for the response from the server.
		//    The response will indicate if the mark/unmark was successful,
		//    and the event handler will deal with this accordingly
		//
		request.onreadystatechange =
			function() { handle_server_response( request, null ) };

		//  Send the request - consists of a GET with no body
		request.open( "GET", url );
		request.send( null );
	}

	// window.status = "Sent XMLHttpRequest: " + action + "  ...";
}

//  Function to update the 'Add to Marked List' checkbox, and the highlighting
//    which surrounds it, according to whether the item is in the Marked List
//    or not.
//
//  The first argument is the identifier of the checkbox (formed from the
//    item's area and identifier, of the form 'area:id'); the second argument
//    is true if the item is marked, or false if unmarked.
//
//  This is used when a page is initially loaded to highlight any items that
//    are currently in the Marked List; and subsequently when items are added
//    or removed by the user using the checkboxes on the page.
//
function highlight_item( checkboxId, isMarked )
{
	//  Find the checkbox with the specified identifier.  If this is
	//    not present on the page then there is nothing to do
	//
	var checkbox = document.getElementById( checkboxId );
	if ( ! checkbox ) return;

	//  Ensure the checkbox is appropriately checked or unchecked
	if ( isMarked && ! checkbox.checked )
	{
		//  Check the box now that the item is in the Marked List
		checkbox.checked = true;
	}
	else if ( ! isMarked && checkbox.checked )
	{
		//  Uncheck the box now that the item is not in the Marked List
		checkbox.checked = false;
	}

	//  Apply any highlighting to the item (such as a background colour
	//    or a surrounding border) which is assumed to be represented by
	//    a CSS class named 'inMarkedList' or 'notInMarkedList'
	//
	//  Starting from the checkbox, work backwards through the hierarchy
	//    of enclosing elements until one is found which has either of
	//    these classes, and then update the class appropriately.
	//
	for ( node = checkbox; node != null; node = node.parentNode )
	{
		var classname = node.className;
		if ( classname != null &&
		     ( classname == "inMarkedList" ||
		       classname == "notInMarkedList" ) )
		{
			//  Update the class of this eleemnt to apply the highlighting
			node.className = isMarked ? "inMarkedList" : "notInMarkedList";
			break;
		}
	}
}

//  Function invoked when the user clicks the 'Mark/Clear all items on this page'
//    checkbox.
//
//  Iterates over all the Marked List checkboxes, all of which should have the
//    name "mlcb", and processes each in turn, as if the user had clicked
//    each one individually.
//
function mark_or_clear_all_items_on_page( markAllCheckbox )
{
	if ( DEBUG )
	alert( "Mark/Clear all items on page ..." );

	//  Find all the 'Add to Marked List' checkboxes on this page
	var checkboxList = document.getElementsByName( "mlcb" );

	if ( DEBUG )
	alert( "Found " + checkboxList.length + " checkboxes on this page ..." );

	var statusMsg = ( markAllCheckbox.checked ? "Marking " : "Clearing " ) +
	                "all " + checkboxList.length + " items on page ... ";

	//  Accumulate the array of items to be marked or unmarked
	var itemArray = new Array();
	var i;
	for ( i = 0; i < checkboxList.length; i++ )
	{
		if ( markAllCheckbox.checked &&
		     ! checkboxList[ i ].checked )
		{
			//  This item needs to be marked
			itemArray[ itemArray.length ] = checkboxList[ i ].value;
		}

		else if ( ! markAllCheckbox.checked &&
		          checkboxList[ i ].checked )
		{
			//  This item needs to be unmarked
			itemArray[ itemArray.length ] = checkboxList[ i ].value;
		}
	}

	if ( DEBUG )
	alert( "Found " + itemArray.length + " items to be " +
	       ( markAllCheckbox.checked ? "marked" : "cleared" ) );

	//  Mark or clear all the items
	if ( itemArray.length > 0 )
	{
		//  Disable the checkbox while the request is being processed
		markAllCheckbox.disabled = true;

		//  Send the request to mark or unmark these items
		mark_or_unmark_items( markAllCheckbox,
		                      markAllCheckbox.checked, itemArray );
	}

}
