/**
* Methods for making calls on framework services and statics describing application services
*/

var Service = {

	SCOPE_SEPARATOR: '-',
	ID_SEPARATOR: '_',

	// The URL of the request broker which handles all requests for services
	URL: 'requestBroker.php',
	// The URL for uploading documents
	DOCUMENT_UPLOAD_URL: '../framework/classes/document/DocumentUploader.php',

	// Keep this next section synchronised with Service.php
	
	DOCUMENT_INDEX: 'document.index',
	DOCUMENT_SEARCH: 'document.search',

	DOWNLOAD: 'download',
	REPORTS: 'reports',
	SEARCHER: 'searcher',
	BUTTONS: 'buttons',
	FSTREE: 'fstree',
	FSTREE_CONTROLS: 'fstreeControls',
	FSTREE_EDITOR: 'fstreeEditor',

	LISTER: 'lister',
	VIEWER: 'viewer',

	EDITOR_CREATE: 'editor.create',
	EDITOR_EDIT: 'editor.edit',
	EDITOR_SAVE: 'editor.save',
	EDITOR_REMOVE: 'editor.remove',
	EDITOR_CANCEL: 'editor.cancel',
	EDITOR_DUPLICATE: 'editor.duplicate',
	EDITOR_REFRESH: 'editor.refresh',
	
	contentSuccess: function(xhrObject) {
		document.body.style.cursor = "";
		var xmlObject = XML.getXMLObject(xhrObject);
		
		// Look for an error
		var error = xmlObject.getElementsByTagName('error')[0];
		if (error != undefined) {
			var message = error.getElementsByTagName('message')[0].firstChild.data;
			alert(message);
			return;
		}

		var root = xmlObject.getElementsByTagName('success')[0];
		var service = root.getElementsByTagName('service')[0].firstChild.data;
	    var context = root.getElementsByTagName('context')[0].firstChild.data;
		var target = root.getElementsByTagName('target')[0].firstChild.data;
		var content = root.getElementsByTagName('content')[0].firstChild.data;
	
		$(target).update(content);
		switch(service) {
			case Service.EDITOR_REMOVE:
				var entity = root.getElementsByTagName('entity')[0].firstChild.data;
				var entityID = root.getElementsByTagName('entityID')[0].firstChild.data;
				switch(entity) {
					case Entity.NOTE:
					case Entity.ACTION:
						var relatedEntityField = context + Service.SCOPE_SEPARATOR + 'entity';
						var relatedEntity = $(relatedEntityField).value;
						var relatedEntityIDField = context + Service.SCOPE_SEPARATOR + 'instanceID';
						var relatedEntityID = $(relatedEntityIDField).value;
				  		var filter = new ListFilter(relatedEntity, relatedEntityID);
					default:
						var eventHandler = 'Entity.view(\'' + context + '\',\'' + entity + '\',\'@id\')';
						Entity.list(context, entity, eventHandler, null, filter);
						break;
				}
				Entity.closeViewer(context, entity);
				break;
			case Service.EDITOR_CANCEL:
				var dirtyID = dirty.getDirty(context);
				if (dirtyID > 0) dirty.remove(context);
				var entity = root.getElementsByTagName('entity')[0].firstChild.data;
				Entity.cancelEditor(context, entity);
				break;
			case Service.EDITOR_SAVE:
				var dirtyID = dirty.getDirty(context);
				if (dirtyID > 0) dirty.remove(context);
				var entity = root.getElementsByTagName('entity')[0].firstChild.data;
				var entityID = root.getElementsByTagName('entityID')[0].firstChild.data;
				switch(entity) {
					case Entity.NOTE:
					case Entity.ACTION:
						var relatedEntityField = context + Service.SCOPE_SEPARATOR + 'entity';
						var relatedEntity = $(relatedEntityField).value;
						var relatedEntityIDField = context + Service.SCOPE_SEPARATOR + 'instanceID';
						var relatedEntityID = $(relatedEntityIDField).value;
				  		var filter = new ListFilter(relatedEntity, relatedEntityID);
					default:
						dirty.remove(context);
						var selection = new Selection(entity, entityID);
						var eventHandler = 'Entity.view(\'' + context + '\',\'' + entity + '\',\'@id\')';
						Entity.list(context, entity, eventHandler, selection, filter);
						break;
				}
				//Entity.edit(context, entity, entityID);
				Entity.view(context, entity,'',entityID);
				break;
			case Service.EDITOR_CREATE:
				var entity = root.getElementsByTagName('entity')[0].firstChild.data;
				// Call the entity type to do additional related entity stuff
				try {
					var call = entity.ucFirst() + '.create(\'' + context + '\')';
					eval(call);
				} catch(err) {alert(err + ' error calling create for: ' + entity);}
				// Request the edit buttons
				var target = context + Service.SCOPE_SEPARATOR + Service.BUTTONS + Service.SCOPE_SEPARATOR + entity;
				Service.buttons(target, context, Widget.EDITOR_BUTTONS, entity, null);
				dirty.add(context);
				break;
			case Service.EDITOR_EDIT:
				
				var entity = root.getElementsByTagName('entity')[0].firstChild.data;
				var entityID = root.getElementsByTagName('entityID')[0].firstChild.data;
				// Call the entity type
				try {
					var call = entity.ucFirst() + '.edit(\'' + context + '\',\'' + entityID + '\')';
					eval(call);
				} catch(err) {alert(err + 'error calling edit for: ' + entity);}
				// Request the edit buttons
				var target = context + Service.SCOPE_SEPARATOR + Service.BUTTONS + Service.SCOPE_SEPARATOR + entity;
				Service.buttons(target, context, Widget.EDITOR_BUTTONS, entity, entityID);
				dirty.add(context, entityID);
				break;
			case Service.VIEWER:
				var entity = root.getElementsByTagName('entity')[0].firstChild.data;
				var entityID = root.getElementsByTagName('entityID')[0].firstChild.data;
				try {
					var call = entity.ucFirst() + '.view(\'' + context + '\',\'' + entityID + '\')';
					eval(call);
				} catch(err) {;}
				// Request the view buttons
				var target = context + Service.SCOPE_SEPARATOR + Service.BUTTONS + Service.SCOPE_SEPARATOR + entity;
				Service.buttons(target, context, Widget.VIEWER_BUTTONS, entity, entityID);
				break;
			case AdminService.LOGIN:
				document.location = 'index.php';
				break;
			case Service.EDITOR_DUPLICATE:
				var entity = root.getElementsByTagName('entity')[0].firstChild.data;
				var entityID = root.getElementsByTagName('entityID')[0].firstChild.data;
				switch(entity) {
					case Entity.NOTE:
					case Entity.ACTION:
						var relatedEntityField = context + Service.SCOPE_SEPARATOR + 'entity';
						var relatedEntity = $(relatedEntityField).value;
						var relatedEntityIDField = context + Service.SCOPE_SEPARATOR + 'instanceID';
						var relatedEntityID = $(relatedEntityIDField).value;
				  		var filter = new ListFilter(relatedEntity, relatedEntityID);
					default:
						dirty.remove(context);
						var selection = new Selection(entity, entityID);
						var eventHandler = 'Entity.view(\'' + context + '\',\'' + entity + '\',\'@id\')';
						Entity.list(context, entity, eventHandler, selection, filter);
						Entity.edit(context, entity, entityID);
						break;
				}
				break;
			default:
				break;
		}
	},


	/**
	* General success handler for services that are not returning XHTML, i.e. services without a widget
	*/
	success: function(xhrObject) {
		document.body.style.cursor = "";
		var xmlObject = XML.getXMLObject(xhrObject);
		// Look for an error
		var error = xmlObject.getElementsByTagName('error')[0];
		if (error != undefined) {
			var message = error.getElementsByTagName('message')[0].firstChild.data;
			alert(message);
			return;
		}
		var root = xmlObject.getElementsByTagName('success')[0];
		var service = root.getElementsByTagName('service')[0].firstChild.data;
		switch(service) {
			case Service.DOCUMENT_INDEX:
				alert("Indexing has finished");
				break;
			case Service.REPORTS:
				// If we get here then there is something to report so back to the server to force a file save dialog
				var pars = 'service=' + Service.REPORTS;
				var reportID = root.getElementsByTagName('reportID')[0].firstChild.data;
				pars += '&' + 'reportID=' + reportID;
				pars += '&' + 'generateReport=' + 'true';
				// Forces a file save dialog
				document.location = 'requestBroker.php?' + pars;		
				break;
			case AdminService.LOGOUT:
				document.location = 'index.php';
				break;
			case AdminService.REMOVED_PURGE:
			case AdminService.REMOVED_RESTORE:
				//AdminService.refreshRemoved(Context.ADMIN, 'admin-lister-entity-select');
				AdminService.refreshRemoved(Context.ADMIN);
				break;
			case AdminService.CHANGE_PASSWORD:
				alert('Password updated');
				// Clear the form fields
				var textInputElements = $(Context.PROFILE + Service.SCOPE_SEPARATOR + 'password' + Service.SCOPE_SEPARATOR + 'form').getInputs('password');
				for (i = 0; i < textInputElements.length; i++) {
					$(textInputElements[i]).value = '';
				}
				break;
			case Service.EDITOR_DUPLICATE:
				
				break;
			default:
				break;
		}
	},


	failure: function(xhrObject) {
		document.body.style.cursor = "";
		alert('sorry there was a problem servicing your request');
	},
 
    documentUpload: function(context) {
    	// Collect the document file name
     	try {
  			var file = $F(context + Service.SCOPE_SEPARATOR + Widget.EDITOR + Service.SCOPE_SEPARATOR + 'file');
      	   	if (file.length == 0) {
		   		alert("Please select a file.");
				return;
		   	}
     	} catch(err) {
 		   		alert(err);
				return;
     	}
		// Ask for confirmation
		var answer = confirm('Upload may take a few minutes and cannot be interrupted. Click OK to continue.');
		if (answer) {		
			// File upload is not supported by XMLHTTP so we don't have asynchronous upload. Means we sit here for a bit
	 		var formID = context + Service.SCOPE_SEPARATOR + Entity.DOCUMENT + Service.SCOPE_SEPARATOR + 'form';
	 		$(formID).action = Service.DOCUMENT_UPLOAD_URL;
			$(formID).submit();
			// Back to the default action URL
	 		$(formID).action = 'javascript:void(0)'; 
		}		   
    },

	documentIndex: function() {
		var pars = 'service=' + Service.DOCUMENT_INDEX;
		var onSuccessFunction = 'Service.success';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});		
	},

	documentSearch: function() {
		var pars = 'service=' + Service.DOCUMENT_SEARCH;
		// Get the search terms
		var idPrefix = Context.DOCUMENTS + Service.SCOPE_SEPARATOR;
		var termsFieldID = idPrefix + 'terms';
		var terms = $(termsFieldID).value;
		if (terms.trim().length == 0) {
			alert('Please supply some search terms.');
			exit;
		}
		pars += '&' + 'terms=' + terms.trim();
		
		// Use the AND operator
		pars += '&' + 'operator=' + 'and';
		
		// Need a target for results
		var target = 'documents-results';
		pars += '&' + 'target=' + target;
		
		// Context
		pars += '&' + 'context=' + Context.DOCUMENTS;
		
		// Widget
		pars += '&' + 'widget=' + Widget.DOCUMENT_SEARCH_RESULTS;
		
		var onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});		
	},
	
	/**
	* Make reports service request
	* @param reportID id defining requested report
	*/
	reports: function(reportID, onSuccessFunction) {
		var pars = 'service=' + Service.REPORTS;
		pars += '&' + 'reportID=' + reportID;
		// Check whether report status
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.success';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},

	/**
	* Make searcher service request
	* @param context the context of the request
	* @param entity the name of the entity being edited
	* @param service the editor service required
	* @param widget the buttons widget to use
	* @param entity the entity type
	* @param entityID the id of an entity instance
	*/
	searcher: function(target, context, widget, entity, onSuccessFunction) {
		var pars = 'service=' + Service.SEARCHER;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'widget=' + widget;
		pars += '&' + 'entity=' + entity;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},

	/**
	* Make buttons service request
	* @param context the context of the request
	* @param entity the name of the entity being edited
	* @param service the editor service required
	* @param widget the buttons widget to use
	* @param entity the entity type
	* @param entityID the id of an entity instance
	*/
	buttons: function(target, context, widget, entity, entityID, onSuccessFunction) {
		var pars = 'service=' + Service.BUTTONS;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'widget=' + widget;
		pars += '&' + 'entity=' + entity;
		if (entityID != undefined && entityID != null) pars += '&' + 'entityID=' + entityID;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},
	

	/**
	* Make lister service request
	*
	* @param target the target element into which widget XHTML is placed
	* @param context the context in which the lister is required
	* @param entity the entity type being listed
	* @param label label for list overrides the default
	* @param eventHandler the event handler for the select (required to support option selection in IE which does not support bubbling up to an enclosing div for select elements)
	* @param size the size attribute of the list's select element created by a ListerWidget
	* @param multiple the size attribute of the list's select element created by a ListerWidget
	* @param filter optional filter which reduces the list options to those related to another entity instance defined by the filter
	* @param widget optional - if defined overrides the default Lister widget, e.g. FlatListWidget
	* @param selection optional - defines the selected options of the select element created by a ListerWidget
	* @param exclusions optional - defines the excluded items of the select element created by a ListerWidget
	* @param suffix optional - defines an suffix for the id of a select element created by a ListerWidget. This permits multiple listings of the
	* same entity in a given context. For example, product descriptors and category descriptors of a collection. Usage:
	* <context>-lister-<entity>-<suffix>-select
	*/
	lister: function(target, context, entity, label, eventHandler, size, multiple, filter, widget, selection, exclusions, suffix, onSuccessFunction) {
		var pars = 'service=' + Service.LISTER;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'entity=' + entity;
	
		if (label != undefined && label != null && label.length > 0) pars += '&' + 'label=' + label;
		pars += '&' + 'eventHandler=' + eventHandler;
		if (size == undefined || size.length == 0) pars += '&' + 'size=15';
		else pars += '&' + 'size=' + size;
		pars += '&' + 'disabled=false';
		if (multiple != undefined && multiple != null && multiple) pars += '&' + 'multiple=' + multiple;
		if (filter != undefined && filter != null) pars += '&' + filter.serialize();
		if (widget != undefined && widget != null && widget.length > 0) pars += '&' + 'widget=' + widget;
		else pars += '&' + 'widget=' + Widget.LISTER;
		if (selection != undefined && selection != null) pars += '&' + selection.serialize();
		if (exclusions != undefined && exclusions != null) pars += '&' + exclusions.serialize();
		if (suffix != undefined && suffix != null && suffix.length > 0) pars += '&' + 'suffix=' + suffix;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},
	
	remove: function(target, context, entity, label, eventHandler, size, multiple, filter, widget, selection, exclusions, suffix, onSuccessFunction) {
		var pars = 'service=' + Service.LISTER;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'entity=' + entity;
		
		//If a case is selected when remove is clicked the selected case will be removed
		//The case active state will be changed to 0
		if($("cases-lister-entityCase-select")){
			if($("cases-lister-entityCase-select").value!="")
				pars += '&' + 'remove=' + $("cases-lister-entityCase-select").value;
		}
		if (label != undefined && label != null && label.length > 0) pars += '&' + 'label=' + label;
		pars += '&' + 'eventHandler=' + eventHandler;
		if (size == undefined || size.length == 0) pars += '&' + 'size=15';
		else pars += '&' + 'size=' + size;
		pars += '&' + 'disabled=false';
		if (multiple != undefined && multiple != null && multiple) pars += '&' + 'multiple=' + multiple;
		if (filter != undefined && filter != null) pars += '&' + filter.serialize();
		if (widget != undefined && widget != null && widget.length > 0) pars += '&' + 'widget=' + widget;
		else pars += '&' + 'widget=' + Widget.LISTER;
		if (selection != undefined && selection != null) pars += '&' + selection.serialize();
		if (exclusions != undefined && exclusions != null) pars += '&' + exclusions.serialize();
		if (suffix != undefined && suffix != null && suffix.length > 0) pars += '&' + 'suffix=' + suffix;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},
	
	caseSearch: function(target, context, entity, label, eventHandler, size, multiple, filter, widget, selection, exclusions, suffix, onSuccessFunction,closedCase) {
		var pars = 'service=' + Service.LISTER;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'entity=' + entity;
		pars += '&' + 'closed=' + closedCase;
		if (label != undefined && label != null && label.length > 0) pars += '&' + 'label=' + label;
		pars += '&' + 'eventHandler=' + eventHandler;
		if (size == undefined || size.length == 0) pars += '&' + 'size=15';
		else pars += '&' + 'size=' + size;
		pars += '&' + 'disabled=false';
		if (multiple != undefined && multiple != null && multiple) pars += '&' + 'multiple=' + multiple;
		if (filter != undefined && filter != null) pars += '&' + filter.serialize();
		if (widget != undefined && widget != null && widget.length > 0) pars += '&' + 'widget=' + widget;
		else pars += '&' + 'widget=' + Widget.LISTER;
		if (selection != undefined && selection != null) pars += '&' + selection.serialize();
		if (exclusions != undefined && exclusions != null) pars += '&' + exclusions.serialize();
		if (suffix != undefined && suffix != null && suffix.length > 0) pars += '&' + 'suffix=' + suffix;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},
	


	/**
	* Make editor service request
	* @param context the context of the request
	* @param entity the name of the entity being edited
	* @param service the editor service required
	* @param entityID the id of the edited entity - null if creating an entity
	* @param data form data
	* @param subContext optional parameter for entity types with sub-contexts with individual forms
	*/
	editor: function(target, context, entity, service, entityID, data, subContext, widget, onSuccessFunction) {
		var pars = 'service=' + service;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'entity=' + entity;
		pars += '&' + 'disabled=false';
		if (entityID != undefined && entityID != null) pars += '&' + 'entityID=' + entityID;
		if (data != undefined && data != null) pars += '&' + data;
		if (subContext != undefined && subContext != null && subContext.length > 0) pars += '&' + 'subContext=' + subContext;
		if (widget != undefined && widget != null && widget.length > 0) pars += '&' + 'widget=' + widget;
		else pars += '&' + 'widget=' + Widget.EDITOR;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},
	
	duplicate: function(target, context, entity, service, entityID, data, subContext, widget, onSuccessFunction) {
		var pars = 'service=' + service;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'entity=' + entity;
		pars += '&' + 'disabled=false';
		if (entityID != undefined && entityID != null) pars += '&' + 'entityID=' + entityID;
		if (data != undefined && data != null) pars += '&' + data;
		if (subContext != undefined && subContext != null && subContext.length > 0) pars += '&' + 'subContext=' + subContext;
		if (widget != undefined && widget != null && widget.length > 0) pars += '&' + 'widget=' + widget;
		else pars += '&' + 'widget=' + Widget.EDITOR;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.success';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},

	/**
	* Make viewer service request on an entity
	* @param target the target element into which widget XHTML is placed
	* @param context the context in which the viewer is required
	* @param entity the entity type being listed
	* @param entityID the id of the instance being listed
	*/
	viewer: function(target, context, entity, entityID, widget, onSuccessFunction) {
		var pars = 'service=' + Service.VIEWER;
		pars += '&' + 'target=' + target;
		pars += '&' + 'context=' + context;
		pars += '&' + 'entity=' + entity;
		pars += '&' + 'disabled=false';
		if (entityID != undefined) pars += '&' + 'entityID=' + entityID;
		if (widget != undefined && widget != null && widget.length > 0) pars += '&' + 'widget=' + widget;
		else pars += '&' + 'widget=' + Widget.VIEWER;
		if (onSuccessFunction == undefined || onSuccessFunction == null) onSuccessFunction = 'Service.contentSuccess';
		var onFailureFunction = 'Service.failure';
		new Ajax.Request(Service.URL, {parameters:pars, onSuccess:eval(onSuccessFunction), onFailure:eval(onFailureFunction)});
	},
	
	/**
	* Make download request
	* @param member id whose document we want to downlaod
	*/
	download: function(fileName, fileSystem) {
		var pars = 'service=' + Service.DOWNLOAD;
		pars += '&' + 'fileName=' + fileName;
		pars += '&' + 'fileSystem=' + fileSystem;
		document.location = Service.URL + '?' + pars;
	}
}
