/*
 * LICENCE[[
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1/CeCILL 2.O 
 *
 * The contents of this file are subject to the Mozilla Public License Version 
 * 1.1 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ 
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, 
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 
 * for the specific language governing rights and limitations under the 
 * License. 
 * 
 * The Original Code is utc.fr code. 
 * 
 * The Initial Developer of the Original Code is 
 * Universite de Technologie de Compiegne. 
 * 
 * Portions created by the Initial Developer are Copyright (C) 2005 
 * the Initial Developer. All Rights Reserved. 
 * 
 * Contributor(s): 
 * 
 * 
 * Alternatively, the contents of this file may be used under the terms of 
 * either of the GNU General Public License Version 2 or later (the "GPL"), 
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 
 * or the CeCILL Licence Version 2.0 (http://www.cecill.info/licences.en.html), 
 * in which case the provisions of the GPL, the LGPL or the CeCILL are applicable 
 * instead of those above. If you wish to allow use of your version of this file 
 * only under the terms of either the GPL or the LGPL, and not to allow others 
 * to use your version of this file under the terms of the MPL, indicate your 
 * decision by deleting the provisions above and replace them with the notice 
 * and other provisions required by the GPL or the LGPL. If you do not delete 
 * the provisions above, a recipient may use your version of this file under 
 * the terms of any one of the MPL, the GPL, the LGPL or the CeCILL.
 * ]]LICENCE
 */
const WSREGISTRYSERVICE_CONTRACTID = '@scenari.com/wspregistryservice;1';
const WSREGISTRYSERVICE_CID = Components.ID('{7E2B58E8-E168-403E-AD45-1F7CA1255742}');
const WSREGISTRYSERVICE_IID = Components.interfaces.scIWspRegistryService;

const WSP_IID = Components.interfaces.scIWsp;
const WSPOPTIONUI_IID = Components.interfaces.scIWspOptionUi;
const WSPTYPEUI_IID = Components.interfaces.scIWspTypeUi;

const cstPackList = "chrome://scenaricms/content/wspmgr/packlist";

// ###
// # Définition du scWspRegistryService
// #
function scWspRegistryService() {
	this.fFilePath = null;
	this.fFile = null;
	this.fListeners = [];
	this.fListServer = new Object();
	try{
		//initialisation du fichier de config
		var vFolderService = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
		this.fFile = vFolderService.get("ProfD", Components.interfaces.nsIFile);
		//détermination de l'espace de travail dans le profil dédié à cette application (utilisé en mode XPI)
		var vWorkZone = "";
		try{vWorkZone = gPrefs.getCharPref("scenari.profileWorkDirectory");}catch(e){};
		if(vWorkZone!="") this.fFile.append(vWorkZone);
		this.fFile.append("scListeWsp.xml");
		if (!this.fFile.exists()) this.fFile.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0644);

		//chargement du fichier
		var vListConfig = null;
		var vIS = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
		vIS.init(this.fFile,0x01, 00004, null);
		var vSIS = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
		vSIS.init(vIS);
		try{
			var vDomParser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
			vListConfig = vDomParser.parseFromString(vSIS.read(vSIS.available()), "text/xml");
			if(vListConfig.documentElement.nodeName == "parsererror") {
				debug("Echec au parsing du fichier de configuration.");
				this.xSaveConfig();
				vListConfig = this.xGetCurrentDomConfig();
			}
		}catch(e){
			debug("Echec à la lecture du fichier de configuration : "+e);
			this.xSaveConfig();
			vListConfig = this.xGetCurrentDomConfig();
		}

		// construction de la liste des server
		if(vListConfig){
			// si le fichier de config n'est pas null
			var vDefaultUrlLocal = gPrefs.getCharPref("scenari.urlServerLocal");
			var vListServerRead = vListConfig.documentElement.getElementsByTagName('server');
			for(var i=0; i < vListServerRead.length; i++){
				var vServerNode = vListServerRead[i];
				var vUrl = "";
				if(vServerNode.hasAttribute("type") && vServerNode.getAttribute("type")=="local"){
					vUrl = vDefaultUrlLocal;
				}else{
					vUrl = vServerNode.getAttribute("url");
				}
				var vLogin = (vServerNode.hasAttribute("login")) ? vServerNode.getAttribute("login") : null;
				var vPassword = (vServerNode.hasAttribute("password")) ? vServerNode.getAttribute("password") : null;
				var vServer = new Server(vUrl, vServerNode.getAttribute("titre"), vLogin, vPassword);
				this.fListServer[vUrl] = vServer;
				// construction de la liste des wsp de ce server
				var vListWspRead = vServerNode.getElementsByTagName('wsp');
				for(var ii=0; ii < vListWspRead.length; ii++){
					var vWspNode = vListWspRead[ii];
					vServer.addWsp(
						vWspNode.getAttribute("code"),
						vWspNode.getAttribute("comment"),
						vWspNode.getAttribute("actif")=="true"
					);
				}				
			}
		}
	}catch(e){
		debug("sWspRegistryService:xLoadWsp : "+e);
	}	
}



scWspRegistryService.prototype = {
	
	/**
	 * 
	 * 
	 */
	getWsp: function (pUrlServer, pCode){
		var vServer = this.fListServer[pUrlServer];
		if(vServer) {
			return vServer.getWsp(pCode);
		}
		return null;
	},
	
	
	/**
	 * 
	 * 
	 */
	xGetCurrentDomConfig: function (){
		try{
			var vDomDocument = Components.classes["@mozilla.org/xul/xul-document;1"].createInstance(Components.interfaces.nsIDOMDocument);
			//vDomDocument.QueryInterface(Components.interfaces.nsIDOM3Document).xmlVersion = "1.0";
			//var vListeServer = this.fListeServer;
			var vListeWsp=vDomDocument.createElement('listWsp');
				for(var vUrl in this.fListServer){
					var vServer = this.fListServer[vUrl];
					var vServerNode=vDomDocument.createElement('server');
					vServerNode.setAttribute('url', vUrl);
					vServerNode.setAttribute('titre', vServer.fTitle);
					if (vServer.isLocal) vServerNode.setAttribute('type', 'local');
					if (vServer.fLogin) vServerNode.setAttribute('login', vServer.fLogin);
					if (vServer.fPassword) vServerNode.setAttribute('password', vServer.fPassword);
					for(var vCdWsp in vServer.fWsps) {
						var vWsp = vServer.getWsp(vCdWsp);
						var vWspNode = vDomDocument.createElement('wsp');
						vWspNode.setAttribute('code', vCdWsp);
						vWspNode.setAttribute('comment', vWsp.getComment());
						vWspNode.setAttribute('actif', vWsp.isActive());
						vServerNode.appendChild(vWspNode);
					}
					vListeWsp.appendChild(vServerNode);
				}
			vDomDocument.appendChild(vListeWsp);
			return vDomDocument;
		}catch(e){
			debug("sWspRegistryService:xGetCurrentDomConfig (Echec au calcul du dom de config) : "+e);
			return null;
		}	
	},
	
	/**
	 * 
	 * 
	 */
	xSaveConfig: function (){
		try{
			var vOutputStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance( Components.interfaces.nsIFileOutputStream );
			vOutputStream.init(this.fFile, 0x04 | 0x08 | 0x20, 0644, 0 );
			var vDomDocument = this.xGetCurrentDomConfig();
			var vSerializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(Components.interfaces.nsIDOMSerializer);
			var vData = vSerializer.serializeToString(vDomDocument);
			vOutputStream.write(vData, vData.length );
			vOutputStream.close();
			return true;
		}catch(e){
			debug("sWspRegistryService:xSaveConfig (Echec à l'écriture du fichier de configuration) : "+e);
			return false;
		}	
	},
	
	/**
	 * Retourne tous les ateliers actifs.
	 * 
	 */
	getEnabledWsps: function (){
		var vArr = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsICollection);
		for(var vUrlServer in this.fListServer){
			var vServer = this.fListServer[vUrlServer];
			for(var vCdWsp in vServer.fWsps){
				var vWsp = vServer.fWsps[vCdWsp];
				if(vWsp.isActive()) {
					vArr.AppendElement(vWsp.QueryInterface(Components.interfaces.nsISupports));
				}
			}
		}
		return vArr;
	},
	
	/**
	 * Retourne tous les ateliers inactifs.
	 * 
	 */
	getDisabledWsps : function (){
		var vArr = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsICollection);
		for(var vUrlServer in this.fListServer){
			var vServer = this.fListServer[vUrlServer];
			for(var vCdWsp in vServer.fWsps){
				var vWsp = vServer.fWsps[vCdWsp];
				if(!vWsp.isActive()) {
					vArr.AppendElement(vWsp.QueryInterface(Components.interfaces.nsISupports));
				}
			}
		}
		return vArr;
	},
		
	/**
	 * Retourne la liste des ateliers déclarés d'un server (triés dans l'ordre alpha des codes).
	 * 
	 */
	getServerWsps: function (pUrlServer){
		var vArr = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsICollection);
		var vServer = this.fListServer[pUrlServer];
		if(vServer) {
			var vArray = [];
			for(var vCdWsp in vServer.fWsps) vArray.push(vCdWsp);
			vArray.sort(function(p1, p2){return p1.localeCompare(p2);});
			for(var i = 0; i < vArray.length; i++){
				vArr.AppendElement(vServer.fWsps[vArray[i]].QueryInterface(Components.interfaces.nsISupports));
			}
		}
		return vArr;
	},

	/**
	 * Crée et reference un nouveau WSP.
	 */
	addWsp: function (pUrlServer, pCode, pComment, pActive){
		try{
			var vServer = this.fListServer[pUrlServer];
			if( ! vServer) vServer = this.addDataServer(pUrlServer, null);
			var vActif = (pActive!=null) ? pActive : true;
			var vNewWsp = vServer.addWsp(pCode, pComment, vActif);
			this.xSaveConfig();
			this.xFireWspRegEvents("create", pUrlServer, vNewWsp);
			return true;
		}catch (e){
			debug("sWspRegistryService:addWsp (impossible de créer le wsp '"+pCode+"') : "+e);
		}
		return false;
	},
	
	/**
	 * Reference un nouveau Server.
	 */
	addDataServer: function (pUrl, pTitle){
		try{
			var vServer = new Server(pUrl, pTitle);
			if(pUrl in this.fListServer) {
				this.fListServer[pUrl].fTitle = pTitle;
			} else {
				this.fListServer[pUrl] = new Server(pUrl, pTitle);
			}
			this.xSaveConfig();
			this.xFireWspRegEvents("create", pUrl, null);
			return true;
		}catch (e){
			debug("sWspRegistryService:addDataServer (impossbile de créer le server '"+pUrl+"') : "+e);
			return false;
		}
	},
	
	/**
	 * renseigne le titre d'un Server.
	 */
	setTitleServer: function (pUrlServer, pTitle){
		try{
			this.fListServer[pUrlServer].fTitle=pTitle;
			this.xSaveConfig();
			this.xFireWspRegEvents("update", pUrlServer, null);
			return true;
		}catch (e){
			debug("sWspRegistryService:addDataServer (impossbile de créer le server '"+pUrlServer+"') : "+e);
			return false;
		}
	},
	
	/**
	 * renseigne le login/password d'un Server.
	 */
	setServerConnexionSetting: function (pUrlServer, pLogin, pPassword){
		try{
			var vServer = this.fListServer[pUrlServer];
			if( ! vServer) vServer = this.addDataServer(pUrlServer, null);
			var vHttpAuthMgr = Components.classes["@mozilla.org/network/http-auth-manager;1"].getService(Components.interfaces.nsIHttpAuthManager);
			var ioService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
			var vUrl = ioService.newURI(pUrlServer, null, null);
			vServer.setServerConnexion(pLogin, pPassword);
			this.xSaveConfig();
			
			/* La gestion des login/password par nsIHttpAuthManager provoque une exception
			vHttpAuthMgr.setAuthIdentity(vUrl.scheme, vUrl.host, vUrl.port, null, null, null, null, pLogin, pPassword);
			var vDomain = "";
			var vLogin = "";
			var vPassword = "";
			vHttpAuthMgr.getAuthIdentity(vUrl.scheme, vUrl.host, vUrl.port, null, null, null, vDomain, vLogin, vPassword);
			debug("vLogin :: "+vLogin+" , vPassword :: "+vPassword);
			*/
			this.xFireWspRegEvents("update", pUrlServer, null);
			return true;
		}catch (e){
			debug("sWspRegistryService:setServerConnexionSetting (impossible de changer le user/password du server '"+pUrlServer+"') : "+e);
			return false;
		}
	},
	
	/**
	 * renseigne les propriétés titre d'un Wsp.
	 */
	setCommentWsp: function (pUrlServer, pCode, pComment){
		try{
			var vWsp = this.getWsp(pUrlServer, pCode);
			vWsp.setComment(pComment);
			this.xSaveConfig();
			this.xFireWspRegEvents("update", pUrlServer, vWsp);
			return true;
		}catch (e){
			debug("sWspRegistryService:setInfoWsp (impossbile maj le wsp '"+pCode+"') : "+e);
			return false;
		}
	},
	/**
	 * rend actif ou pas un atelier.
	 */
	setActiveWsp: function (pUrlServer, pCode, pActive){
		try{
			var vWsp = this.getWsp(pUrlServer, pCode);
			if(vWsp.isActive()!=pActive){
				vWsp.setActive(pActive);
				this.xSaveConfig();
				this.xFireWspRegEvents("update", pUrlServer, vWsp);
			}
			return true;
		}catch (e){
			debug("sWspRegistryService:setActiveWsp (impossbile maj le wsp '"+pCode+"') : "+e);
			return false;
		}
	},
	
	/**
	 * Supprime un Server.
	 */
	removeDataServer: function (pUrlServer){
		try{
			if(pUrlServer in this.fListServer){
				var vServer  = this.fListServer[pUrlServer];
				var vDataServer = vServer.getDataServer();
				if(vDataServer) vDataServer.quit();
				delete this.fListServer[pUrlServer];
				this.xSaveConfig();
				this.xFireWspRegEvents("remove", pUrlServer, null);
				return true;
			}
			return false;
		}catch (e){
			debug("sWspRegistryService:removeDataServer (Impossible de supprimer le serveur '"+pUrl+"') : "+e);
			return false;
		}
	},
		
	/**
	 *
	 */
	getAllWspRegistry: function (){
		return this.xGetCurrentDomConfig();
	},
	
	/**
	 * Supprime un Atelier.
	 */
	removeWsp: function (pUrlServer, pCode){
		try{
			var vServer = this.fListServer[pUrlServer];
			if(vServer) {
				var vWsp = vServer.removeWsp(pCode);
				if(vWsp) {
					this.xSaveConfig();
					this.xFireWspRegEvents("remove", pUrlServer, vWsp);
					return true;
				}
			}
			return false;
		}catch (e){
			debug("sWspRegistryService:removeWsp (Impossible de supprimer le wsp '"+pCode+"') : "+e);
			return false;
		}
	},
	
	/**
	 * Récupère l'objet scIDataServer d'un URL déclarée dans le wspRegistry.
	 */
	getDataServer: function (pUrl){
		try{
			var vServer = this.fListServer[pUrl];
			if(vServer)	return vServer.getDataServer();
			return null;
		}catch (e){
			debug("sWspRegistryService:getDataServer (Impossible de trouver le server '"+pUrl+"') : "+e);
			return null;
		}
	},
	
	/**
	 * Enregistre un listener sur les modifs du registre des ateliers.
	 * Le listener doit implémenter l'interface "scIWspRegListener".
	 * avec la fonction : 
	 * handleWspRegUpdated(in string pTypeEvent, in string pUrlServer, in scIWsp pWsp)
	 */
	addWspRegListener: function (pListener){
		for(var i = 0; i < this.fListeners.length; i++) {
			if(this.fListeners[i] == pListener) return;
		}
		this.fListeners.push(pListener);
	},

	/**
	 * Elimine un listener sur les modifs du registre des ateliers.
	 */
	removeWspRegListener: function (pListener){
		for(var i = 0; i < this.fListeners.length; i++) {
			if(this.fListeners[i] == pListener) {
				this.fListeners.splice(i, 1);
				break;
			}
		}
		if(this.fListeners.length == 0){
			//Plus d'abonnés, on purge tous les servers.
			for(var vUrl in this.fListServer){
				this.fListServer[vUrl].quit();
			}
		}
	},
	
	fireUpdateEvent: function (pUrlServer, pCodeWsp){
		var vWsp = (pCodeWsp) ? this.getWsp(pUrlServer, pCodeWsp) : null;
		if(vWsp) vWsp.initDef();
		this.xFireWspRegEvents("update", pUrlServer, vWsp);
	},
	
	xFireWspRegEvents: function (pTypeEvent, pUrlServer, pWsp){
		for(var i = 0; i < this.fListeners.length; i++) {
			try{
				this.fListeners[i].handleWspRegUpdated(pTypeEvent, pUrlServer, pWsp);
			}catch(e){
				debug("Echec au traitement d'un handleWspRegUpdated ::"+e);
			}
		}
	},

    QueryInterface: function(pIId) {
        if (!pIId.equals(Components.interfaces.nsISupports) &&
            !pIId.equals(WSREGISTRYSERVICE_IID))
            throw Components.results.NS_ERROR_NO_INTERFACE;
        return this;
    }
};


/**
  * Objet interne Handler du DataServer.
  **/
function Server(pUrl, pTitle, pLogin, pPassword){
	var vDefaultUrlLocal = gPrefs.getCharPref("scenari.urlServerLocal").length>0 ? gPrefs.getCharPref("scenari.urlServerLocal") : null;
	this.fIniUrl = pUrl;
	this.isLocal = false;
	if(vDefaultUrlLocal && pUrl.indexOf(vDefaultUrlLocal)==0) this.isLocal = true;
	if(pTitle && pTitle!=""){
		this.fTitle = pTitle;
	}else if(this.isLocal){
		this.fTitle = "Ateliers locaux";
	}else{
		this.fTitle = pUrl;
	}
	this.fDataServer = null;
	this.fLogin = pLogin;
	this.fPassword = pPassword;
	this.fWsps = {};
}

Server.prototype.clearDataServer = function(){
	if(this.fDataServer!=null){
		this.fDataServer.quit();
		this.fDataServer = null;
	}
}

Server.prototype.setServerConnexion = function(pLogin, pPassword){
	try{
		this.fLogin = pLogin;
		this.fPassword = pPassword;
		var vDataServer = this.getDataServer();
		vDataServer.setUser(pLogin, pPassword);
	}catch (e){
		debug("Server.prototype.setServerConnexion : " + e);
	}
}

Server.prototype.getDataServer = function(){
	if(this.fDataServer==null) {
		try{
			this.fDataServer = Components.classes["@scenari.com/httpdataserver;1"].createInstance(Components.interfaces.scIDataServer);
			//debug("create new Server ! : "+this.fIniUrl);
			//this.fDataServer = new scHttpDataServer();
			this.fDataServer.init(this.fIniUrl, null, this.fLogin, this.fPassword);
		}catch (e){
			//debug("sWspRegistryService:getDataServer (Impossible de créer le serveur '"+this.fIniUrl+"') : "+e);
			this.fDataServer = null;
		}
	}
	//debug("Server.prototype.getDataServer::"+this.fDataServer.getIniUrl()+" local="+this.fDataServer.isServerLocal());
	return this.fDataServer;
}
Server.prototype.quit = function(){
	if(this.fDataServer) {
		this.fDataServer.quit();
		this.fDataServer = null;
	}
}
Server.prototype.getWsp = function(pCode) {
	return this.fWsps[pCode];
}
Server.prototype.addWsp = function(pCode, pComment, pActive){
	var vNewWsp = new scWsp(this, pCode, pComment, pActive);
	this.fWsps[pCode] = vNewWsp;
	return vNewWsp;
}
Server.prototype.removeWsp = function(pCdWsp){
	var vWsp = this.fWsps[pCdWsp];
	if(vWsp) delete this.fWsps[pCdWsp];
	return vWsp;
}


/**
  * Définition du scWsp
  **/
function scWsp(pServer, pCode, pComment, pActive) {
	this.fServer=pServer;
	this.fCode=pCode;
	this.fComment=pComment;
	this.fActive=pActive;
	this.fWspType=null;
	this.fWspTypeUi = null;
	this.fWspOptionUiCollection = null;
}
scWsp.prototype = {
	
	/**
	 * Retourne le code de cet atelier (vu par le serveur).
	 * 
	 */
	getCode: function(){
		return this.fCode;
	},
	/**
	 * Retourne le server de données de cet atelier.
	 * 
	 */
	getServer: function(){
		return this.fServer.getDataServer();
	},
	/**
	 * Retourne l'url du server de données de cet atelier.
	 * 
	 */
	getUrlServer: function(){
		return this.fServer.fIniUrl;
	},
	/**
	 * Retourne le titre du serveur.
	 * 
	 */
	getTitleServer: function(){
		return this.fServer.fTitle;
	},
	/**
	 * Retourne le commentaire stocké au niveau du profil utilisateur.
	 * 
	 */
	getComment: function(){
		return this.fComment;
	},
	/**
	 * wsp actif/inactif
	 */
	isActive: function(){
		return this.fActive;
	},
	/**
	 * Retourne l'objet wspTypeUi
	 */
	getWspTypeUi: function(){
		try{
			if(this.fWspTypeUi){
				return this.fWspTypeUi;
			}else{
				if(this.getWspType()){
					var vWspTypeUri = this.getWspType().getAttribute("uri");
					var vXULOverlayProvider = Components.classes["@mozilla.org/chrome/chrome-registry;1"].getService(Components.interfaces.nsIXULOverlayProvider);
					var vIoService 	= Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
					var vUri 		= vIoService.newURI(cstPackList, null, null);							
					var vOverlayList= vXULOverlayProvider.getXULOverlays(vUri);
					while(vOverlayList.hasMoreElements()){//Pour tous les packs déclarés...
						var vUriPack = vOverlayList.getNext().QueryInterface(Components.interfaces.nsIURI);
						var vPackDom = getDomFromLocalFileUrl(vUriPack.spec);
						if(vPackDom){
							var vWspTypeUiList 	= vPackDom.getElementsByTagName('wspTypeUi');
							var vWspTypeUi		= vWspTypeUiList.length>0 ? vWspTypeUiList[0] : null;
							if(vWspTypeUi && vWspTypeUi.hasAttribute('uri') && vWspTypeUi.getAttribute('uri')==vWspTypeUri){
								var vComponent = vWspTypeUi.getAttribute('component');
								if(vComponent && Components.classes[vComponent]){
									var vUi = Components.classes[vComponent].createInstance(Components.interfaces.scIWspTypeUi);
									vUi.init(vWspTypeUi);
									this.fWspTypeUi = vUi;
									return vUi;
								}else{
									debug("getWspTypeUi : impossible d'instancier le component '" + vComponent + "' du wspType '" + vWspTypeUri + "'. Vérifier @component dans wspTypeUi.");
								}
							}
						}
					}
				}
			}
			return null;
		}catch(e){
			debug("scWsp > getWspTypeUi :: " + e);
			return null;
		}
	},
	/**
	 * Retourne une collection d'objets scIWspOptionUi
	 */
	getWspOptionUiList: function(){
		try{
			if(this.fWspOptionUiCollection){
				return this.fWspOptionUiCollection.QueryInterface(Components.interfaces.nsICollection);
			}else{
				if(this.getWspType()){
					var vOptionList = this.getWspType().getElementsByTagName("wspOption");
					var vOptionListArray = new Array();
					for(var ii=0; ii<vOptionList.length; ii++) {
						vOptionListArray[vOptionList[ii].getAttribute('uri')] = vOptionList[ii];
					}
					
					if(vOptionList.length>0){// si il y a des options pour lesquels on recherche le wspOptionUi
						var vOptionUiCollection = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsICollection);
						var vXULOverlayProvider = Components.classes["@mozilla.org/chrome/chrome-registry;1"].getService(Components.interfaces.nsIXULOverlayProvider);
						var vIoService 			= Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
						var vUri 				= vIoService.newURI(cstPackList, null, null);							
						var vOverlayList		= vXULOverlayProvider.getXULOverlays(vUri);
						
						while(vOverlayList.hasMoreElements()){//Pour tous les packs déclarés...
							var vUriPack = vOverlayList.getNext().QueryInterface(Components.interfaces.nsIURI);
							var vPackDom = getDomFromLocalFileUrl(vUriPack.spec);
							if(vPackDom){
								var vWspOptionUiList = vPackDom.getElementsByTagName('wspOptionUi');
								for(var ii=0; ii<vWspOptionUiList.length; ii++) {
									if(vWspOptionUiList[ii].hasAttribute('uri') && vWspOptionUiList[ii].getAttribute('uri') in vOptionListArray){
										var vComponent = vWspOptionUiList[ii].getAttribute('component');
										if(vComponent && Components.classes[vComponent]){
											var vUi = Components.classes[vComponent].createInstance(Components.interfaces.scIWspOptionUi);
											vUi.init(vWspOptionUiList[ii]);
											vOptionUiCollection.AppendElement(vUi);
										}else{
											debug("getWspOptionUi : impossible d'instancier le component '" + vComponent + "' du wspOption '" + vWspOptionUiList[ii].getAttribute('uri') + "'. Vérifier @component dans wspOptionUi.");
										}
									}
								}
							}
						}
						this.fWspOptionUiCollection = vOptionUiCollection;
						return vOptionUiCollection;
					}
				}
			}
			return null;
		}catch(e){
			debug("scWsp > getWspOptionUiList :: " + e);
			return null;
		}
	},
	/**
	 * Internes
	 */
	initDef: function(){
		// réinitialisation des objets de ce wsp
		this.fWspType = null;
		this.fWspTypeUi = null;
		this.fWspOptionUiCollection = null;
	},
	setActive: function(pActive){
		this.fActive=pActive;
	},
	setComment: function(pComment){
		if(pComment!=null) this.fComment=pComment;
	},
	getWspType: function(){
		try{
			if(this.fWspType){
				return this.fWspType;
			}else{
				if(this.getServer().isServerReady()){
					//interroge le serveur pour obtenir le wspType
					var vInfoWsp = this.getServer().getDomFromService("/u/adminWsp?cdaction=InfoWsp&param=" + this.getCode());
					if(vInfoWsp && vInfoWsp.documentElement) {
						var vStatus = vInfoWsp.documentElement.getAttribute('status');
						if(vStatus=="ok"){
							var vWspType = vInfoWsp.documentElement.getElementsByTagName("wspType")[0];
							this.fWspType = vWspType;
							return vWspType;
						}
					}
				}
			}
			return null;
		}catch(e){
			debug("scWsp > getWspType :: " + e);
			return null;
		}
	},
    QueryInterface: function(pIId) {
        if (!pIId.equals(Components.interfaces.nsISupports) &&
            !pIId.equals(WSP_IID))
            throw Components.results.NS_ERROR_NO_INTERFACE;
        return this;
    }
};


/**
  * fctions internes
  **/
function debug(pText) {
	var vConsoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
	vConsoleService.logStringMessage(pText);
}

function getDomFromLocalFileUrl(pUrl) {
	try{
		var vIoService = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
		var vChannel = vIoService.newChannel(pUrl,null,null);
		var vInput = vChannel.open();
		try {
			var vBuf = Components.classes["@mozilla.org/network/buffered-input-stream;1"].createInstance(Components.interfaces.nsIBufferedInputStream);
			vBuf.init(vInput, vChannel.contentLength);
			var vParser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
			return vParser.parseFromStream(vBuf, null, vChannel.contentLength, "text/xml");
		} finally {
			vInput.close();
		}
	}catch(e){
		debug("Impossible de parser le fichier de l'URL : '"+pUrl+"': "+e);
		return null;
	}
}

function listProperties(pObj){
	var vRes = "";
	var vProp = null;
	for (vProp in pObj) {
		try {
			vRes += vProp +'(' + pObj[vProp]+ ')'+ "\n";
		} catch(e){
			vRes += vProp +' -> toString in error\n';
		}
	}
	return vRes;
}

function getXml(pElement){
	var vSerializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(Components.interfaces.nsIDOMSerializer);
	return pElement ? vSerializer.serializeToString(pElement) : "";
}

gPrefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);


/**
  * Module
  **/
var sModule = {
    registerSelf: function(compMgr, fileSpec, location, type) {
        compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);

        compMgr.registerFactoryLocation(WSREGISTRYSERVICE_CID, 
                                        "scWspRegistryService JS component", 
                                        WSREGISTRYSERVICE_CONTRACTID, 
                                        fileSpec, 
                                        location,
                                        type);
    },

    getClassObject: function(compMgr, cid, iid) {
        if (!cid.equals(WSREGISTRYSERVICE_CID))
            throw Components.results.NS_ERROR_NO_INTERFACE;

        if (!iid.equals(Components.interfaces.nsIFactory))
            throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

        return sWspRegFactory;
    },

    canUnload: function(compMgr) { return true; }
};

var sWspRegFactory = {
    createInstance: function(outer, iid) {
        if (outer != null)
            throw Components.results.NS_ERROR_NO_AGGREGATION;
    
        if (!iid.equals(WSREGISTRYSERVICE_IID) &&
            !iid.equals(Components.interfaces.nsISupports))
            throw Components.results.NS_ERROR_INVALID_ARG;

        return new scWspRegistryService();
    }
}

/** Module initialisation */
function NSGetModule(comMgr, fileSpec) { return sModule; }

