/**
 * oeevbf.user.js
 * Copyright (c) 2009-2010 pict-hordes.com
 * Released under the GPL license
 * 
 * @version		1.1
 * @author		darksolune <darksolune@hotmail.com>
 * @link		http://www.oeev-hordes.com
 * @license		http://www.gnu.org/copyleft/gpl.html GNU General Public License
 * @charset		UTF-8
 */

// ==UserScript==
// @name			OeevBestFriend
// @namespace		http://www.oeev-hordes.com
// @description		Enrichi l'interface de hordes.fr afin d'avoir des liens vers "Où en êtes-vous ?", Pict'Hordes et Patamap
// @include			http://www.hordes.fr/*
// @require			http://yui.yahooapis.com/2.8.0r4/build/yahoo/yahoo-min.js
// @require			http://yui.yahooapis.com/2.8.0r4/build/dom/dom-min.js
// @require			http://yui.yahooapis.com/2.8.0r4/build/selector/selector-min.js
// @require			http://yui.yahooapis.com/2.8.0r4/build/json/json-min.js
// ==/UserScript==

(function() {

var FVERSION = 1.1;
var BDEBUG = false;

/**
 * Namespace
 */
var OEEVBF = {};

/**
 * Wrapper to select by id
 * @param {String} sId
 */
var $ = function(sId){return window.document.getElementById(sId);};

/**
 * Wrapper for adding listeners
 * @param {Object} oTarget
 * @param {String} sEvent
 * @param {Function} oCallback
 */
OEEVBF.addListener = function(oTarget, sEvent, oCallback) {
	try {
		if (oCallback) {
			if (oTarget.pop) {
				for (var i = 0, j = oTarget.length ; i < j ; i++) {
					oTarget[i].addEventListener(sEvent, oCallback, false);
				}
			}
			else {
				oTarget.addEventListener(sEvent, oCallback, false);
			}
		}
		else {
			throw new Error('No callback defined');
		}
	}
	catch (oError) {
		OEEVBF.log('Error OEEVBF.addListener : ' + oError.message, true);
	}
};

/**
 * Wrapper for removing listeners
 * @param {Object} oTarget
 * @param {String} sEvent
 * @param {Function} oCallback
 */
OEEVBF.removeListener = function(oTarget, sEvent, oCallback) {
	try {
		if (oTarget.pop) {
			for (var i = 0, j = oTarget.length ; i < j ; i++) {
				oTarget[i].removeEventListener(sEvent, oCallback, false);
			}
		}
		else {
			oTarget.removeEventListener(sEvent, oCallback, false);
		}
	}
	catch (oError) {
		OEEVBF.log('Error OEEVBF.removeListener : ' + oError.message, true);
	}
};

/**
 * Wrapper for selector CSS3
 * @param {String} sQuery
 * @param {Object} oFrom
 * @param {Bool} bOnlyFirst
 */
OEEVBF.selector = function(sQuery, oFrom, bOnlyFirst) {
	return YAHOO.util.Selector.query(sQuery, oFrom, bOnlyFirst);
};

/**
 * Manage logs & errors
 * @param {Mixed} oData
 * @param {Bool} bError
 */
OEEVBF.log = function(oData, bError) {
	if (BDEBUG && window.wrappedJSObject.console && window.wrappedJSObject.console.error && window.wrappedJSObject.console.log) {
		if (bError) {
			window.wrappedJSObject.console.error(oData);
		}
		else {
			window.wrappedJSObject.console.log(oData);
		}
	}
};

/**
 * Wrapper for trim
 * @param {String} sText
 */
OEEVBF.trim = function(sText) {
	return sText.replace(/^\s+/g,'').replace(/\s+$/g,'');
};

/**
 * Make a array with unique values
 * @param {Array} b
 */
OEEVBF.unique = function(b) {
	var a = [], i, l = b.length;
	for( i=0; i<l; i++ ) {
		if( a.indexOf( b[i], 0, b ) < 0 ) { a.push( b[i] ); }
	}
	return a;
};

/**
 * Equivalent to in_array in PHP
 * @param {Object} needle
 * @param {Array} haystack
 * @param {Bool} argStrict
 */
OEEVBF.inArray = function(needle, haystack, argStrict) {
	var key = '', strict = !!argStrict;
	if (strict) {
		for (key in haystack) {
			if (haystack[key] === needle) {
				return true;
			}
		}
	}
	else {
		for (key in haystack) {
			if (haystack[key] == needle) {
				return true;
			}
		}
	}
	return false;
};

/**
 * Main manager
 */
OEEVBF.manager = {
	
	/**
	 * Parameters
	 */
	iTimeout: 1000,
	
	/**
	 * Const
	 */
	aPageToLaunch: [
					'^http://www.hordes.fr/(?:#)$',
					'outside',
					'home(?:;|\\?)',
					'city/door',
					'ghost/user',
					'saloon/thread/[0-9]+\\?',
					'ghost/maps',
					'ghost/ranking\\?cat=soul',
					'ghost/ranking\\?(sk=|cat=hardcore|cat=normal)',
					'ghost/ranking\\?cat=rewards'
					],
	
	/**
	 * Constainer
	 */
	oUI: null,
	
	/**
	 * Check if Hordes "is here" and check the version
	 */
	first: function() {
		try {
			OEEVBF.log('OeevBF Versionning...');
			// Load user data
			OEEVBF.storeData.load();
			// Provide object UI for OeevBF
			OEEVBF.manager.oUI = new OEEVBF.ui();
			if (!(window && window.wrappedJSObject && window.wrappedJSObject.js)) {
				throw new Error('Something wrong in JS');
			}
			var oRequest = new OEEVBF.request(OEEVBF.action.sSiteUrlVersion, null, OEEVBF.action.versionCheck, null);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.manager.first : ' + oError.message, true);
		}
	},
	
	/**
	 * Edit function to detect url to catch and start OeevBF
	 */
	init: function() {
		try {
			// Edit the Hordes function to watch page load
			/*
			window.wrappedJSObject.js.XmlHttp._oWrappedOnDataFunction_ = window.wrappedJSObject.js.XmlHttp.onData;
			window.wrappedJSObject.js.XmlHttp.onData = function() {
				try {
					var sUrl = this.urlForBack;
					var oResults = this._oWrappedOnDataFunction_.apply(this, arguments);
					window.setTimeout(OEEVBF.manager.ready, 0, sUrl);
					return oResults;
				}
				catch (oError) {
					window.alert('Pour une raison inconnue votre navigateur refuse de charger la page. Essayez de recharger la page avec CTRL+F5 et/ou de désactiver les scripts "userscript" que vous auriez pu ajouter (la tête de singe en bas à droite de votre navigateur).');
				}
			};
			*/
			window.wrappedJSObject.js.XmlHttp._oWrappedOnDataFunction_ = window.wrappedJSObject.js.XmlHttp.onData;
			window.wrappedJSObject.js.XmlHttp.onData = function() {
				try {
					var sUrl = this.url;
					var oResults = window.wrappedJSObject.js.XmlHttp._oWrappedOnDataFunction_.apply(this, arguments);
					window.setTimeout(OEEVBF.manager.ready, 0, sUrl);
					return oResults;
				}
				catch (oError) {
					window.alert('Pour une raison inconnue votre navigateur refuse de charger la page. Essayez de recharger la page avec CTRL+F5 et/ou de désactiver les scripts "userscript" que vous auriez pu ajouter (la tête de singe en bas à droite de votre navigateur).');
					OEEVBF.log(oError);
				}
			};
			// Next step
			OEEVBF.manager.ready();
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.manager.init : ' + oError.message, true);
		}
	},
	
	/**
	 * Identify the page to know if OeevBF is needed
	 * @param {String} sUrl
	 */
	ready: function(sUrl) {
		try {
			if (!sUrl) {
				sUrl = OEEVBF.manager.url();
			}
			// Add the preference button on top of each page
			if (!$(OEEVBF.manager.oUI.sPrefMainDivId)) {
				OEEVBF.log('OeevBF add the pref button');
				OEEVBF.manager.oUI.interfaceButtonPreference();
			}
			OEEVBF.log('OeevBF identifying the page : ' + sUrl);
			for (var i = 0, j = OEEVBF.manager.aPageToLaunch.length ; i < j ; i++) {
				if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[i])) {
					OEEVBF.log('OeevBF needed');
					OEEVBF.manager.launch(sUrl);
					break;
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.manager.ready : ' + oError.message, true);
		}
	},
	
	/**
	 * All ready, look for the script state and add interface
	 * @param {String} sUrl
	 */
	launch: function(sUrl) {
		try {
			if (!sUrl) {
				sUrl = OEEVBF.manager.url();
			}
			OEEVBF.log('OeevBF working...');
			if (!OEEVBF.manager.checkInstall()) {
				// First run for OeevBF
				OEEVBF.storeData.set(OEEVBF.storeData.sVersionId, FVERSION);
				OEEVBF.storeData.set(OEEVBF.storeData.sPrefId, [22, 9]);
				OEEVBF.storeData.set(OEEVBF.storeData.sPrefCityLinkId, true);
				OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkId, true);
				OEEVBF.storeData.set(OEEVBF.storeData.sChooseOeevId, true);
				OEEVBF.storeData.set(OEEVBF.storeData.sChoosePatamapId, true);
				OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkChoixVilleId, true);
				OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkRankId, true);
			}
			// Connection page
			if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[0])) {
				OEEVBF.action.resetApiKey();
			}
			else {
				// If there is no Api Key, like after login, we get them
				if (((OEEVBF.storeData.get(OEEVBF.storeData.sApiKeyId)) === undefined) || (OEEVBF.storeData.get(OEEVBF.storeData.sApiKeyId).length === 0)) {
					OEEVBF.action.getApiKeyByPref();
				}
				// First run of this version, we load default conf for new parameters
				if (!YAHOO.lang.isBoolean(OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkChoixVilleId))) {
					OEEVBF.storeData.set(OEEVBF.storeData.sChooseOeevId, true);
					OEEVBF.storeData.set(OEEVBF.storeData.sChoosePatamapId, true);
					OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkChoixVilleId, true);
					OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkRankId, true);
				}
				// Répartit toutes les URL vers le code associé
				OEEVBF.manager.interfaceDispatcher(sUrl);
			}
			OEEVBF.log('OeevBF ready');
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.manager.launch : ' + oError.message, true);
		}
	},
	
	/**
	 * Load the right interface for the good url
	 * @param {String} sUrl
	 */
	interfaceDispatcher: function(sUrl) {
		try {
			OEEVBF.log('OeevBF interface needed...');
			if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[1])) {
				OEEVBF.manager.oUI.interfaceOutsideButton();
			}
			else if ((OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[2])) || (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[3]))) {
				OEEVBF.manager.oUI.interfaceInsideButton();
			}
			else if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[4])) {
				OEEVBF.action.linkCityName();
				OEEVBF.action.preparePictHordesLink();
			}
			else if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[5])) {
				OEEVBF.action.forumActions();
			}
			else if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[6])) {
				OEEVBF.action.addMapButton();
			}
			else if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[7])) {
				OEEVBF.action.soolRankActions();
			}
			else if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[8])) {
				OEEVBF.action.addRankMapButton();
				OEEVBF.action.linkPictHordesCityRank();
			}
			else if (OEEVBF.manager.detectPage(sUrl, OEEVBF.manager.aPageToLaunch[9])) {
				OEEVBF.action.addRankData();
			}
			OEEVBF.log('OeevBF interface installed');
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.manager.interfaceDispatcher : ' + oError.message, true);
		}
	},
	
	/**
	 * Test is the current page is sPage
	 * @param {String} sUrl
	 * @param {String} sPage
	 */
	detectPage: function(sUrl, sPage) {
		var oRegex = new RegExp(sPage, 'g');
		return oRegex.test(sUrl);
	},
	
	/**
	 * Return the url of the page
	 */
	url: function() {
		return window.document.location;
	},
	
	/**
	 * Return the anchor of the url of the page
	 */
	anchor: function() {
		return window.document.location.hash;
	},
	
	/**
	 * Test if it's the first run of the script
	 */
	checkInstall: function() {
		return !YAHOO.lang.isUndefined(OEEVBF.storeData.get(OEEVBF.storeData.sVersionId));
	},
	
	/**
	 * Manage click on the interface
	 * @param {Object} oEvent
	 */
	buttonClickHandler: function(oEvent) {
		try {
			OEEVBF.log('OeevBF Click');
			var oTarget = oEvent.currentTarget;
			if (oTarget.id == OEEVBF.manager.oUI.sButtonHelpId) {
				OEEVBF.action.showPref();
			}
			else if (oTarget.id == OEEVBF.manager.oUI.sButtonUpdateId) {
				OEEVBF.action.updateSites();
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.manager.buttonClickHandler : ' + oError.message, true);
		}
	}
};

/**
 * Manage actions
 */
OEEVBF.action = {
	
	/**
	 * Parameters
	 */
	sSiteApiKey: 'http://www.hordes.fr/disclaimer?id=',
	sSiteUrlVersion: 'http://www.oeev-hordes.com/oeevbf_version.json',
	sSiteUrlSee: 'http://www.oeev-hordes.com/',
	sSitePatamapUrlSee: 'http://www.patamap.com/',
	sCityLink: 'http://www.oeev-hordes.com/?name=',
	sSoulLink: 'http://www.pict-hordes.com/ame.php?id=',
	sDistinctionLink: 'http://www.pict-hordes.com/distinction.php?id=',
	sSoulUrl: 'http://www.pict-hordes.com/oeevbf_verifid.php',
	sOeevCityUrl: 'http://www.oeev-hordes.com/?ville=',
	sPatamapCityUrl: 'http://www.patamap.com/index.php?view=',
	sSoulsRankUrl: 'http://www.pict-hordes.com/classement.json',
	
	aSites: [
				{
					sId: 22,
					sPost: 'mode=json',
					sName: 'Où en êtes-vous ?'
				},
				{
					sId: 9,
					sName: 'Patamap'
				}
				],
	
	sCityNoLink: 'Ancienne Cité Oubliée',
	sMessageUpdateSiteError: 'La mise à jour a échouée pour le site : ',
	iNbToWait: 0,
	sMultiErrorMessage: '',
	
	sIdRegex: 'from=disclaimer\\?id=([0-9]+);',
	sUrlRegex: '<form\\s+action="([0-9a-zA-Z:/.\\-]+)"\\s+method="post"\\s+target="_blank">',
	sApiKeyRegex: '<input\\s+type="hidden"\\s+name="key"\\s+value="([a-zA-Z0-9]+)"/>',
	sCityRegex: '<img.*>\\s*(.*)\\s*',
	sPictSoulRegex: '^js\\.UserBox\\.show\\(this,\\s+([0-9]+),\\s+\'',
	sPictSoulWorldRegex: '^js\\.XmlHttp\\.get\\(\'ghost/city\\?uid=([0-9]+);',
	sPictSoulPageRegex: 'ghost/user\\?uid=([0-9]+)',
	sPictSoulRankRegex: '^js\\.XmlHttp\\.get\\(\'ghost/user\\?uid=([0-9]+);',
	sChooseMapRegex: '^js\\.XmlHttp\\.get\\(\'ghost/maps\\?mapId=([0-9]+);',
	sChooseMapRegex2: '^js\\.XmlHttp\\.get\\(\'ghost/user\\?uid=([0-9]+);from=ghost/maps\\?mapId=([0-9]+);',
	sRankMapRegex: '^js\\.XmlHttp\\.get\\(\'ghost/ranking\\?cat=([a-zA-Z]+);dmid=([0-9]+);',
	
	/**
	 * Alert the user if the version is not right
	 */
	versionCheck: function(oData) {
		try {
			OEEVBF.log('OeevBF Version check');
			if (oData && oData.version) {
				if (FVERSION < oData.version) {
					OEEVBF.manager.oUI.alertVersion(oData.url);
				}
				else {
					OEEVBF.manager.init();
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.versionCheck : ' + oError.message, true);
		}
	},
	
	/**
	 * The end of the first time notification
	 */
	firstTimeValidation: function() {
		try {
			OEEVBF.storeData.set(OEEVBF.storeData.sVersionId, FVERSION);
			OEEVBF.action.getAndSavePreference();
			OEEVBF.manager.interfaceDispatcher(OEEVBF.manager.url());
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.firstTimeValidation : ' + oError.message, true);
		}
	},
	
	/**
	 * Display the preferences in a notification
	 */
	showPref: function() {
		try {
			OEEVBF.manager.oUI.interfacePreference();
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.showPref : ' + oError.message, true);
		}
	},
	
	/**
	 * Get the value of preferences and save the API keys
	 */
	getAndSavePreference: function(){
		try {
			var aPref = [];
			OEEVBF.action.resetApiKey();
			aPref[aPref.length] = OEEVBF.action.aSites[0].sId;
			if ($(OEEVBF.manager.oUI.sCheckboxPatamapId) && ($(OEEVBF.manager.oUI.sCheckboxPatamapId).checked)) {
				aPref[aPref.length] = OEEVBF.action.aSites[1].sId;
			}
			OEEVBF.storeData.set(OEEVBF.storeData.sPrefId, aPref);
			OEEVBF.storeData.set(OEEVBF.storeData.sPrefCityLinkId, $(OEEVBF.manager.oUI.sCheckboxCityLinkId).checked);
			OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkId, $(OEEVBF.manager.oUI.sCheckboxPictLinkId).checked);
			OEEVBF.storeData.set(OEEVBF.storeData.sChooseOeevId, $(OEEVBF.manager.oUI.sCheckboxChooseOeevId).checked);
			OEEVBF.storeData.set(OEEVBF.storeData.sChoosePatamapId, $(OEEVBF.manager.oUI.sCheckboxChoosePatamapId).checked);
			OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkChoixVilleId, $(OEEVBF.manager.oUI.sCheckboxPictLinkChoixVilleId).checked);
			OEEVBF.storeData.set(OEEVBF.storeData.sPrefPictLinkRankId, $(OEEVBF.manager.oUI.sCheckboxPictLinkRankId).checked);
			OEEVBF.action.getApiKeyByPref();
			OEEVBF.action.cleanNotification();
			var oLeftMenu = OEEVBF.selector('div[class="left"]', window.document, true);
			if (oLeftMenu) {
				OEEVBF.manager.oUI.removeMenu();
				OEEVBF.manager.interfaceDispatcher(OEEVBF.manager.url());
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.getAndSavePreference : ' + oError.message, true);
		}
	},
	
	/**
	 * Get the ApiKey for the preferences
	 */
	getApiKeyByPref: function() {
		try {
			var aPref = OEEVBF.storeData.get(OEEVBF.storeData.sPrefId);
			for (var i = 0, j = aPref.length ; i < j ; i++) {
				var oRequest = new OEEVBF.request(OEEVBF.action.sSiteApiKey + aPref[i], '', OEEVBF.action.saveApiKey);
			}
			return aPref.length;
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.getApiKeyByPref : ' + oError.message, true);
		}
	},
	
	/**
	 * Store the API key
	 */
	saveApiKey: function(sData) {
		try {
			var oRegex = new RegExp(OEEVBF.action.sIdRegex, 'g');
			if (!oRegex.test(sData)) {
				throw new Error('No site id found');
			}
			var sSiteId = RegExp.$1;
			oRegex = new RegExp(OEEVBF.action.sUrlRegex, 'g');
			if (!oRegex.test(sData)) {
				throw new Error('No site url found');
			}
			var sSiteUrl = RegExp.$1;
			oRegex = new RegExp(OEEVBF.action.sApiKeyRegex, 'g');
			if (!oRegex.test(sData)) {
				throw new Error('No site api key found');
			}
			var sApiKey = RegExp.$1;
			var aApiKeyList = OEEVBF.storeData.get(OEEVBF.storeData.sApiKeyId);
			if (!aApiKeyList) {
				aApiKeyList = [];
			}
			aApiKeyList[aApiKeyList.length] = {sSiteId: sSiteId, sApiKey: sApiKey, sSiteUrl: sSiteUrl};
			OEEVBF.storeData.set(OEEVBF.storeData.sApiKeyId, aApiKeyList);
			OEEVBF.log('OeevBF Api key site ' + sSiteId + ' retrieved and saved');
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.saveApiKey : ' + oError.message, true);
		}
	},
	
	/**
	 * Erase all Api Key saved
	 */
	resetApiKey: function() {
		try {
			OEEVBF.storeData.set(OEEVBF.storeData.sApiKeyId, []);
			OEEVBF.log('OeevBF Api key reset');
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.resetApiKey : ' + oError.message, true);
		}
	},
	
	/**
	 * Clean the notification div
	 */
	cleanNotification: function() {
		try {
			var oNotifDiv = $(OEEVBF.manager.oUI.sNotifDivId);
			var oButton = OEEVBF.selector('a[class=button]', oNotifDiv, false);
			OEEVBF.removeListener(oButton, 'click', OEEVBF.action.firstTimeValidation);
			OEEVBF.removeListener(oButton, 'click', OEEVBF.action.getAndSavePreference);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.cleanNotification : ' + oError.message, true);
		}
	},
	
	/**
	 * Update all sites
	 */
	updateSites: function() {
		try {
			OEEVBF.manager.oUI.updateLoading(true);
			OEEVBF.action.iNbToWait = 0;
			var aSites = OEEVBF.storeData.get(OEEVBF.storeData.sApiKeyId);
			for (var i = 0, j = aSites.length ; i < j ; i++) {
				var oSite = false;
				for (var k = 0, l = OEEVBF.action.aSites.length; k < l; k++) {
					if (aSites[i].sSiteId == OEEVBF.action.aSites[k].sId) {
						oSite = OEEVBF.action.aSites[k];
						break;
					}
				}
				var sUrl = aSites[i].sSiteUrl;
				var sPost = 'key=' + aSites[i].sApiKey;
				if (oSite && oSite.sUrl) {
					sUrl = oSite.sUrl;
				}
				if (oSite && oSite.sPost) {
					sPost += '&' + oSite.sPost;
				}
				OEEVBF.action.iNbToWait++;
				OEEVBF.action.sMultiErrorMessage = '';
				var oRequest = new OEEVBF.request(sUrl, sPost, OEEVBF.action.updateSitesFinish, OEEVBF.action.updateSitesError);
				oRequest.messageOnError = OEEVBF.action.sMessageUpdateSiteError + oSite.sName;
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.updateSites : ' + oError.message, true);
		}
	},
	
	/**
	 * All site are up to date
	 */
	updateSitesFinish: function() {
		try {
			OEEVBF.action.iNbToWait--;
			if (OEEVBF.action.iNbToWait === 0) {
				OEEVBF.manager.oUI.updateLoading(false);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.updateSitesFinish : ' + oError.message, true);
		}
	},
	
	/**
	 * Error on update a site
	 */
	updateSitesError: function(oRequest){
		try {
			OEEVBF.action.updateSitesFinish();
			if (OEEVBF.action.sMultiErrorMessage !== '') {
				OEEVBF.action.sMultiErrorMessage += '<br />';
			}
			OEEVBF.action.sMultiErrorMessage += oRequest.messageOnError;
			if (OEEVBF.action.iNbToWait === 0) {
				OEEVBF.manager.oUI.showNotif(OEEVBF.action.sMultiErrorMessage);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.updateSitesError : ' + oError.message, true);
		}
	},
	
	/**
	 * Replace city's name by a link to OEEV maps
	 */
	linkCityName: function() {
		try {
			if (OEEVBF.storeData.get(OEEVBF.storeData.sPrefCityLinkId)) {
				var aCityList = OEEVBF.selector('div[class="current"] strong', window.document);
				var aLink = null;
				var sCity = null;
				for (var i = 0, j = aCityList.length ; i < j ; i++) {
					// Detect if there is already a link in it
					aLink = OEEVBF.selector('a', aCityList[i]);
					if (aLink.length > 0) {
						// Remplace the link to a link to OEEV
						sCity = OEEVBF.trim(aLink[0].innerHTML);
						if (sCity != OEEVBF.action.sCityNoLink) {
							OEEVBF.manager.oUI.cleanNode(aCityList[i]);
							OEEVBF.manager.oUI.cityLink(aCityList[i], sCity);
						}
					}
					else {
						// Add a link on the city name
						sCity = OEEVBF.trim(aCityList[i].innerHTML);
						if (sCity != OEEVBF.action.sCityNoLink) {
							OEEVBF.manager.oUI.cleanNode(aCityList[i]);
							OEEVBF.manager.oUI.cityLink(aCityList[i], sCity);
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkCityName : ' + oError.message, true);
		}
	},
	
	/**
	 * All actions on the forum pa
	 */
	forumActions: function() {
		OEEVBF.action.linkCityNameForum();
		OEEVBF.action.linkSoulsForum();
	},
	
	/**
	 * Replace city's name by a link to OEEV maps in the forum
	 */
	linkCityNameForum: function() {
		try {
			if (OEEVBF.storeData.get(OEEVBF.storeData.sPrefCityLinkId)) {
				// Add a link on the city name
				var aCityList = OEEVBF.selector('div[class="city"]', window.document);
				var sCity = null;
				var oRegex = null;
				for (var i = 0, j = aCityList.length ; i < j ; i++) {
					oRegex = new RegExp(OEEVBF.action.sCityRegex, 'g');
					if (oRegex.test(aCityList[i].innerHTML)) {
						sCity = RegExp.$1;
						if (sCity != OEEVBF.action.sCityNoLink) {
							OEEVBF.manager.oUI.cleanNode(aCityList[i]);
							OEEVBF.manager.oUI.cityLink(aCityList[i], sCity, OEEVBF.manager.oUI.sItemMapIcon);
						}
					}
				}
				// This part repair div changed in a
				aCityList = OEEVBF.selector('a[class="city"]', window.document);
				var oParent = null;
				for (i = 0, j = aCityList.length ; i < j ; i++) {
					oRegex = new RegExp(OEEVBF.action.sCityRegex, 'g');
					if (oRegex.test(aCityList[i].innerHTML)) {
						sCity = RegExp.$1;
						if (sCity != OEEVBF.action.sCityNoLink) {
							oParent = aCityList[i].parentNode;
							oParent.removeChild(aCityList[i]);
							OEEVBF.manager.oUI.cityLink(oParent, sCity, OEEVBF.manager.oUI.sItemMapIcon, true);
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkCityNameForum : ' + oError.message, true);
		}
	},
	
	/**
	 * Get all ids for soul's links
	 */
	linkSoulsForum: function() {
		try {
			if (OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkId)) {
				var aUsersId = [];
				var oRegex = null;
				var i = 0;
				var j = 0;
				// City forum
				var aMessageList = OEEVBF.selector('div[class~="message"] a[class="userLink"]', window.document);
				if (aMessageList.length > 0) {
					for (i = 0, j = aMessageList.length ; i < j ; i++) {
						oRegex = new RegExp(OEEVBF.action.sPictSoulRegex, 'g');
						if (oRegex.test(YAHOO.util.Dom.getAttribute(aMessageList[i], 'onclick'))) {
							aUsersId[aUsersId.length] = RegExp.$1;
						}
					}
				}
				// World forum
				aMessageList = OEEVBF.selector('div[class~="message"] span[class~="userLink"] a', window.document);
				if (aMessageList.length > 0) {
					for (i = 0, j = aMessageList.length ; i < j ; i++) {
						oRegex = new RegExp(OEEVBF.action.sPictSoulWorldRegex, 'g');
						if (oRegex.test(YAHOO.util.Dom.getAttribute(aMessageList[i], 'onclick'))) {
							aUsersId[aUsersId.length] = RegExp.$1;
						}
					}
				}
				aUsersId = OEEVBF.unique(aUsersId);
				var oRequest = new OEEVBF.request(OEEVBF.action.sSoulUrl, 'ids=' + aUsersId.join(';'), OEEVBF.action.linkSoulsForumOnId);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkSoulsForum : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a Pict'horde link on souls
	 */
	linkSoulsForumOnId: function(aIds) {
		try {
			var iUserId = null;
			var oRegex = null;
			var i = 0;
			var j = 0;
			// City forum
			var aMessageList = OEEVBF.selector('div[class~="message"] a[class="userLink"]', window.document);
			if (aMessageList.length > 0) {
				for (i = 0, j = aMessageList.length ; i < j ; i++) {
					oRegex = new RegExp(OEEVBF.action.sPictSoulRegex, 'g');
					if (oRegex.test(YAHOO.util.Dom.getAttribute(aMessageList[i], 'onclick'))) {
						iUserId = RegExp.$1;
						if (OEEVBF.inArray(iUserId, aIds)) {
							OEEVBF.manager.oUI.soulsLink(aMessageList[i].parentNode, aMessageList[i], iUserId);
						}
					}
				}
			}
			// World forum
			aMessageList = OEEVBF.selector('div[class~="message"] span[class~="userLink"] a', window.document);
			if (aMessageList.length > 0) {
				for (i = 0, j = aMessageList.length ; i < j ; i++) {
					oRegex = new RegExp(OEEVBF.action.sPictSoulWorldRegex, 'g');
					if (oRegex.test(YAHOO.util.Dom.getAttribute(aMessageList[i], 'onclick'))) {
						iUserId = RegExp.$1;
						if (OEEVBF.inArray(iUserId, aIds)) {
							OEEVBF.manager.oUI.soulsLink(aMessageList[i].parentNode, aMessageList[i], iUserId);
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkSoulsForumOnId : ' + oError.message, true);
		}
	},
	
	/**
	 * Get the ID of the user to define if he add a page on Pict'Hordes
	 */
	preparePictHordesLink: function() {
		try {
			var aData = OEEVBF.selector('div[class="tinyAction"] a', window.document);
			if (aData.length == 1) {
				var oRegex = new RegExp(OEEVBF.action.sPictSoulPageRegex, 'g');
				oRegex.test(YAHOO.util.Dom.getAttribute(aData[0], 'href'));
				var iUserId = RegExp.$1;
				var oRequest = new OEEVBF.request(OEEVBF.action.sSoulUrl, 'ids=' + iUserId, OEEVBF.action.linkPictHordes);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.preparePictHordesLink : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the link to Pict'hordes
	 */
	linkPictHordes: function(aIds) {
		try {
			if (aIds.length == 1) {
				var aData = OEEVBF.selector('div[class="rewardList"]', window.document);
				if (aData.length == 1) {
					OEEVBF.manager.oUI.soulsLink(aData[0].parentNode, aData[0], aIds[0]);
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkPictHordes : ' + oError.message, true);
		}
	},
	
	/**
	 * Add Map buttons on game choice page
	 */
	addMapButton: function() {
		try {
			var oTableCity = OEEVBF.selector('div[class="maps"] > table[class~="table"]', window.document, true);
			if (oTableCity) {
				var i, j, oRow, oCell, oLink, oRegex;
				j = oTableCity.rows.length;
				for (i = 0 ; i < j ; i++ ) {
					oRow = oTableCity.rows[i];
					if (i === 0) {
						OEEVBF.manager.oUI.interfaceChooseMapHead(oRow);
					}
					else {
						oCell = oRow.cells[2];
						oLink = OEEVBF.selector('a', oCell, true);
						if ((oLink) && (oTableCity.rows[i].cells.length != 1)) {
							oRegex = new RegExp(OEEVBF.action.sChooseMapRegex, 'g');
							if (oRegex.test(YAHOO.util.Dom.getAttribute(oLink, 'onclick'))) {
								OEEVBF.manager.oUI.interfaceChooseMap(oRow, RegExp.$1);
							}
							else {
								OEEVBF.manager.oUI.interfaceChooseMapEmpty(oRow, true);
							}
						}
						else if (oTableCity.rows[i].cells.length == 1) {
							if (OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkChoixVilleId)) {
								var aData = OEEVBF.selector('a', oTableCity.rows[i].cells[0], false);
								var aUsersId = [];
								if (aData.length > 0) {
									for (var k = 0, l = aData.length ; k < l ; k++) {
										oRegex = new RegExp(OEEVBF.action.sChooseMapRegex2, 'g');
										if (oRegex.test(YAHOO.util.Dom.getAttribute(aData[k], 'onclick'))) {
											aUsersId[aUsersId.length] = RegExp.$1;
										}
									}
									aUsersId = OEEVBF.unique(aUsersId);
									var oRequest = new OEEVBF.request(OEEVBF.action.sSoulUrl, 'ids=' + aUsersId.join(';'), OEEVBF.action.linkPictHordesChooseMapOnId);
								}
							}
							YAHOO.util.Dom.setAttribute(oTableCity.rows[i].cells[0], 'colspan', 4);
						}
						else if ((oTableCity.rows[i + 1]) && (oTableCity.rows[i + 1].cells.length == 1)) {
							oLink = OEEVBF.selector('a', oTableCity.rows[i + 1].cells[0], true);
							if (oLink) {
								oRegex = new RegExp(OEEVBF.action.sChooseMapRegex2, 'g');
								if (oRegex.test(YAHOO.util.Dom.getAttribute(oLink, 'onclick'))) {
									OEEVBF.manager.oUI.interfaceChooseMap(oRow, RegExp.$2);
								}
								else {
									OEEVBF.manager.oUI.interfaceChooseMapEmpty(oRow, true);
								}
							}
						}
						else {
							OEEVBF.manager.oUI.interfaceChooseMapEmpty(oRow, true);
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.addMapButton : ' + oError.message, true);
		}
	},
	
	/**
	 * Add Map buttons on game choice page
	 */
	addRankMapButton: function() {
		try {
			var oTableCity = OEEVBF.selector('table[class~="mapRanking"]', window.document, true);
			if (oTableCity) {
				var i, j, oRow, oCell, oLink, oRegex;
				j = oTableCity.rows.length;
				for (i = 0 ; i < j ; i++ ) {
					oRow = oTableCity.rows[i];
					if (i === 0) {
						OEEVBF.manager.oUI.interfaceRankMapHead(oRow);
					}
					else {
						OEEVBF.manager.oUI.fixRankTable();
						oCell = oRow.cells[1];
						oLink = OEEVBF.selector('a', oCell, true);
						if ((oLink) && (oTableCity.rows[i].cells.length != 1)) {
							oRegex = new RegExp(OEEVBF.action.sRankMapRegex, 'g');
							if (oRegex.test(YAHOO.util.Dom.getAttribute(oLink, 'onclick'))) {
								OEEVBF.manager.oUI.interfaceChooseMap(oRow, RegExp.$2);
							}
							else {
								OEEVBF.manager.oUI.interfaceChooseMapEmpty(oRow, true);
							}
						}
						else if (oTableCity.rows[i].cells.length == 1) {
							if (OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkChoixVilleId)) {
								var aData = OEEVBF.selector('a', oTableCity.rows[i].cells[0], false);
								var aUsersId = [];
								if (aData.length > 0) {
									for (var k = 0, l = aData.length ; k < l ; k++) {
										oRegex = new RegExp(OEEVBF.action.sChooseMapRegex2, 'g');
										if (oRegex.test(YAHOO.util.Dom.getAttribute(aData[k], 'onclick'))) {
											aUsersId[aUsersId.length] = RegExp.$1;
										}
									}
									aUsersId = OEEVBF.unique(aUsersId);
									var oRequest = new OEEVBF.request(OEEVBF.action.sSoulUrl, 'ids=' + aUsersId.join(';'), OEEVBF.action.linkPictHordesChooseMapOnId);
								}
							}
							YAHOO.util.Dom.setAttribute(oTableCity.rows[i].cells[0], 'colspan', 4);
						}
						else if ((oTableCity.rows[i + 1]) && (oTableCity.rows[i + 1].cells.length == 1)) {
							oLink = OEEVBF.selector('a', oTableCity.rows[i + 1].cells[0], true);
							if (oLink) {
								oRegex = new RegExp(OEEVBF.action.sChooseMapRegex2, 'g');
								if (oRegex.test(YAHOO.util.Dom.getAttribute(oLink, 'onclick'))) {
									OEEVBF.manager.oUI.interfaceChooseMap(oRow, RegExp.$2);
								}
								else {
									OEEVBF.manager.oUI.interfaceChooseMapEmpty(oRow, true);
								}
							}
						}
						else {
							OEEVBF.manager.oUI.interfaceChooseMapEmpty(oRow, true);
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.addMapButton : ' + oError.message, true);
		}
	},
	
	/**
	 * Actions dans la page de classement par points d'ame
	 */
	soolRankActions: function() {		
		try {
			if (OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkRankId)) {
				var aUsersId = [];
				var oRegex = null;
				var oCell;
				var i = 0;
				var j = 0;
				var oTableRank = OEEVBF.selector('table[class~="soulRanking"]', window.document, true);
				j = oTableRank.rows.length;
				for (i = 0 ; i < j ; i++ ) {
					oRow = oTableRank.rows[i];
					if (i === 0) {
						OEEVBF.manager.oUI.interfaceSoolRankHead(oRow);
					}
					else{
						oCell = window.document.createElement('td');
						YAHOO.util.Dom.setStyle(oCell, 'text-align', 'center');
						YAHOO.util.Dom.insertAfter(oCell, oRow.children[1]);
					}
				}
				aNamesList = OEEVBF.selector('td[class="name"] a', window.document);				
				if (aNamesList.length > 0) {
					for (i = 0, j = aNamesList.length ; i < j ; i++) {						
						oRegex = new RegExp(OEEVBF.action.sPictSoulRankRegex, 'g');
						if (oRegex.test(YAHOO.util.Dom.getAttribute(aNamesList[i], 'onclick'))) {
							aUsersId[aUsersId.length] = RegExp.$1;
						}
					}
				}
				aUsersId = OEEVBF.unique(aUsersId);
				var oRequest = new OEEVBF.request(OEEVBF.action.sSoulUrl, 'ids=' + aUsersId.join(';'), OEEVBF.action.linkPictHordesSoolRank);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.soolRankActions : ' + oError.message, true);
		}
	},
	
	/**
	 * Actions dans la page de classement par points d'ame
	 * @param {Array} aIds
	 */
	linkPictHordesSoolRank: function(aIds) {	
		try {
			var iUserId = null;
			var oRegex = null;
			var i = 0;
			var j = 0;
			aNamesList = OEEVBF.selector('td[class="name"] a', window.document);
			if (aNamesList.length > 0) {
				for (i = 0, j = aNamesList.length ; i < j ; i++) {
					oRegex = new RegExp(OEEVBF.action.sPictSoulRankRegex, 'g');
					if (oRegex.test(YAHOO.util.Dom.getAttribute(aNamesList[i], 'onclick'))) {
						iUserId = RegExp.$1;
						if (OEEVBF.inArray(iUserId, aIds)) {
							OEEVBF.manager.oUI.soulsLinkAsImg(aNamesList[i].parentNode.parentNode.children[2], null, iUserId);
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkPictHordesSoolRank : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the link to Pict'hordes
	 */
	linkPictHordesChooseMapOnId: function(aIds) {
		try {
			if (aIds.length > 0) {
				var aData = OEEVBF.selector('td[class="list"] a', window.document, false);
				var iUserId = null;
				if (aData.length > 0) {
					for (var i = 0, j = aData.length ; i < j ; i++) {
						oRegex = new RegExp(OEEVBF.action.sChooseMapRegex2, 'g');
						if (oRegex.test(YAHOO.util.Dom.getAttribute(aData[i], 'onclick'))) {
							iUserId = RegExp.$1;
							if (OEEVBF.inArray(iUserId, aIds)) {
								OEEVBF.manager.oUI.soulsLinkChooseMap(aData[i], aData[i], iUserId);
							}
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkPictHordes : ' + oError.message, true);
		}
	},
	
	/**
	 * Montre l'onglet correspondant
	 * @param {String} sTabId
	 * @param {String} sContentId
	 */
	showPrefTab: function(sTabId, sContentId) {
		try {
			var oContentDisplay = YAHOO.util.Dom.getStyle(sContentId, 'display');
			if (oContentDisplay == 'none') {
				YAHOO.util.Dom.setStyle(sContentId, 'display', 'block');
				YAHOO.util.Dom.setStyle('contentMain', 'display', 'none');
			}
			else {
				YAHOO.util.Dom.setStyle(sContentId, 'display', 'none');
				YAHOO.util.Dom.setStyle('contentMain', 'display', 'block');
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.showPrefTab : ' + oError.message, true);
		}
	},
	
	/**
	 * Prépare le classement de Pict'Horde dans la page de classement
	 */
	addRankData: function() {
		try {
			var oRequest = new OEEVBF.request(OEEVBF.action.sSoulsRankUrl, '', OEEVBF.action.displayRankData);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.addRankTable : ' + oError.message, true);
		}
	},
	
	/**
	 * Affiche la table
	 */
	displayRankData: function(oData) {
		try {
			OEEVBF.manager.oUI.interfaceRankPictHordes(oData);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.displayRankTable : ' + oError.message, true);
		}
	},
	
	/**
	 * Ajoute les liens pict'ame pour les pages de classement pandémonium et normale
	 */
	linkPictHordesCityRank: function() {
		try {
			var iUserId = null, aUsersId = [], aIds = null, oRegex = null;
			var aNamesList = OEEVBF.selector('table[class="details"] a', window.document);
			if (aNamesList.length > 0) {
				for (var i = 0, j = aNamesList.length ; i < j ; i++) {
					oRegex = new RegExp(OEEVBF.action.sPictSoulRankRegex, 'g');
					if (oRegex.test(YAHOO.util.Dom.getAttribute(aNamesList[i], 'onclick'))) {
						iUserId = RegExp.$1;
						if (!OEEVBF.inArray(iUserId, aUsersId)) {
							aUsersId[aUsersId.length] = iUserId;
						}
					}
				}
				if (aUsersId.length > 0) {
					var oRequest = new OEEVBF.request(OEEVBF.action.sSoulUrl, 'ids=' + aUsersId.join(';'), OEEVBF.action.linkPictHordesCityRankUi);
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkPictHordesCityRank : ' + oError.message, true);
		}
	},
	
	/**
	 * Intégre tous les liens
	 */
	linkPictHordesCityRankUi: function(aData) {
		try {
			if (OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkRankId)) {
				var iUserId = null;
				var aNamesList = OEEVBF.selector('table[class="details"] a', window.document);
				if (aNamesList.length > 0) {
					for (var i = 0, j = aNamesList.length ; i < j ; i++) {
						oRegex = new RegExp(OEEVBF.action.sPictSoulRankRegex, 'g');
						if (oRegex.test(YAHOO.util.Dom.getAttribute(aNamesList[i], 'onclick'))) {
							iUserId = RegExp.$1;
							if (OEEVBF.inArray(iUserId, aData)) {
								// Add the link
								OEEVBF.manager.oUI.interfaceRankPictAmeCell(aNamesList[i].parentNode.parentNode, 1, iUserId);
							}
							else {
								// Empty cell
								OEEVBF.manager.oUI.interfaceRankEmptyCell(aNamesList[i].parentNode.parentNode, 1);
							}
						}
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.action.linkPictHordesCityRankUi : ' + oError.message, true);
		}
	}
};

/**
 * UI
 */
OEEVBF.ui = function(){};
OEEVBF.ui.prototype = {
	
	/**
	 * Const
	 */
	sNotifDivId: 'notification',
	sNotifTextDivId: 'notificationText',
	sNotifBodyClass: 'hideSwf',
	sNotifDivClass: 'showNotif',
	
	sLoadingTextAltText: 'Loading...',
	iMainDivWidth: 450,
	iMainDivHeight: 250,
	iBlackCurtainZIndex: 99,
	iMainDivZIndex: 100,
	sSplitTextBrRegex: '<br />',
	iScrollX: 0,
	iScrollY: 150,
	iLoadingTimeout: 1000,
	
	aPrefTabs: ['Main', 'OEEV', 'Liens de villes', 'Pict\'Hordes'],
	
	/**
	 * Icons
	 */
	sAllIcon: 'http://data.hordes.fr/gfx/icons/',
	sMapIcon: 'http://data.hordes.fr/gfx/icons/r_explor.gif',
	sRpIcon: 'http://data.hordes.fr/gfx/icons/r_rp.gif',
	sPatamapIcon: 'http://www.patamap.com/imageshordes/iconePatamap.png',
	sHelpIcon: 'http://data.hordes.fr/gfx/icons/small_help.gif',
	sLoadingIcon: 'http://data.hordes.fr/gfx/design/loading.gif',
	sItemMapIcon: 'http://data.hordes.fr/gfx/icons/item_map.gif',
	sLoadingTextIcon: 'http://data.hordes.fr/gfx/loc/fr/loadingLabel.gif',
	sPictHordesIcon: 'http://data.hordes.fr/gfx/icons/small_hero.gif',
	aEtoilesIcon: ['http://www.pict-hordes.com/img/class1.gif', 'http://www.pict-hordes.com/img/class2.gif', 'http://www.pict-hordes.com/img/class3.gif'],
	
	/**
	 * Text
	 */
	sVersionText: 'Une nouvelle version de "Où en êtes-vous ?" Best Friend est disponible.\nAfin de profiter des dernières corrections et des dernières nouveautées, vous allez être redirigé vers la nouvelle version afin de pouvoir l\'installer.',
	sLoadingAltText: '[icon]',
	sMenuTitleText: '"Où en êtes-vous ?" Best Friend',
	sButtonUpdateText: 'Mettre à jour la ville',
	sButtonUpdateOutsideText: 'Mettre à jour la case',
	sButtonGotoText: 'Consulter Oeev',
	sButtonGotoPatamapText: 'Consulter Patamap',
	sMajDone: 'Map à jour !',
	
	sButtonPrefAltText: 'Préférences OEEVBF',
	
	sSoulLinkText: 'Pict\'Ame',
	
	sFirstTimeTitleText: '"Où êtes-vous ?" Best Friend',
	sFirstTimeText: 'Vous avez installé le script "OEEV Best Friend" qui vous permet de mettre à jour les maps d\'un simple clic sur un bouton. Pour gérer son installation, sous Firefox, cliquez sur la tête de singe en bas a droite.',
	sPreferenceText: 'Quels sites voulez-vous mettre à jour ?',
	sPrefExplainText: 'Vous avez installé le script "OEEV Best Friend" qui vous permet de mettre à jour les maps d\'un simple clic sur un bouton. Pour gérer son installation, sous Firefox, cliquez sur la tête de singe en bas a droite.<br /><br />Il faut recharger la page pour voir les changements de préférences.',
	sCheckboxOeevText: 'Où en êtes-vous ?',
	sCheckboxPatamapText: 'Patamap',
	sPrefOptions: 'Options',
	sCheckboxCityLinksText: 'Dans les forums et la page d\'âme :',
	sCheckboxChooseOeevText: 'Liens Où en êtes-vous ?',
	sCheckboxChoosePatamapText: 'Liens Patamap',
	sPrefChoixVille: 'Page de choix de la ville avant résurrection',
	sPreferenceDiversText: '<br />Divers :',
	sPreferencePageChoixVilleText: '<br />Page de choix de ville et du classement saisonnier :',
	sPreferencePicthordesText: 'Liens Pict\'âme',
	sCheckboxPictLinksText: 'Dans les forums',
	sCheckboxPictLinksChoixVilleText: 'Dans la page de choix de ville',
	sCheckboxPictLinksRankText: 'Dans les pages de classements',
	
	sLinkToOeevText: 'Voir sur Oeev',
	sLinkToPatamapText: 'Voir sur Patamap',
	
	sHeadChooseMapText: 'Map',
	sHeadSoolRankText: 'Pict\'âme',
	
	sPrefTitre: ' OEEV Best Friend',
	
	/**
	 * Id
	 */
	sButtonUpdateId: 'OeevBFmaj',
	sButtonHelpId: 'OeevBFhelp',
	sButtonGotoId: 'OeevBFgoto',
	sButtonGotoPatamapId: 'patamapgoto',
	sMainDivId: 'OeevBFmainDiv',
	sButtonPrefDivId: 'sites',
	sCheckboxOeevId: 'sCheckboxOeevId',
	sCheckboxPatamapId: 'sCheckboxPatamapId',
	sCheckboxCityLinkId: 'sCheckboxCityLinkId',
	sCheckboxPictLinkId: 'sCheckboxPictLinkId',
	sCheckboxPictLinkChoixVilleId: 'sCheckboxPictLinkChoixVilleId',
	sCheckboxPictLinkRankId: 'sCheckboxPictLinkRankId',
	sLoadingId: 'sLoadingId',
	sTextUpdateId: 'sTextUpdateId',
	sMenuDivId: 'sMenuDivId',
	sCheckboxChooseOeevId: 'sCheckboxChooseOeevId',
	sCheckboxChoosePatamapId: 'sCheckboxChoosePatamapId',
	sPrefMainDivId: 'sPrefMainDivId',
	sPrefSecondDivId: 'sPrefSecondDivId',
	sPrefH1Id: 'sPrefH1Id',
	sRankDivId: 'sRankDivId',
	
	/**
	 * More Style
	 */
	sHelpStyle: 'float: right; margin-top: 0; width: 16px;',
	sUpdateStyle: '',
	sUpdateOutsideStyle: '',
	sTextLoadingStyle: 'display: none; width: 220px; height: 22px; padding: 1px 7px; line-height: 22px; color: #F0D79E; font-style: italic;',
	sIconLoadingStyle: 'width: 20px; height: 20px;',
	sClassCity: 'city',
	sMapChooseMapHeadStyle: 'width: 58px;',
	sMapChooseStyle: 'padding: 3px 1px 0px 4px; width: 20px; float: left; margin-right: 2px;',
	sEmptyCellStyle: 'text-align: center;',
	
	sPrefMainDivStyle: 'width:318px; height: 19px; margin-left: 30px; background-color:#5C2B20; border:1px solid #F0D79E; outline:1px solid black; padding-left:5px; padding-right:5px; position:absolute; top:5px; z-index:3;',
	sPrefH1Style: 'background:none repeat scroll 0 0 transparent; cursor:help; font-size:8pt; font-variant:small-caps; height:auto; margin:0; padding:0; text-transform:none; border-bottom:1px solid #B37C4A;',
	sPrefMainImgStyle: 'vertical-align:-9%;',
	sPrefSecondStyle: 'margin-top: 5px;',
	sPrefUlStyle: 'margin:-22px 0px 0px 130px; padding:0; color:#F0D79E; font-family:"Trebuchet MS","Arial",Verdana,sans-serif; font-size:8pt; font-variant:small-caps; letter-spacing:1px; line-height:15px; list-style:none outside none;',
	sPrefLiStyle: 'float:left; margin: 0px 0px 0px 2px; padding:0px 3px 0px 3px; -moz-border-radius:3px 3px 0px 0px; border:1px solid #B37C4A;',
	sPrefContentDivStyle: 'padding:3px 0px 0px 0px; clear: both; display: none;',
	
	sRankDivStyle: '',
	sDistinctionDivStyle: 'border-color: #F0D79E; color: #F0D79E; float: left; width: 182px; height: 100px; margin: 0 0 8px 8px; padding: 5px; -moz-border-radius: 10px 10px 10px 10px; background-color: #5C2B20; border: 2px solid;',
	sDistinctionOrDivStyle: 'border-color: #FED801; color: #FED801; float: left; width: 182px; height: 100px; margin: 0 0 8px 8px; padding: 5px; -moz-border-radius: 10px 10px 10px 10px; background-color: #5C2B20; border: 2px solid;',
	sDistinctionIconStyle: 'text-align: center;',
	sDistinctionTitleStyle: 'margin-bottom: 2px; text-align: center; display: block; text-decoration: none; white-space: nowrap; font-size: 12px; font-weight: bold;',
	sDistinctionEtoileDivStyle: 'color: #F0D79E; float: left; width: 20px; height: 14px; line-height: 14px; margin-top: 3px;',
	sDistinctionPseudoDivStyle: 'color: #F0D79E; float: left; width: 116px; height: 14px; line-height: 14px; padding: 0px 2px; margin-top: 3px; font-size: 12px;',
	sDistinctionTotalDivStyle: 'color: #F0D79E; float: left; width: 42px; height: 14px; line-height: 14px; text-align: right; margin-top: 3px; font-size: 12px;',
	sPlayerLinkAStyle: 'text-decoration: none;',	
	
	/**
	 * Alert the user to get the new version
	 */
	alertVersion: function(sUrl) {
		window.alert(this.sVersionText);
		GM_openInTab(sUrl);
	},
	
	/**
	 * Show the notification to the user
	 * @param {Object} oContent
	 * @param {Function} oCallback
	 */
	showNotif: function(oContent, oCallback) {
		try {
			var oNotifDiv = $(this.sNotifDivId);
			var oNotifTextDiv = $(this.sNotifTextDivId);
			if (!(oNotifDiv && oNotifTextDiv)) {
				throw new Error('Cannot find the notification markup');
			}
			this.cleanNode(oNotifTextDiv);
			if (YAHOO.lang.isObject(oContent)) {
				oNotifTextDiv.appendChild(oContent);
			}
			else {
				oNotifTextDiv.appendChild(this.addText(oNotifTextDiv, oContent, 'span'));
			}
			YAHOO.util.Dom.addClass(window.document.body, this.sNotifBodyClass);
			YAHOO.util.Dom.addClass(oNotifDiv, this.sNotifDivClass);
			window.wrappedJSObject.js.Lib.window.scrollTo(this.iScrollX, this.iScrollY);
			var oButton = OEEVBF.selector('a[class=button]', oNotifDiv, false);
			OEEVBF.addListener(oButton, 'click', oCallback);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.showNotif : ' + oError.message, true);
		}
	},
	
	/**
	 * Remove all node of the node
	 * @param {Object} oNode
	 */
	cleanNode: function(oNode) {
		if (oNode.hasChildNodes()) {
			while (oNode.childNodes.length >= 1) {
				oNode.removeChild(oNode.firstChild);
			}
		}
	},
	
	/**
	 * Remove the menu
	 */
	removeMenu: function() {
		try {
			var oMenu = $(this.sMenuDivId);
			if (oMenu) {
				oMenu.parentNode.removeChild(oMenu);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.removeMenu : ' + oError.message, true);
		}
	},
	
	/**
	 * Put a city link into target
	 * @param {Object} oTarget
	 * @param {String} sCity
	 * @param {String} sImg
	 * @param {Bool} bRebuild
	 */
	cityLink: function(oTarget, sCity, sImg, bRebuild) {
		try {
			if (bRebuild) {
				var oDiv = this.renderDiv(null, this.sClassCity);
				YAHOO.util.Dom.insertBefore(oDiv, oTarget.childNodes[0]);
				oTarget = oDiv;
			}
			var sUrl = OEEVBF.action.sCityLink + escape(sCity);
			if (sImg) {
				this.addImg(oTarget, sImg);
				this.addText(oTarget, ' ');
			}
			this.addA(oTarget, sUrl, sCity);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.cityLink : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the pict'link
	 * @param {Object} oParent
	 * @param {Object} oInsertAfter
	 * @param {Object} iPlayerId
	 */
	soulsLink: function(oParent, oInsertAfter, iPlayerId) {
		try {
			var sUrl = OEEVBF.action.sSoulLink + iPlayerId;
			var oLink = this.renderA(sUrl, this.sSoulLinkText, '_blank');
			YAHOO.util.Dom.setAttribute(oLink, 'style', 'text-decoration: underline;');
			var oText = window.document.createTextNode(' ]');
			YAHOO.util.Dom.insertAfter(oText, oInsertAfter);
			YAHOO.util.Dom.insertAfter(oLink, oInsertAfter);
			oText = window.document.createTextNode(' [ ');
			YAHOO.util.Dom.insertAfter(oText, oInsertAfter);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.soulsLink : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the pict'link as image
	 * @param {Object} oParent
	 * @param {Object} oInsertAfter
	 * @param {Object} iPlayerId
	 */
	soulsLinkAsImg: function(oParent, oInsertAfter, iPlayerId) {
		try {
			var sUrl = OEEVBF.action.sSoulLink + iPlayerId;
			var oLink = this.renderAimg(sUrl, this.sPictHordesIcon, '_blank');
			if(oInsertAfter === null && oParent !== null) {
				oParent.appendChild(oLink);
			}
			else{
				YAHOO.util.Dom.insertAfter(oLink, oInsertAfter);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.soulsLinkAsImg : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the pict'link
	 * @param {Object} oParent
	 * @param {Object} oInsertAfter
	 * @param {Object} iPlayerId
	 */
	soulsLinkChooseMap: function(oParent, oInsertAfter, iPlayerId) {
		try {
			var sUrl = OEEVBF.action.sSoulLink + iPlayerId;
			var oLink = this.renderA(sUrl, this.sSoulLinkText, '_blank');
			YAHOO.util.Dom.setAttribute(oLink, 'style', 'text-decoration: underline;');
			var oText = window.document.createTextNode(' ]');
			YAHOO.util.Dom.insertAfter(oText, oInsertAfter);
			YAHOO.util.Dom.insertAfter(oLink, oInsertAfter);
			oText = window.document.createTextNode(' [ ');
			YAHOO.util.Dom.insertAfter(oText, oInsertAfter);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.soulsLinkChooseMap : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the preference button on top of each page
	 */
	interfaceButtonPreference: function() {
		try {
			var oSiteExterne = OEEVBF.selector('div[id="gamebody"] div[id="sites"]', window.document, true);
			if (oSiteExterne) {
				var i, j, oContentDiv, oMenuUl, oMenuLi, bSelected, aPref, oSpan;
				var oCallHere = this;
				var sPrefMainDivStyle = this.sPrefMainDivStyle;
				var oPrefMainDiv = this.renderDiv(this.sPrefMainDivId, null, sPrefMainDivStyle);
				var oPrefMainH1 = window.document.createElement('h1');
				YAHOO.util.Dom.setAttribute(oPrefMainH1, 'id', this.sPrefH1Id);
				YAHOO.util.Dom.setAttribute(oPrefMainH1, 'style', this.sPrefH1Style);
				this.addImg(oPrefMainH1, this.sRpIcon, this.sButtonPrefAltText, this.sPrefMainImgStyle);
				this.addText(oPrefMainH1, this.sPrefTitre, 'span');
				oPrefMainDiv.appendChild(oPrefMainH1);
				var oText = OEEVBF.selector('span', oPrefMainDiv, true);
				YAHOO.util.Dom.setAttribute(oText, 'id', 'sMainId');
				OEEVBF.addListener(oText, 'mouseover', function(oEvent){oCallHere.showMenu.call(oCallHere, oEvent);});
				oSpan = oText;
				var oPrefContentDiv = this.renderDiv(this.sPrefSecondDivId, null, this.sPrefSecondStyle);
				oMenuUl = window.document.createElement('ul');
				for (i = 1 ; i < this.aPrefTabs.length ; i++) {
					oMenuLi = window.document.createElement('li');
					this.addText(oMenuLi, this.aPrefTabs[i], null);
					YAHOO.util.Dom.setAttribute(oMenuLi, 'style', this.sPrefLiStyle);
					YAHOO.util.Dom.setAttribute(oMenuLi, 'id', 's' + this.aPrefTabs[i] + 'Id');
					OEEVBF.addListener(oMenuLi, 'mouseover', function(oEvent){oCallHere.showMenu.call(oCallHere, oEvent);});
					oMenuUl.appendChild(oMenuLi);
				}
				YAHOO.util.Dom.setAttribute(oMenuUl, 'style', this.sPrefUlStyle);
				oPrefContentDiv.appendChild(oMenuUl);
				for (i = 0 ; i < this.aPrefTabs.length ; i++) {
					oContentDiv = this.renderDiv(null, null, null);
					switch(this.aPrefTabs[i]) {
						case 'OEEV':
							bSelected = false;
							aPref = OEEVBF.storeData.get(OEEVBF.storeData.sPrefId);
							for (i = 0, j = aPref.length ; i < j ; i++) {
								if (aPref[i] == 9) {
									bSelected = true;
									break;
								}
							}
							this.addText(oContentDiv, this.sPreferenceText);
							this.addCheckbox(oContentDiv, this.sCheckboxOeevId, this.sCheckboxOeevId, this.sCheckboxOeevText, true, true);
							this.addCheckbox(oContentDiv, this.sCheckboxPatamapId, this.sCheckboxPatamapId, this.sCheckboxPatamapText, bSelected, false);
							break;
						case 'Liens de villes':														
							this.addText(oContentDiv, this.sCheckboxCityLinksText);
							bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sPrefCityLinkId);
							this.addCheckbox(oContentDiv, this.sCheckboxCityLinkId, this.sCheckboxCityLinkId, this.sCheckboxChooseOeevText, bSelected, false);
							this.addText(oContentDiv, this.sPreferencePageChoixVilleText);
							bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sChooseOeevId);
							this.addCheckbox(oContentDiv, this.sCheckboxChooseOeevId, this.sCheckboxChooseOeevId, this.sCheckboxChooseOeevText, bSelected, false);
							bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sChoosePatamapId);
							this.addCheckbox(oContentDiv, this.sCheckboxChoosePatamapId, this.sCheckboxChoosePatamapId, this.sCheckboxChoosePatamapText, bSelected, false);
							break;
						case 'Pict\'Hordes':
							this.addText(oContentDiv, this.sPreferencePicthordesText);
							bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkId);
							this.addCheckbox(oContentDiv, this.sCheckboxPictLinkId, this.sCheckboxPictLinkId, this.sCheckboxPictLinksText, bSelected, false);
							bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkChoixVilleId);
							this.addCheckbox(oContentDiv, this.sCheckboxPictLinkChoixVilleId, this.sCheckboxPictLinkChoixVilleId, this.sCheckboxPictLinksChoixVilleText, bSelected, false);
							bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkRankId);
							this.addCheckbox(oContentDiv, this.sCheckboxPictLinkRankId, this.sCheckboxPictLinkRankId, this.sCheckboxPictLinksRankText, bSelected, false);
							break;
						default:
							this.addText(oContentDiv, this.sPrefExplainText, 'span');
							break;
					}
					YAHOO.util.Dom.setAttribute(oContentDiv, 'id', 'sDiv' + this.aPrefTabs[i] + 'Id');
					YAHOO.util.Dom.setAttribute(oContentDiv, 'style', this.sPrefContentDivStyle);
					oPrefContentDiv.appendChild(oContentDiv);
				}
				oPrefMainDiv.appendChild(oPrefContentDiv);
				aPref = OEEVBF.selector('input[type="checkbox"]', oPrefContentDiv, false);
				OEEVBF.addListener(aPref, 'click', OEEVBF.action.getAndSavePreference);
				YAHOO.util.Dom.insertAfter(oPrefMainDiv, oSiteExterne);
				this.showMenu({target: oSpan});
				this.switchPreference({type: 'mouseout'});
				OEEVBF.addListener(oPrefMainDiv, 'mouseover', function(oEvent){oCallHere.switchPreference.call(oCallHere, oEvent);});
				OEEVBF.addListener(oPrefMainDiv, 'mouseout', function(oEvent){oCallHere.switchPreference.call(oCallHere, oEvent);});
				window.setTimeout(function(){
					if (OEEVBF.selector('div[id="gamebody"] div[id="modules"]', window.document, true)) {
						YAHOO.util.Dom.setStyle('sPrefMainDivId', 'margin-left', '70px');
					}
				}, OEEVBF.manager.iTimeout);
			}
			else {
				OEEVBF.log('OEEVBF.ui.interfaceButtonPreference : cannot find the game body', true);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceButtonPreference : ' + oError.message, true);
		}
	},
	
	/**
	 * Throw out padding and with
	 */
	fixRankTable: function() {
		var aList = OEEVBF.selector('div.compactDetails');
		YAHOO.util.Dom.setStyle(aList, 'padding-left', '0px');
		aList = OEEVBF.selector('table.details');
		YAHOO.util.Dom.setStyle(aList, 'width', 'auto');
		YAHOO.util.Dom.setStyle(aList, 'margin-left', '0px');
	},
	
	/**
	 * Show only if the script is run for the first time
	 */
	interfaceFirstTime: function() {
		try {
			var oMainDiv = this.renderDiv(this.sMainDivId);
			this.addText(oMainDiv, this.sFirstTimeTitleText);
			this.addText(oMainDiv, this.sFirstTimeText, 'p');
			this.addPref(oMainDiv);
			this.showNotif(oMainDiv, OEEVBF.action.firstTimeValidation);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceFirstTime : ' + oError.message, true);
		}
	},
	
	/**
	 * Include the interface for the inside page
	 */
	interfaceInsideButton: function() {
		try {
			if (!$(this.sButtonHelpId)) {
				var oLeftMenu = OEEVBF.selector('div[class="left"]', window.document, true);
				if (!oLeftMenu) {
					throw new Error('Cannot find the left menu');
				}
				var oRegion = YAHOO.util.Dom.getRegion(oLeftMenu);
				var iWidth = oRegion.width - this.iWidthHelp;
				this.addSeparator(oLeftMenu);
				this.addText(oLeftMenu, this.sMenuTitleText, 'h2');
				/* this.addButton(oLeftMenu, this.sButtonHelpId, null, this.sHelpIcon, this.sHelpStyle, null, OEEVBF.manager.buttonClickHandler); */
				this.addButton(oLeftMenu, this.sButtonUpdateId, this.sButtonUpdateText, this.sMapIcon, this.sUpdateStyle /* + ' width: ' + iWidth + 'px;' */, null, OEEVBF.manager.buttonClickHandler);
				this.addLoading(oLeftMenu);
				this.addText(oLeftMenu, this.sMajDone, 'span', this.sTextLoadingStyle, this.sTextUpdateId);
				this.addButton(oLeftMenu, this.sButtonGotoId, this.sButtonGotoText, this.sRpIcon, null, OEEVBF.action.sSiteUrlSee, null);
				var aPref = OEEVBF.storeData.get(OEEVBF.storeData.sPrefId);
				for (var i = 0, j = aPref.length ; i < j ; i++) {
					if (aPref[i] == 9) {
						this.addButton(oLeftMenu, this.sButtonGotoPatamapId, this.sButtonGotoPatamapText, this.sPatamapIcon, null, OEEVBF.action.sSitePatamapUrlSee, null);
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceButton : ' + oError.message, true);
		}
	},
	
	/**
	 * Include the interface for the outside page
	 */
	interfaceOutsideButton: function() {
		try {
			if (!$(this.sButtonHelpId)) {
				var oLeftMenu = OEEVBF.selector('div[class="left"]', window.document, true);
				if (!oLeftMenu) {
					throw new Error('Cannot find the left menu');
				}
				var oRegion = YAHOO.util.Dom.getRegion(oLeftMenu);
				var iWidth = oRegion.width - this.iWidthHelp;
				var oMainDiv = this.renderDiv(this.sMenuDivId);
				this.addSeparator(oMainDiv);
				/* this.addButton(oMainDiv, this.sButtonHelpId, null, this.sHelpIcon, this.sHelpStyle, null, OEEVBF.manager.buttonClickHandler); */
				this.addButton(oMainDiv, this.sButtonUpdateId, this.sButtonUpdateOutsideText, this.sMapIcon, this.sUpdateOutsideStyle /* + ' width: ' + iWidth + 'px;' */, null, OEEVBF.manager.buttonClickHandler);
				this.addLoading(oMainDiv);
				this.addText(oMainDiv, this.sMajDone, 'span', this.sTextLoadingStyle, this.sTextUpdateId);
				this.addButton(oMainDiv, this.sButtonGotoId, this.sButtonGotoText, this.sRpIcon, null, OEEVBF.action.sSiteUrlSee, null);
				var aPref = OEEVBF.storeData.get(OEEVBF.storeData.sPrefId);
				for (var i = 0, j = aPref.length ; i < j ; i++) {
					if (aPref[i] == 9) {
						this.addButton(oMainDiv, this.sButtonGotoPatamapId, this.sButtonGotoPatamapText, this.sPatamapIcon, null, OEEVBF.action.sSitePatamapUrlSee, null);
					}
				}
				oLeftMenu.appendChild(oMainDiv);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceButton : ' + oError.message, true);
		}
	},
	
	/**
	 * Include the interface for the preference page
	 */
	interfacePreference: function() {
		try {
			var oMainDiv = this.renderDiv(this.sMainDivId);
			this.addText(oMainDiv, this.sFirstTimeTitleText);
			this.addText(oMainDiv, this.sPrefExplainText, 'p');
			this.addPref(oMainDiv);
			this.showNotif(oMainDiv, OEEVBF.action.getAndSavePreference);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfacePreference : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the head of links to the rows
	 */
	interfaceChooseMapHead: function(oRow) {
		try {
			var oCell;
			var bPrefOeev = OEEVBF.storeData.get(OEEVBF.storeData.sChooseOeevId);
			var bPrefPatamap = OEEVBF.storeData.get(OEEVBF.storeData.sChoosePatamapId);
			if (bPrefOeev || bPrefPatamap) {
				YAHOO.util.Dom.setAttribute(oRow.cells[0], 'colspan', 2);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceChooseMapHead : ' + oError.message, true);
		}
	},
	
	/**
	 * Ajout du header dans le tableau du classement des villes
	 */
	interfaceRankMapHead: function(oRow) {
		try {
			var oCell;
			var bPrefOeev = OEEVBF.storeData.get(OEEVBF.storeData.sChooseOeevId);
			var bPrefPatamap = OEEVBF.storeData.get(OEEVBF.storeData.sChoosePatamapId);
			if (bPrefOeev || bPrefPatamap) {
				oCell = window.document.createElement('th');
				YAHOO.util.Dom.setAttribute(oCell, 'style', this.sMapChooseMapHeadStyle);
				this.addText(oCell, this.sHeadChooseMapText, null);
				YAHOO.util.Dom.insertBefore(oCell, oRow.children[1]);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceRankMapHead : ' + oError.message, true);
		}
	},
	
	/**
	 * Ajout du header dans le tableau du classement par points d'ame
	 */
	interfaceSoolRankHead: function(oRow) {
		try {
			var oCell;
			var bPref = OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkRankId);
			if (bPref) {
				oCell = window.document.createElement('th');
				this.addText(oCell, this.sHeadSoolRankText, null);
				YAHOO.util.Dom.insertAfter(oCell, oRow.children[1]);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceSoolRankHead : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the links to the rows
	 */
	interfaceChooseMap: function(oRow, iMapId) {
		try {
			var oCell;
			var bPrefOeev = OEEVBF.storeData.get(OEEVBF.storeData.sChooseOeevId);
			var bPrefPatamap = OEEVBF.storeData.get(OEEVBF.storeData.sChoosePatamapId);
			if (bPrefOeev || bPrefPatamap) {
				oCell = this.renderCell(oRow, null, this.sMapChooseMapHeadStyle, 1);				
				if (bPrefOeev) {
					this.addButton(oCell, null, null, this.sRpIcon, this.sMapChooseStyle, OEEVBF.action.sOeevCityUrl + iMapId, null, true);
				}
				if (bPrefPatamap) {
					this.addButton(oCell, null, null, this.sPatamapIcon, this.sMapChooseStyle, OEEVBF.action.sPatamapCityUrl + iMapId, null, true);
				}		
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceChooseMap : ' + oError.message, true);
		}
	},
	
	/**
	 * Add black cells
	 */
	interfaceChooseMapEmpty: function(oRow, bText) {
		try {
			var oCell;
			var bPrefOeev = OEEVBF.storeData.get(OEEVBF.storeData.sChooseOeevId);
			var bPrefPatamap = OEEVBF.storeData.get(OEEVBF.storeData.sChoosePatamapId);
			if (bPrefOeev || bPrefPatamap) {
				oCell = this.renderCell(oRow, null, null, 1);
				if (bText) {
					YAHOO.util.Dom.setAttribute(oCell, 'style', this.sEmptyCellStyle);
					this.addText(oCell, '-', null);
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceChooseMapEmpty : ' + oError.message, true);
		}
	},
	
	/**
	 * Add table rank
	 */
	interfaceRankPictHordes: function(oData) {
		try {
			var i = null, j = null, oDistinctionDiv = null, oLineContainerDiv = null, oLineContainerUnDiv = null, oLineContainerDeuxDiv = null, oLineContainerTroisDiv = null;
			var oBandeau = OEEVBF.selector('div[class="critical"]', window.document, true);
			var oContainerDiv = this.renderDiv(this.sRankDivId, null, this.sRankDivStyle);
			YAHOO.util.Dom.insertAfter(oContainerDiv, oBandeau);
			for (i in oData) {
				if (oData[i].rare == '1') {
					oDistinctionDiv = this.renderDiv(null, null, this.sDistinctionOrDivStyle);
				}
				else {
					oDistinctionDiv = this.renderDiv(null, null, this.sDistinctionDivStyle);
				}
				oLineContainerDiv = this.renderDiv(null, null, this.sDistinctionIconStyle);
				this.addImg(oLineContainerDiv, this.sAllIcon + oData[i].img + '.gif', oData[i].name, '');
				oDistinctionDiv.appendChild(oLineContainerDiv);				
				oDistinctionLink = this.renderA(OEEVBF.action.sDistinctionLink+i, oData[i].name, '_blank', this.sDistinctionTitleStyle);
				oDistinctionDiv.appendChild(oDistinctionLink);
				var k = 0;
				for (j in oData[i].joueurs) {
					oLineContainerUnDiv = this.renderDiv(null, null, this.sDistinctionEtoileDivStyle);
					this.addImg(oLineContainerUnDiv, this.aEtoilesIcon[(oData[i].joueurs[j].rang)-1], oData[i].name, '');
					oLineContainerDeuxDiv = this.renderDiv(null, null, this.sDistinctionPseudoDivStyle);					
					oPlayerLink = this.renderA(OEEVBF.action.sSoulLink+j, oData[i].joueurs[j].pseudo, '_blank', this.sPlayerLinkAStyle);
					oLineContainerDeuxDiv.appendChild(oPlayerLink);										
					oLineContainerTroisDiv = this.renderDiv(null, null, this.sDistinctionTotalDivStyle);
					this.addText(oLineContainerTroisDiv, oData[i].joueurs[j].count, null, '');
					oLineContainerDiv = this.renderDiv(null, null, null);
					oLineContainerDiv.appendChild(oLineContainerUnDiv);
					oLineContainerDiv.appendChild(oLineContainerDeuxDiv);
					oLineContainerDiv.appendChild(oLineContainerTroisDiv);
					oDistinctionDiv.appendChild(oLineContainerDiv);
					k++;
				}
				$(this.sRankDivId).appendChild(oDistinctionDiv);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceRankPictHordes : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a empty cell
	 */
	interfaceRankEmptyCell: function(oRow, iCellPosition) {
		try {
			oCell = this.renderCell(oRow, null, null, iCellPosition);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceRankEmptyCell : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the pict'ame link
	 */
	interfaceRankPictAmeCell: function(oRow, iCellPosition, iPlayerId) {
		try {
			var sUrl = OEEVBF.action.sSoulLink + iPlayerId;
			var oLink = this.renderA(sUrl, this.sSoulLinkText, '_blank');
			oCell = this.renderCell(oRow, null, null, iCellPosition);
			oCell.appendChild(oLink);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.interfaceRankPictAmeCell : ' + oError.message, true);
		}
	},
	
	/**
	 * Montre ou masque les prefs
	 */
	switchPreference: function(oEvent) {
		try {
			if ((oEvent.type == 'mouseover') && (YAHOO.util.Dom.getStyle(this.sPrefSecondDivId, 'display') == 'none')) {
				YAHOO.util.Dom.setStyle(this.sPrefSecondDivId, 'display', 'block');
				YAHOO.util.Dom.setStyle(this.sPrefH1Id, 'border-bottom', '1px solid #B37C4A');
				YAHOO.util.Dom.setStyle(OEEVBF.selector('span', this.sPrefH1Id, false), 'display', 'inline');
				YAHOO.util.Dom.setStyle(this.sPrefMainDivId, 'width', '340px');
				YAHOO.util.Dom.setStyle(this.sPrefMainDivId, 'min-height', '140px');
				YAHOO.util.Dom.setStyle(this.sPrefMainDivId, 'height', 'auto');
				YAHOO.util.Dom.setStyle(this.sPrefMainDivId, 'padding-bottom', '2px');
			}
			else if (oEvent.type == 'mouseout') {
				YAHOO.util.Dom.setStyle(this.sPrefSecondDivId, 'display', 'none');
				YAHOO.util.Dom.setStyle(this.sPrefH1Id, 'border-bottom', 'none');
				YAHOO.util.Dom.setStyle(OEEVBF.selector('span', this.sPrefH1Id, false), 'display', 'none');
				YAHOO.util.Dom.setStyle(this.sPrefMainDivId, 'width', '16px');
				YAHOO.util.Dom.setStyle(this.sPrefMainDivId, 'min-height', '19px');
				YAHOO.util.Dom.setStyle(this.sPrefMainDivId, 'height', '19px');
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.switchPreference : ' + oError.message, true);
		}
	},
	
	/**
	 * Montre et masque les menus
	 * @param {Event} oEvent
	 */
	showMenu: function(oEvent) {
		try {
			var oTarget = oEvent ? oEvent.target : this;
			if (oTarget && oTarget.id) {
				var sLiId = null;
				var sDivId = null;
				for (var i = 0 ; i < this.aPrefTabs.length ; i++) {
					sLiId = 's' + this.aPrefTabs[i] + 'Id';
					sDivId = 'sDiv' + this.aPrefTabs[i] + 'Id';
					if (sLiId == oTarget.id) {
						if (this.aPrefTabs[i] != 'Main') {
							YAHOO.util.Dom.setStyle(sLiId, 'border-bottom', '1px solid #5C2B20');
						}
						YAHOO.util.Dom.setStyle(sDivId, 'display', 'block');
					}
					else {
						if (this.aPrefTabs[i] != 'Main') {
							YAHOO.util.Dom.setStyle(sLiId, 'border-bottom', '1px solid #B37C4A');
						}
						YAHOO.util.Dom.setStyle(sDivId, 'display', 'none');
					}
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.showMenu : ' + oError.message, true);
		}
	},
	
	/**
	 * Display or not the loading and the update button
	 * @param {Bool} bLoading
	 */
	updateLoading: function(bLoading) {
		if (bLoading) {
			YAHOO.util.Dom.setStyle(this.sButtonUpdateId, 'display', 'none');
			YAHOO.util.Dom.setStyle(this.sLoadingId, 'display', 'block');
			YAHOO.util.Dom.setStyle(this.sTextUpdateId, 'display', 'none');
		}
		else {
			YAHOO.util.Dom.setStyle(this.sButtonUpdateId, 'display', 'none');
			YAHOO.util.Dom.setStyle(this.sLoadingId, 'display', 'none');
			YAHOO.util.Dom.setStyle(this.sTextUpdateId, 'display', 'block');
			YAHOO.lang.later(this.iLoadingTimeout, this, this.endLoading, null, false);
		}
	},
	
	/**
	 * Show up the button and hide the text
	 */
	endLoading: function() {
		YAHOO.util.Dom.setStyle(this.sTextUpdateId, 'display', 'none');
		YAHOO.util.Dom.setStyle(this.sButtonUpdateId, 'display', 'block');
	},
	
	/**
	 * Preferences of OeevBF
	 * @param {Object} oTarget
	 */
	addPref: function(oTarget) {
		try {
			var bSelected = false;
			var aPref = OEEVBF.storeData.get(OEEVBF.storeData.sPrefId);
			for (var i = 0, j = aPref.length ; i < j ; i++) {
				if (aPref[i] == 9) {
					bSelected = true;
					break;
				}
			}
			var oPref = window.document.createElement('p');
			this.addText(oPref, this.sPreferenceText);
			this.addCheckbox(oPref, this.sCheckboxOeevId, this.sCheckboxOeevId, this.sCheckboxOeevText, true, true);
			this.addCheckbox(oPref, this.sCheckboxPatamapId, this.sCheckboxPatamapId, this.sCheckboxPatamapText, bSelected, false);
			oTarget.appendChild(oPref);
			oPref = window.document.createElement('p');
			this.addText(oPref, this.sPrefOptions);
			bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sPrefCityLinkId);
			this.addCheckbox(oPref, this.sCheckboxCityLinkId, this.sCheckboxCityLinkId, this.sCheckboxCityLinksText, bSelected, false);
			bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sPrefPictLinkId);
			this.addCheckbox(oPref, this.sCheckboxPictLinkId, this.sCheckboxPictLinkId, this.sCheckboxPictLinksText, bSelected, false);
			bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sChooseOeevId);
			this.addCheckbox(oPref, this.sCheckboxChooseOeevId, this.sCheckboxChooseOeevId, this.sCheckboxChooseOeevText, bSelected, false);
			bSelected = OEEVBF.storeData.get(OEEVBF.storeData.sChoosePatamapId);
			this.addCheckbox(oPref, this.sCheckboxChoosePatamapId, this.sCheckboxChoosePatamapId, this.sCheckboxChoosePatamapText, bSelected, false);
			oTarget.appendChild(oPref);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.addPref : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a button in the target given
	 * @param {Object} oTarget
	 * @param {String} sId
	 * @param {String} sText
	 * @param {String} sIcon
	 * @param {String} sStyle
	 * @param {String} sUrl
	 * @param {Function} oOnClick
	 * @param {Bool} bBlank
	 */
	addButton: function(oTarget, sId, sText, sIcon, sStyle, sUrl, oOnClick, bBlank) {
		try {
			var oButton = this.renderButton(sId, sText, sIcon, sStyle, sUrl, bBlank);
			oTarget.appendChild(oButton);
			if (oOnClick) {
				OEEVBF.addListener(oButton, 'click', oOnClick);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.addButton : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a checkbox in the target given
	 * @param {Object} oTarget
	 * @param {String} sId
	 * @param {String} sName
	 * @param {String} sText
	 * @param {Bool} bChecked
	 * @param {Bool} bDisable
	 */
	addCheckbox: function(oTarget, sId, sName, sText, bChecked, bDisable) {
		try {
			var oContainer = window.document.createElement('div');
			var oCheckbox = window.document.createElement('input');
			if (sId) {
				YAHOO.util.Dom.setAttribute(oCheckbox, 'id', sId);
			}
			YAHOO.util.Dom.setAttribute(oCheckbox, 'type', 'checkbox');
			YAHOO.util.Dom.setAttribute(oCheckbox, 'name', sName);
			if (bChecked) {
				YAHOO.util.Dom.setAttribute(oCheckbox, 'checked', 'checked');
			}
			if (bDisable) {
				YAHOO.util.Dom.setAttribute(oCheckbox, 'disabled', 'disabled');
			}
			var oLabel = window.document.createElement('label');
			YAHOO.util.Dom.setAttribute(oLabel, 'for', sId);
			oLabel.appendChild(window.document.createTextNode(sText));
			oContainer.appendChild(oCheckbox);
			oContainer.appendChild(oLabel);
			oTarget.appendChild(oContainer);
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.addCheckbox : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a text
	 * @param {Object} oTarget
	 * @param {String} sText
	 * @param {String} sTag
	 * @param {String} sStyle
	 * @param {String} sId
	 */
	addText: function(oTarget, sText, sTag, sStyle, sId) {
		try {
			if (sTag && ((sTag == 'p') || (sTag == 'span') || (sTag == 'h2'))) {
				var oContainer = window.document.createElement(sTag);
				if (sId) {
					YAHOO.util.Dom.setAttribute(oContainer, 'id', sId);
				}
				if (sStyle) {
					YAHOO.util.Dom.setAttribute(oContainer, 'style', sStyle);
				}
				oTarget.appendChild(oContainer);
				oTarget = oContainer;
			}
			var oRegex = new RegExp(this.sSplitTextBrRegex, 'g');
			var aPart = sText.split(oRegex);
			for (var i = 0, j = aPart.length ; i < j ; i++) {
				if (i != (j - 1)) {
					oTarget.appendChild(window.document.createTextNode(aPart[i]));
					oTarget.appendChild(window.document.createElement('br'));
				}
				else {
					oTarget.appendChild(window.document.createTextNode(aPart[i]));
				}
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.ui.addText : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a separator
	 * @param {Object} oTarget
	 */
	addSeparator: function(oTarget) {
		try {
			oTarget.appendChild(this.renderSeparator());
		}
		catch(oError) {
			OEEVBF.log('Error OEEVBF.ui.addSeparator : ' + oError.message, true);
		}
	},
	
	/**
	 * Add the loading
	 * @param {Object} oTarget
	 */
	addLoading: function(oTarget) {
		try {
			var oDiv = this.renderDiv(this.sLoadingId);
			oDiv.appendChild(this.renderImg(this.sLoadingIcon, this.sLoadingAltText, this.sIconLoadingStyle));
			oDiv.appendChild(this.renderImg(this.sLoadingTextIcon, this.sLoadingTextAltText));
			YAHOO.util.Dom.setStyle(oDiv, 'display', 'none');
			YAHOO.util.Dom.setStyle(oDiv, 'height', '20px');
			YAHOO.util.Dom.setStyle(oDiv, 'margin', '6px 0px');
			oTarget.appendChild(oDiv);
		}
		catch(oError) {
			OEEVBF.log('Error OEEVBF.ui.addLoading : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a link
	 * @param {Object} oTarget
	 * @param {String} sUrl
	 * @param {String} sCity
	 */
	addA: function(oTarget, sUrl, sText) {
		try {
			var oLink = this.renderA(sUrl, sText, '_blank');
			oTarget.appendChild(oLink);
		}
		catch(oError) {
			OEEVBF.log('Error OEEVBF.ui.addA : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a image
	 * @param {Object} oTarget
	 * @param {String} sUrl
	 * @param {String} sAltText
	 * @param {String} sStyle
	 */
	addImg: function(oTarget, sUrl, sAltText, sStyle) {
		try {
			var oImg = this.renderImg(sUrl, sAltText, sStyle);
			oTarget.appendChild(oImg);
		}
		catch(oError) {
			OEEVBF.log('Error OEEVBF.ui.addImg : ' + oError.message, true);
		}
	},
	
	/**
	 * Add a Div
	 * @param {Object} oTarget
	 * @param {String} sId
	 * @param {String} sClass
	 */
	addDiv: function(oTarget, sId, sClass) {
		try {
			var oImg = this.renderDiv(sId, sClass);
			oTarget.appendChild(oImg);
		}
		catch(oError) {
			OEEVBF.log('Error OEEVBF.ui.addDiv : ' + oError.message, true);
		}
	},
	
	/**
	 * Return a cell
	 * @param {Object} oTarget
	 * @param {String} sId
	 * @param {String} sStyle
	 * @param {Int} iInsertPosition
	 */
	renderCell: function(oTarget, sId, sStyle, iInsertPosition) {
		if (!YAHOO.lang.isNumber(iInsertPosition)) {
			iInsertAfter = -1;
		}
		var oCell = oTarget.insertCell(iInsertPosition);
		if (sId) {
			YAHOO.util.Dom.setAttribute(oCell, 'id', sId);
		}
		if (sStyle) {
			YAHOO.util.Dom.setAttribute(oCell, 'style', sStyle);
		}
		return oCell;
	},
	
	/**
	 * Return a button
	 * @param {String} sId
	 * @param {String} sText
	 * @param {String} sIcon
	 * @param {String} sStyle
	 * @param {String} sUrl
	 * @param {Bool} bBlank
	 */
	renderButton: function(sId, sText, sIcon, sStyle, sUrl, bBlank) {
		var oButton = window.document.createElement('a');
		YAHOO.util.Dom.addClass(oButton, 'button');
		if (sId) {
			YAHOO.util.Dom.setAttribute(oButton, 'id', sId);
		}
		if (sStyle) {
			YAHOO.util.Dom.setAttribute(oButton, 'style', sStyle);
		}
		if (bBlank) {
			YAHOO.util.Dom.setAttribute(oButton, 'target', '_blank');
		}
		if (sIcon) {
			oButton.appendChild(this.renderImg(sIcon));
			if (sText) {
				sText = ' ' + sText;
			}
		}
		if (sUrl) {
			YAHOO.util.Dom.setAttribute(oButton, 'target', '_blank');
			YAHOO.util.Dom.setAttribute(oButton, 'href', sUrl);
		}
		if (sText) {
			var oInner = window.document.createTextNode(sText);
			oButton.appendChild(oInner);
		}
		return oButton;
	},
	
	/**
	 * Return an image
	 * @param {String} sSrc
	 * @param {String} sAltText
	 * @param {String} sStyle
	 */
	renderImg: function(sSrc, sAltText, sStyle) {
		var oImg = window.document.createElement('img');
		YAHOO.util.Dom.setAttribute(oImg, 'src', sSrc);
		if (sAltText) {
			YAHOO.util.Dom.setAttribute(oImg, 'alt', sAltText);
			YAHOO.util.Dom.setAttribute(oImg, 'title', sAltText);
		}
		if (sStyle) {
			YAHOO.util.Dom.setAttribute(oImg, 'style', sStyle);
		}
		return oImg;
	},
	
	/**
	 * Return a separator
	 */
	renderSeparator: function() {
		var oSeparator = window.document.createElement('div');
		YAHOO.util.Dom.addClass(oSeparator, 'separator');
		return oSeparator;
	},
	
	/**
	 * Return a div
	 * @param {String} sId
	 * @param {String} sClass
	 * @param {String} sStyle
	 */
	renderDiv: function(sId, sClass, sStyle) {
		var oDiv = window.document.createElement('div');
		if (sId) {
			YAHOO.util.Dom.setAttribute(oDiv, 'id', sId);
		}
		if (sClass) {
			YAHOO.util.Dom.addClass(oDiv, sClass);
		}
		if (sStyle) {
			YAHOO.util.Dom.setAttribute(oDiv, 'style', sStyle);
		}
		return oDiv;
	},
	
	/**
	 * Return a A
	 * @param {String} sUrl
	 * @param {String} sText
	 * @param {String} sTarget
	 */
	renderA: function(sUrl, sText, sTarget, sStyle) {
		var oLink = window.document.createElement('a');
		YAHOO.util.Dom.setAttribute(oLink, 'href', sUrl);
		if (sTarget) {
			YAHOO.util.Dom.setAttribute(oLink, 'target', sTarget);
		}
		if (sStyle) {
			YAHOO.util.Dom.setAttribute(oLink, 'style', sStyle);
		}		
		var oInner = window.document.createTextNode(sText);
		oLink.appendChild(oInner);
		return oLink;
	},
	
	/**
	 * Return a A with a IMG content
	 * @param {String} sUrl
	 * @param {String} sImgUrl
	 * @param {String} sTarget
	 */
	renderAimg: function(sUrl, sImgUrl, sTarget) {
		var oLink = window.document.createElement('a');
		YAHOO.util.Dom.setAttribute(oLink, 'href', sUrl);
		if (sTarget) {
			YAHOO.util.Dom.setAttribute(oLink, 'target', sTarget);
		}
		var oInner = window.document.createElement('img');
		YAHOO.util.Dom.setAttribute(oInner, 'src', sImgUrl);
		oLink.appendChild(oInner);
		return oLink;
	}
};

/**
 * Manage http request (ajax)
 * @param {String} sSite
 * @param {String} sUrl
 * @param {String} sPost
 * @param {Function} oCallbackFinish
 * @param {Function} oCallbackError
 */
OEEVBF.request = function(sUrl, sPost, oCallbackFinish, oCallbackError) {
	try {
		if ((!sUrl) && (!YAHOO.lang.isString(sUrl))) {
			throw new Error('Wrong url for request');
		}
		this.sUrl = sUrl;
		if (sPost) {
			this.sPost = sPost;
		}
		if (oCallbackFinish) {
			this.oCallbackFinish = oCallbackFinish;
		}
		if (oCallbackError) {
			this.oCallbackError = oCallbackError;
		}
		if (GM_xmlhttpRequest) {
			var oAjax = this;
			var oRequest = {
				method: this.getMethod(),
				url: this.sUrl,
				onload: function(oEvent){oAjax.loadHandler.call(oAjax, oEvent);},
				onerror: function(oEvent){oAjax.errorHandler.call(oAjax, oEvent);}
			};
			if (this.getMethod() == 'post') {
				oRequest.data = this.sPost;
				oRequest.headers = this.getHeaders();
			}
			this.oRequest = GM_xmlhttpRequest(oRequest);
		}
		OEEVBF.log('OeevBF starting new request : ' + this.sUrl);
	}
	catch (oError) {
		OEEVBF.log('Error OEEVBF.request.constructor : ' + oError.message, true);
	}
};
OEEVBF.request.prototype = {
	
	/**
	 * Container
	 */
	oRequest: null,
	sUrl: '',
	sPost: '',
	oCallbackFinish: null,
	oCallbackError: null,
	
	/**
	 * Method of the request
	 */
	getMethod: function() {
		var sMethod = 'get';
		if (this.sPost !== '') {
			sMethod = 'post';
		}
		return sMethod;
	},
	
	/**
	 * Headers for http
	 */
	getHeaders: function() {
		var aHeaders = [];
		if (this.getMethod() == 'post') {
			aHeaders['Content-Type'] = 'application/x-www-form-urlencoded';
		}
		return aHeaders;
	},
	
	/**
	 * Wrapper for callback
	 * @param {Object} oEvent
	 */
	loadHandler: function(oEvent) {
		try {
			OEEVBF.log('OeevBF request loaded');
			if (this.oCallbackFinish) {
				var oData = oEvent.responseText;
				if ((oData.indexOf('{') === 0) || (oData.indexOf('[') === 0)) {
					try {
						oData = YAHOO.lang.JSON.parse(oData);
					}
					catch (oError1) {
						OEEVBF.log('Cannot decode JSON : ' + oError1.message, true);
					}
				}
				this.oCallbackFinish(oData);
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.request.loadHandler : ' + oError.message, true);
		}
	},
	
	/**
	 * Wrapper for errors
	 * @param {Object} oEvent
	 */
	errorHandler: function(oEvent) {
		try {
			OEEVBF.log('OeevBF request failed');
			if (this.oCallbackError) {
				this.oCallbackError();
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.request.errorHandler : ' + oError.message, true);
			OEEVBF.log(oEvent, true);
		}
	}
};

/**
 * Store, load datas
 */
OEEVBF.storeData = {
	
	/**
	 * Parameters
	 */
	sOeevId: 'sOeev',
	sVersionId: 'sVersion',
	sApiKeyId: 'sApiKey',
	sPrefId: 'sPrefId',
	sPrefCityLinkId: 'sPrefCityLinkId',
	sPrefPictLinkId: 'sPrefPictLinkId',
	sChoosePatamapId: 'sChoosePatamapId',
	sChooseOeevId: 'sChooseOeevId',
	sPrefPictLinkChoixVilleId: 'sPrefPictLinkChoixVilleId',
	sPrefPictLinkRankId: 'sPrefPictLinkRankId',
	
	/**
	 * Containers
	 */
	oData: {},
	
	/**
	 * Set a user data
	 * @param {String} sKey
	 * @param {Object} oValue
	 */
	set: function(sKey, oValue) {
		OEEVBF.storeData.oData[sKey] = oValue;
		OEEVBF.storeData.store();
	},
	
	/**
	 * Get a user data
	 * @param {String} sKey
	 */
	get: function(sKey) {
		return OEEVBF.storeData.oData[sKey];
	},
	
	/**
	 * Persistent storage load of data
	 */
	load: function() {
		try {
			var oData = GM_getValue(OEEVBF.storeData.sOeevId);
			if (oData) {
				OEEVBF.storeData.oData = YAHOO.lang.JSON.parse(oData);
			}
			else {
				throw new Error('No data in memory');
			}
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.storeData.load : ' + oError.message, true);
		}
	},
	
	/**
	 * Persistent storage for data
	 */
	store: function() {
		try {
			GM_setValue(OEEVBF.storeData.sOeevId, YAHOO.lang.JSON.stringify(OEEVBF.storeData.oData));
		}
		catch (oError) {
			OEEVBF.log('Error OEEVBF.storeData.store : ' + oError.message, true);
		}
	}
};

/**
 * OeevBestFriend initialization
 */
window.setTimeout(OEEVBF.manager.first, OEEVBF.manager.iTimeout);

})();
