/**
* Represents the parent class for entity types even though no formal inheritance can be declared.
* Methods for making requests for entity services and handling the responses.
*/

var Entity = {

	// Entity types. Keep synchronised with the list in Entity.php
	QACASE: 'Qacase',
	TASK: 'task',
	APEL: 'apel',
	
	EA: 'ea',
	EATYPE: 'eaType',
	EAORGANISATION: 'eaOrganisation',
	CASE: 'case',
	COMPLAINT: 'complaint',
	SURVEY: 'survey',
	
	USER: 'user',
	USERTYPE: 'userType',
	NOTE: 'note',
	ACTION: 'action',
	ACTIONTYPE: 'actionType',
	// Generic entity used for complex filters that depend on the entity type rather than a type instances. For example
	// filtering product and category descriptors of a collection instance
	ENTITY: 'entity',

	handleEvent: function(event, context, entity) {
		var element = Event.element(event);
			
		if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'edit')) {
			Entity.edit(context, entity);
			return;
		} else if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'remove')) {
			Entity.remove(context, entity);
			return;
		} else if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'save')) {
			Entity.save(context, entity);
			return;
		} else if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'cancel')) {
			Entity.cancel(context, entity);
			return;
		} else if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'close')) {
			Entity.closeEditor(context, entity);
			return;
		} else if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'clear')) {
			Entity.clearEditor(context, entity);
			return;
		} else if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'actions')) {
			Entity.actions(context, entity);
			return;
		} else if (element.id.endsWith(Service.SCOPE_SEPARATOR + 'notes')) {
			Entity.notes(context, entity);
			return;
		} else {
			// Test for a click on RTE generated content so we invoke the editor
			if (element.tagName == 'DIV' && element.id.endsWith(Service.SCOPE_SEPARATOR + 'invoke_rte')){
				Entity.rte(element.id, context, entity);
				return;
			} else {
				var ancestors = element.ancestors();
				for (i = 0; i < ancestors.length; i++) {
					if (ancestors[i].tagName == 'DIV' && ancestors[i].id.endsWith(Service.SCOPE_SEPARATOR + 'invoke_rte')){
						Entity.rte(ancestors[i].id, context, entity);
						return;
					}
				}
			}
		}
		// Try for entity type handling
		try {
			Case.handleEvent(event, context);
		} catch(err) {}
		return;
	},


	/**
	* Get an entity ID for editing by getting the value in the viewer hidden id field for context and entity
	*/
	getEntityID: function(context, entity){
		try {
			var idElement = context + Service.SCOPE_SEPARATOR + Widget.VIEWER + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'id';
			return $F(idElement);
		} catch (err) {
			try {
				var idElement = context + Service.SCOPE_SEPARATOR + Widget.EDITOR + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'id';
				return $F(idElement);
			} catch (err) {
				// Must be creating
				return -1;
			}
		}
	},

	/**
	* Called before edit or create in order to control the display of notes and actions
	*/
	prepare: function(context) {
		return;
	},
	
	/**
	* Handle display of notes panel
	*/
	notes: function(context, entity) {
		var notesContext = context + '_notes';
		var closed = ($(notesContext).getStyle('display') == 'none');
		if (!closed) {
			if(dirty.getDirty(notesContext) != undefined) {
				var answer = false;
				var dirtyID = dirty.getDirty(notesContext);
				if (dirtyID > 0) answer = Entity.cancel(notesContext, Entity.NOTE);
				else answer = Entity.closeEditor(notesContext, Entity.NOTE);
				if (!answer) return;
			}
		}
		$(notesContext).toggle();
		var relatedEntityField = notesContext + Service.SCOPE_SEPARATOR + 'entity';
		var relatedEntity = $(relatedEntityField).value;
		var relatedEntityIDField = notesContext + Service.SCOPE_SEPARATOR + 'instanceID';
		var relatedEntityID = $(relatedEntityIDField).value;
  		var filter = new ListFilter(relatedEntity, relatedEntityID);
		//var entityIDField = notesContext + Service.SCOPE_SEPARATOR + 'instanceID';
		//var entityID = $(entityIDField).value;
		//var filter = new ListFilter(entity, entityID);
		Entity.refreshList(notesContext, Entity.NOTE, null, false, null, filter);
	},
	
	/**
	* Handle display of actions panel
	*/
	actions: function(context, entity) {
		var actionsContext = context + '_actions';
		var closed = ($(actionsContext).getStyle('display') == 'none');
		if (!closed) {
			if(dirty.getDirty(actionsContext) != undefined) {
				var answer = false;
				var dirtyID = dirty.getDirty(actionsContext);
				if (dirtyID > 0) answer = Entity.cancel(actionsContext, Entity.ACTION);
				else answer = Entity.closeEditor(actionsContext, Entity.ACTION);
				if (!answer) return;
			}
		}
		$(actionsContext).toggle();
		var relatedEntityField = actionsContext + Service.SCOPE_SEPARATOR + 'entity';
		var relatedEntity = $(relatedEntityField).value;
		var relatedEntityIDField = actionsContext + Service.SCOPE_SEPARATOR + 'instanceID';
		var relatedEntityID = $(relatedEntityIDField).value;
  		var filter = new ListFilter(relatedEntity, relatedEntityID);
		//var entityID = Entity.getEntityID(context, entity);
		//var filter = new ListFilter(entity, entityID);
		Entity.refreshList(actionsContext, Entity.ACTION, null, false, null, filter);
	},


	rte: function(target, context, entity) {
		// Get the hidden field which has the same ID as the div but without the -rte suffix
		// This field contains the text
		var parts = target.split(Service.SCOPE_SEPARATOR);
		var temp = parts.pop();
		var dataFieldID = parts.join(Service.SCOPE_SEPARATOR);
		var oFCKeditor = new FCKeditor(dataFieldID + Service.SCOPE_SEPARATOR + 'rte', '200px');
		oFCKeditor.BasePath = 'js/FCKeditor/';
		oFCKeditor.Value = $(dataFieldID).value;
		$(target).update(oFCKeditor.CreateHtml());
	},

	save: function(context, entity, validate) {
		// If we are dealing with products then we need to set the context to the active tab
		var subContext = '';
	
		document.body.style.cursor = 'wait';

		if (validate == undefined || validate == null || validate == true) {
			// Call the entity type's validation method
			try {
				
				var call = entity.ucFirst() + '.validate(\'' + context + '\')';
				var message = eval(call);
				if (message.length > 0) {
					document.body.style.cursor = '';
					alert(message);
					return;
				}
			} catch(err) {
				document.body.style.cursor = '';
				alert('error validating form data for: ' + entity + ' ' + err);
				return;
			}
		}
		
		var target = context + Service.SCOPE_SEPARATOR + entity;

		// Deal with any FCK editors
		try {
		
			var textInputElements = new Array();
			if (entity == Entity.PRODUCT) textInputElements = $(subContext + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'form').getInputs();
			else textInputElements = $(context + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'form').getInputs();
			for (i = 0; i < textInputElements.length; i++) {
				if (FCKeditorAPI.GetInstance(textInputElements[i].id) != null) {
				//alert(textInputElements[i].id)
					var parts = textInputElements[i].id.split(Service.SCOPE_SEPARATOR);
					var temp = parts.pop();
					var dataFieldID = parts.join(Service.SCOPE_SEPARATOR);
					$(dataFieldID).value = FCKeditorAPI.GetInstance(textInputElements[i].id).GetXHTML();
				}
			}
		} catch(err){;}
		var data = '';
		if (entity == Entity.USER) {
			
			// Special case for user because we need to encrypt the password field
			data = User.getData(context, entity);
		} else {
			data = $(context + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'form').serialize();				
			
			
			try {
				var call = entity.ucFirst() + '.getData(\'' + context + '\',\'' + entity + '\')';
				data += eval(call);
			} catch(err) {
				document.body.style.cursor = '';
			}
		}
		Service.editor(target, context, entity, Service.EDITOR_SAVE, null, data, subContext);
	},

	cancel: function(context, entity) {
		var answer = confirm('Your ' + entity.ucFirst() + ' may have unsaved changes, do you wish to continue?');
		if (answer) {
			document.body.style.cursor = 'wait';
			var target = context + Service.SCOPE_SEPARATOR + entity;
			var idElement = context + Service.SCOPE_SEPARATOR + Widget.EDITOR + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'id';
			var entityID = $F(idElement);
			Service.editor(target, context, entity, Service.EDITOR_CANCEL, entityID, null);
		}
		return answer;
	},

	remove: function(context, entity, onSuccessFunction, onFailureFunction){
		var answer = confirm('Confirm Remove of ' + entity.ucFirst());
		if (answer) {
			document.body.style.cursor = 'wait';
			var entityID = Entity.getEntityID(context, entity);
			if (entityID == -1) {
				Entity.removeFailure();
				return;
			}
			var target = context + Service.SCOPE_SEPARATOR + entity;
			Service.editor(target, context, entity, Service.EDITOR_REMOVE, entityID, null);
		}
	},

	create: function(context, entity){
		// To support notes and actions need to a pre-call method to test for dirty notes or actions
		Entity.prepare(context);
		if(dirty.getDirty(context) != undefined){
		
			var answer = false;
			var dirtyID = dirty.getDirty(context);
			if (dirtyID > 0) answer = Entity.cancel(context, entity);
			else answer = Entity.closeEditor(context, entity);
			if (!answer) return;
		}
		Entity.clearLister(context, entity);
		Entity.closeViewer(context, entity);
		var target = context + Service.SCOPE_SEPARATOR + entity;
		Service.editor(target, context, entity, Service.EDITOR_CREATE, null, null);
	},

	edit: function(context, entity, entityID, refresh){
		// To support notes and actions need to a pre-call method to test for dirty notes or actions
		Entity.prepare(context);
		if (entityID == undefined || entityID == null || entityID.length == 0) {
			entityID = Entity.getEntityID(context, entity);
			if (entityID == -1) {
				alert('Please make a selection');
				return;
			}
		}
		var target = context + Service.SCOPE_SEPARATOR + entity;
		var service = Service.EDITOR_EDIT;
		if (refresh != undefined && refresh != null && refresh == true) service = Service.EDITOR_REFRESH;
		Service.editor(target, context, entity, service, entityID, null);
	},

	view: function(context, entity, elementID, entityID, profileID){
		// Handle product sub-tabs
		if(dirty.getDirty(context) != undefined){
			var answer = false;
			var dirtyID = dirty.getDirty(context);
			if (dirtyID > 0) answer = Entity.cancel(context, entity);
			else answer = Entity.closeEditor(context, entity);
			if (!answer) {
				var selection = null;
				if (dirtyID > 0)var selection = new Selection(entity, dirtyID);
				Entity.list(context, entity, null, selection);
				return;
			}
		}
		var target = context + Service.SCOPE_SEPARATOR + entity;
		if (entityID == undefined || entityID == null) {
			var selectedID = $(elementID).value;
			var parts = selectedID.split(Service.SCOPE_SEPARATOR);
			entityID = parts[parts.length - 1];
		}
		Service.viewer(target, context, entity, entityID, profileID);
	},

	list: function(context, entity, eventHandler, selection, filter, size) {
		var target = context + Service.SCOPE_SEPARATOR + Widget.LISTER + Service.SCOPE_SEPARATOR + entity;
		if (eventHandler == undefined || eventHandler == null || eventHandler.length == 0) eventHandler = 'Entity.view(\'' + context + '\',\'' + entity + '\',\'@id\')';
		Service.lister(target, context, entity, null, eventHandler, size, '', filter, null, selection);
	},

	/**
	* Refresh listing of entity type in context
	*/
	refreshList: function(context, entity, eventHandler, suppressDirty, selection, filter) {
		if(dirty.getDirty(context) != undefined && suppressDirty == undefined){
			var answer = false;
			var dirtyID = dirty.getDirty(context);
			if (dirtyID > 0) answer = Entity.cancel(context, entity);
			else answer = Entity.closeEditor(context, entity);
			if (!answer) return;
		}
		Entity.list(context, entity, eventHandler, selection, filter);
		Entity.closeViewer(context, entity);
	},

	cancelEditor: function(context, entity) {
		var elementID = context + Service.SCOPE_SEPARATOR + Widget.LISTER + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'select';
		Entity.view(context, entity, elementID);
		try {
			Note.refreshPanel(context);
		}catch(err){;}
		try {
			Action.refreshPanel(context);
		}catch(err){;}
	},

	clearEditor: function(context, entity) {
		var textInputs = $(context + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'form').getInputs('text');
		for (i = 0; i < textInputs.length; i++) {
			textInputs[i].value = '';
		}
	},

	closeEditor: function(context, entity) {
		var answer = confirm('Your ' + entity.ucFirst() + ' may have unsaved changes, do you wish to continue?');
		if (answer) {
			dirty.remove(context);
			var target = context + Service.SCOPE_SEPARATOR +  entity;
			$(target).update('');
			try {
				target = context + Service.SCOPE_SEPARATOR + 'buttons' + Service.SCOPE_SEPARATOR +  entity;
				$(target).update('');
			} catch(err) {;}
			// Call the entity type
			try {
				var call = entity.ucFirst() + '.closeEditor(\'' + context + '\')';
				eval(call);
			} catch(err) {;}
		}
		return answer;
	},

	closeViewer: function(context, entity) {
		try {
			var target = context + Service.SCOPE_SEPARATOR + entity;
			$(target).update('');
			var target = context + Service.SCOPE_SEPARATOR + Service.BUTTONS + Service.SCOPE_SEPARATOR + entity;
			$(target).update('');
		}catch(err){;}
		// Call the entity type
		try {
			var call = entity.ucFirst() + '.closeViewer(\'' + context + '\')';
			eval(call);
		} catch(err) {}
	},

	clearLister: function(context, entity) {
		try {
			var elementID = context + Service.SCOPE_SEPARATOR + Widget.LISTER + Service.SCOPE_SEPARATOR + entity + Service.SCOPE_SEPARATOR + 'select';
			var descendants = $(elementID).descendants();
			for (j = 0; j < descendants.length; j++) {
				if ($(descendants[j]).tagName == 'OPTION') {
					$(descendants[j]).selected = '';
				}
			}
		} catch(err) {return;}
	},
	serialiseFormData: function(formID){
		var data ="";
		try{
			var inputElements = $(formID).getInputs();
			for (i = 0; i < inputElements.length; i++) {
				var id = inputElements[i].id;
				if ($(id).type=="checkbox"){
					if($(id).checked){
						data += '&' + id +"=1";
					}
					else{
						data += '&' + id +"=0";
					}
				}
				else if ($(id).type=="select"){
					var options = $(id).getElementsByTagName('option');
					for(m = 0; m < options[m].length; m++){
						data += '&'+id+'='+options[m].selected;
					}
					
					data += '&' + id +'='+$(id).checked;
				}
				else{
					data += '&' + id +'='+encodeURIComponent($(id).value);
				}
			}
			
			var inputElements = $(formID).getElementsByTagName('select');
			for (i = 0; i < inputElements.length; i++) {
				id = inputElements[i].id;
				
				var options = $(id).getElementsByTagName('option');
				for (m = 0; m < options.length; m++) {
					if(options[m].selected){
						data += '&' + id +'_'+options[m].value+'=1';
					}
					else{
						data += '&' + id +'_'+options[m].value+'=0';
					}
				}
			}
			var inputElements = $(formID).getElementsByTagName('textarea');
			for (i = 0; i < inputElements.length; i++) {
				id = inputElements[i].id;
				data += '&' + id +'='+encodeURIComponent(inputElements[i].value);
					
				
			}
			
			
		}catch(err) { return "";}
		return data;
	}

}

