/**
 * The "service" object (also called "widget") is a single object used by CARGO Library.
 * It contains utility function for setting up CARGO widget (service).
 * @title  CARGO
 * @module service
 * @author Jose Manuel Rodriguez CNIO-INB (jmrodriguez@cnio.es)
 * @version 2.0
 */

/**
 * service is an abstract base class. It is defined by means of
 * widget (service) description given as xml document.
 * @constructor
 * @param {Integer} iServiceId Service identifier
 * @param {XMLElement} oServiceElement Service description
 */
function service(iServiceId, oServiceElement)
{
	this.id = iServiceId;
	this._getServiceProperties(oServiceElement); // Add service properties
};

service.prototype = {

/* ATTRIBUTES */

	/**
	* Instance of cargo object
	* @type Object
	*/
	cargo: null,
	/**
	* Unique identifier of service
	* @type Integer
	*/
	id: null,
	/**
	* Name of service
	* @type String
	*/
	name: null,
	/**
	* Description of service
	* @type String
	*/
	description: null,
	/**
	* URL of service
	* @type String
	*/
	url: null,
	/**
	* List of service types
	* @type Array
	*/
	types: null,
	/**
	* "Relative" path where icon file of service is located
	* @type String
	*/
	icon: null,
	/**
	* List of namespaces used as input.
	* The structure of namespace list is:
	* [
	*  {
	*    name: "namespace",
	*    uri: "uri of namespace"
	*  }...
	* ]
	* @type Array
	*/
	namespaces: null,
	/**
	* Default width of widget window
	* @type Integer
	*/
	windowWidth: 300,
	/**
	* Default height of widget window
	* @type Integer
	*/
	windowHeight: 300,
	/**
	* Providers who has developed the service
	* @type Array
	*/
	providers: null,
	/**
	* List of instances of widget for each window
	* @type Object
	*/
	widgets: null,

/* Private METHODS */

	/**
	* Add the properties of service object.
	* @private
	* @param {XMLElement} oServiceElem Service description
	*/
	_getServiceProperties: function (oServiceElem)
	{
		var oConstant = new constant();
		var sPrefix_wi = oConstant.xmlNamespaces['widgetList'].p;
		var sPrefix_ty = oConstant.xmlNamespaces['typeList'].p;
		var sPrefix_ns = oConstant.xmlNamespaces['namespaceList'].p;
		var sPrefix_pro = oConstant.xmlNamespaces['providerList'].p;


		this.name = Sarissa.getText(oServiceElem.selectSingleNode(sPrefix_wi+":name"));
		this.description = Sarissa.getText(oServiceElem.selectSingleNode(sPrefix_wi+":description"));
		this.url = Sarissa.getText(oServiceElem.selectSingleNode(sPrefix_wi+":url"));

		var sDoc = Sarissa.getText(oServiceElem.selectSingleNode(sPrefix_wi+":documentation")); // Optional field
		if ((sDoc != null) && (sDoc != 'NULL')) { this.documentation = sDoc; };

		var sIcon = Sarissa.getText(oServiceElem.selectSingleNode(sPrefix_wi+":icon")); // Optional field
		if ((sIcon != null) && (sIcon != 'NULL')) { this.icon = sIcon; };
	
		var sWidth = Sarissa.getText(oServiceElem.selectSingleNode(sPrefix_wi+":window/"+sPrefix_wi+":width")); // Optional field
		if ((sWidth != null) && (sWidth != 'NULL')) { this.windowWidth = parseInt(sWidth); };
	
		var sHeight = Sarissa.getText(oServiceElem.selectSingleNode(sPrefix_wi+":window/"+sPrefix_wi+":height")); // Optional field
		if ((sHeight != null) && (sHeight != 'NULL')) { this.windowHeight = parseInt(sHeight); };

		var aTypes = new Array();
		var oNodeList = oServiceElem.selectNodes(
							sPrefix_ty+":typeList/"+
							sPrefix_ty+":type"
		);
		if (oNodeList.length > 0) { // There were some error
			for (var iIndex = 0; iIndex < oNodeList.length; iIndex++) {
				var oType = {
						name: Sarissa.getText(oNodeList[iIndex].selectSingleNode(sPrefix_ty+":name"))
				};
				aTypes.push(oType);
			}
		}
		this.types = aTypes;

		var aTakenNS = new Array();
		var oNodeList = oServiceElem.selectNodes(
							sPrefix_wi+":inputNamespaceList/"+
							sPrefix_ns+":namespaceList/"+
							sPrefix_ns+":namespace"
		);
		if (oNodeList.length > 0) { // There were some error
			for (var iIndex = 0; iIndex < oNodeList.length; iIndex++) {
				var oNamespace = {
						id: Sarissa.getText(oNodeList[iIndex].selectSingleNode("@id"))
				};
				aTakenNS.push(oNamespace);
			}
		}
		this.namespaces = aTakenNS;

		var aProviders = new Array();
		var oNodeList = oServiceElem.selectNodes(
							sPrefix_pro+":providerList/"+
							sPrefix_pro+":provider"
		);
		if (oNodeList.length > 0) { // There were some error
			for (var iIndex = 0; iIndex < oNodeList.length; iIndex++) {
				var oProvider = {
						name: Sarissa.getText(oNodeList[iIndex].selectSingleNode(sPrefix_pro+":name")),
						email: Sarissa.getText(oNodeList[iIndex].selectSingleNode(sPrefix_pro+":email")),
						organization: Sarissa.getText(oNodeList[iIndex].selectSingleNode(sPrefix_pro+":organization")),
						orglink: Sarissa.getText(oNodeList[iIndex].selectSingleNode(sPrefix_pro+":orglink"))
				};
				aProviders.push(oProvider);
			}
		}
		this.providers = aProviders;
	},

/* Public METHODS */

	/**
	* Give the list of namespaces that the service accepts as input.
	* The structure of namespace list is:
	* [
	*  {
	*    name: "namespace",
	*    uri: "uri of namespace"
	*  }...
	* ]
	* @return {Array} aNamespace List of namespaces
	*/
	getNamespaces: function ()
	{
		return this.namespaces;
	},
	/**
	* Return true if widget (service) accepts the given namespace as input.
	* Otherwise, return false.
	* @param {String} sNamespace Namespace
	* @return {Boolean} bAccept Boolean value (true, false)
	*/
	acceptGivenNamespace: function (sNamespace)
	{
		for (var iIndex = 0; iIndex < this.namespaces.length; iIndex++)
		{
			if (this.namespaces[iIndex].id == sNamespace) { return true; };
		}
		return false;
	},
	/**
	* Reload all widget windows of this service that are loaded inside of dashboard.
	* @param {String} sNamespace Namespace
	* @param {String} sId Id of input
	*/
	reloadAllWidgets: function (sNamespace, sId)
	{
		for (var iIndex = 0; iIndex < this.widgets.length; iIndex++)
		{
			if (this.widgets[iIndex])
			{
				this.widgets[iIndex].reloadMainFunction(this.url + "?" + sNamespace + "=" + sId);
			}
		}
	},
	/**
	* Reload widget window from its name window
	* @param {String} sCargoTicket Cargo Ticket
	* @param {String} sWWidgetName Name of widget window
	* @param {String} sNamespace Namespace
	* @param {String} sId Id of input
	*/
	reloadWidget: function (sCargoTicket, sWWidgetName, sNamespace, sId)
	{
		for (var iIndex = 0; iIndex < this.widgets.length; iIndex++)
		{
			if (this.widgets[iIndex] && (this.widgets[iIndex].name == sWWidgetName))
			{
				this.widgets[iIndex].reloadMainFunction(this.url+"?"+"cargo_ticket="+sCargoTicket+"&widget_name="+sWWidgetName+"&"+sNamespace+"="+sId);
			}
		}
	}
};
