/*
	Copyright © 2006, JFG Networks, All rights reserved
*/
////////////////////////////////////////////////////////////////////////////////
// OB Lib.js by hadrien at over-blog dot com                                  //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Required																	  //
////////////////////////////////////////////////////////////////////////////////
/**
 * URL to Javascripts files
 */
var JSUrl;
/**
 * URL to CSS files
 */
var CSSUrl;
/**
 * URL to images
 */
var IMGUrl;
var DEBUG = false;


// YUI Shortcuts
var yahooIsHere = false;
try {
	var _YUD =  YAHOO.util.Dom;
	yahooIsHere = true;
} catch (e) {
	_YUD =  false;
}
try {
	var _YUDD =  YAHOO.util.DD;
	yahooIsHere = true;
} catch (e) {
	_YUDD =  false;
}
try {
	var _YUDDP =  YAHOO.util.DDProxy;
	yahooIsHere = true;
} catch (e) {
	_YUDDP =  false;
}
try {
	var _YUA =  YAHOO.util.Anim;
	yahooIsHere = true;
} catch (e) {
	_YUA =  false;
}
try {
	var _YUE =  YAHOO.util.Event;
	yahooIsHere = true;
} catch (e) {
	_YUE =  false;
}
try {
	var _YUC =  YAHOO.util.Connect;
	yahooIsHere = true;
} catch (e) {
	_YUC =  false;
}
if (!yahooIsHere) {
	var YAHOO = false;
}




////////////////////////////////////////////////////////////////////////////////
// Global Static Methods													  //
////////////////////////////////////////////////////////////////////////////////

/**
 * OB_Log adds a new log line in console or in a new div into webpage.
 * @author Hadrien Lanneau hadrien at overblog dot com
 * @param {String} data String to log.
 */
function OB_Log(data)
{
	if (window.console)
	{
		window.console.log(data);
	}
	else
	{
		alert(data);
	}
};

// Enhancemebnt des objets génériques
String.prototype.trim = function()
{
	return this.replace(/^\s+|\s+$/g,"");
};

String.prototype.strip = function()
{
	return this.replace(/(<([^>]+)>)/ig, '').replace('>','').replace('<','');
};

String.prototype.space = function()
{
	return this.replace(/_/g, ' ');
};


var truncate = function(s_totruncate, i_length, s_etc, b_break_words)
{
	if (!s_totruncate)
	{
		return '';
	}
	if (!i_length)
	{
		i_length = 80;
	}
	if (!s_etc)
	{
		s_etc = '…';
	}
	if (!b_break_words)
	{
		b_break_words = false;
	}

	if (s_totruncate.length == 0 )
	{
		return '';
	}

	if (s_totruncate.length > i_length)
	{
		i_length = i_length - s_etc.length;
		if (b_break_words)
		{
			s_totruncate.substring(
					0,
					i_length + 1
					);
			s_totruncate.replace(
					'/\s+?(\S+)?$/',
					''
					);
		}

		return s_totruncate.substring(
				0,
				i_length
				) + s_etc;
	}
	else
	{
		return s_totruncate;
	}
};


var showEl = function(el, effect)
{
	el = getElmt(el);
	if (el)
	{
		if (!effect)
		{
			el.style.display = 'block';
		}
		else
		{
			// ajouter l'effet
			switch (effect)
			{
				case 'height':
					el.style.height = 'auto';
					el.style.overflow = 'visible';
					break;
			}
		}
	}
};

var hideEl = function(el, effect)
{
	el = getElmt(el);
	if (el)
	{
		if (!effect)
		{
			el.style.display = 'none';
		}
		else
		{
			// ajouter l'effet
			switch (effect)
			{
				case 'height':
					el.style.height = 0;
					el.style.overflow = 'hidden';
					break;
			}
		}
	}
};

var destroyEl = function(elArr)
{
	var el = getElmt(elArr);
	if (el.parentNode)
	{
		el.parentNode.removeChild(el);
	}
	else if (elArr[0])
	{
		for (var i = 0; elArr[i]; i++)
		{
			destroyEl(elArr[i]);
		}
	}
};

/**
 * Create an a node
 * @param {String} href the url to link
 * @param {String} classe classes associated with the link
 * @param {String} id the link id
 * @param {String} innerText the text to put the link on
 * @returns an A node
 * @type node
 */
function createLink(href, classe , id , innerText){
	var nLink = document.createElement('a');

	if(typeof('href') != 'undefined'){
		nLink.setAttribute('href',href);
	}

	if(typeof('class') != 'undefined'){
		nLink.setAttribute('class',classe);
	}

	if(typeof('id') != 'undefined'){
		nLink.setAttribute('id',id);
	}

	if(typeof('innerText') != 'undefined'){
		var nText = document.createTextNode(innerText);
		nLink.appendChild(nText);
	}
	return nLink ;
};


/**
 * Get a reference to an element by itself or by its ID
 * @author Hadrien Lanneau hadrien at overblog dot com
 * @param {String/Element} Element or Id of Element
 * @returns Element
 * @type Element
 */
function getElmt(elmt) {
	if (typeof elmt == 'string') {
		return document.getElementById(elmt);
	} else {
		return elmt;
	}
};

/**
 * Get user navigator
 * @author Hadrien Lanneau hadrien at overblog dot com
 * @returns Accronym of user browser ('ie' => Internet Explorer, 'mz' => Mozilla, 'sf' => Safari, 'op' => Opera)
 * @type String
 */
function getBrowser() {
	if (navigator.appName.indexOf('Internet Explorer') != -1)
	{
		if (navigator.appVersion.indexOf('MSIE 7') != -1)
		{
			return 'ie7';
		}
		return 'ie';
	}
	if (navigator.appName.indexOf('Opera') != -1)
	{
		return 'op';
	}
	if (navigator.appVersion.indexOf('Safari') != -1)
	{
		return 'sf';
	}
	if (navigator.appName.indexOf('Konqueror') != -1)
	{
		return 'kq';
	}
	if (navigator.appCodeName.indexOf('Mozilla') != -1)
	{
		return 'mz';
	}
};
// Translations
var language;
var localizedFile;
/**
 * Get a localised string
 * @author Hadrien Lanneau hadrien at overblog dot com
 * @param {String} String you want to translate
 * @returns The translated string if found in dictionary or same string
 * @type String
 */
function getLocalizedString(str)
{
	try
	{
		if (localizedString && localizedString[str])
		{
			return localizedString[str];
		}
	}
	catch (e)
	{
		return str;
	}
	return str;
};

/**
 * Test if a key press event is a numerical key
 * @param {Event} Window event (event)
 * @returns True if typed key is a numerical key or a special key, false if not
 * @type Boolean
 */
function numericKeysOnly(e) {
	var key =  _YUE.getEvent(e).keyCode;
	if ((key > 47 && key < 58) ||	// numbers on principal keyboard
			(key > 95 && key < 106) ||	// numbers pad
			(key == 8) ||					// delete
			(key == 13) ||				// enter
			(key == 27) ||				// escape
			(key == 46) ||				// suppr
			(key == 188) ||				// coma
			(key == 190)) {				// dot
		return key;
	}
	return false;
};

/**
 * toggle
 */
var toggle = function(elmt, display)
{
	elmt = getElmt(elmt);
	if (!display)
	{
		display = 'block';
	}
	if (elmt.style.display == display ||
			elmt.style.display == '')
	{
		elmt.style.display = 'none';
	}
	else
	{
		elmt.style.display = display;
	}
	return true;
};

/**
 * Trim
 */
function trim(s)
{
	return s.trim();
};

/*
 * Display a confirm message when leaving page
 */
var confirmOnQuit = function(str)
{
	if (str)
	{
		window.onbeforeunload = function()
		{
			return str;
		};
		document.body.onbeforeunload = function()
		{
			return str;
		};
		return true;
	}
	else
	{
		window.onbeforeunload = new Function();
		document.body.onbeforeunload = new Function();
		return true;
	}
};

/**
 * Set alt lines on a list
 * @param {String/Element} list ID of ul list to render
 */
var setAltLines = function(list)
{
	list = getElmt(list);
	if (!list)
	{
		return false;
	}

	// Si on est dans une liste
	var elmts = list.getElementsByTagName('li');
	if (elmts.length == 0)
	{
		// Sinon on est dans un tableau
		elmts = list.getElementsByTagName('tr');
	}

	var alt = false;
	for (var i = 1; elmts[i]; i++)
	{
		if (alt)
		{
			_YUD.addClass(
					elmts[i],
					'alt'
					);
			alt = false;
		}
		else
		{
			_YUD.removeClass(
					elmts[i],
					'alt'
					);
			alt = true;
		}
		elmts[i].onmouseover = function()
		{
			_YUD.addClass(
					this,
					'over'
					);
		};
		elmts[i].onmouseout = function()
		{
			_YUD.removeClass(
					this,
					'over'
					);
		};
	}
};

var OB_AutoInputs = new Array();
/**
 * Create a new OB_AutoInputs object
 * @deprecated
 * @param {Element} element Input element where data will be put
 * @param {Boolean} withPlus Add a "plus" button to add new item
 * @constructor
 */
var OB_AutoInput = function(element, withPlus, params) {
	/**
	 * Input where data have to be register
	 * @type Element
	 */
	this.element = getElmt(element);
	/**
	 * New Ul list
	 * @type Element
	 */
	this.newElement = null;
	/**
	 * Array of items
	 * @type Array
	 */
	this.items = new Array();
	/**
	 * With plus button or not
	 * @type Boolean
	 */
	this.withPlus = withPlus;
	/**
	 * Function on Input focus
	 * @type Function
	 */
	this.focusEvent = null;
	if (params && params.focusEvent) {
		this.focusEvent = params.focusEvent;
	}
	/**
	 * Function on Input blur
	 * @type Function
	 */


	this.blurEvent = null;
	if (params && params.blurEvent) {
		this.blurEvent = params.blurEvent;
	}
	/**
	 * Id of auto input
	 * @type Integer
	 */
	this.id = null;
	////////////////////////////////
	OB_AutoInputs.push(this);
	this.id = OB_AutoInputs.length;

	if (getBrowser() != 'sf') { // Désactivé sous Safari pour cause de plantage
		this.init();
	}
};
OB_AutoInput.prototype = {
	/**
	 * Initialization
	 */
init: function() {
		  this.newElement = document.createElement('ul');
		  this.element.parentNode.insertBefore(this.newElement, this.element);
		  this.element.style.display = 'none';

		  // splite toute les valeurs de l'input afin de creer un item pour chaque tag
		  if (this.element.value != '') {
			  var values = this.element.value.split(',');

			  for (var i = 0; values[i]; i++) {
				  this.addItem(values[i]);
			  }
		  } else {
			  this.addItem(getLocalizedString('nouveau tag'));
		  }
	  },
	  /**
	   * Add an item to the list
	   * @param {String} str String value to insert into new item
	   */
addItem: function(str) {
			 var newItem = new OB_AutoInputItem(str);
			 this.items.push(newItem);
			 this.redraw();
		 },
		 /**
		  * Delete an item from list
		  * @param {OB_AutoInputItem} item Item to delete
		  */
deleteItem: function(item) {
				if (this.items.length > 1) {
					this.items.splice(this.getInputPosition(item), 1);
					this.redraw();
				} else {
					this.items[0].value = getLocalizedString('nouveau tag');
					this.redraw();
				}
				this.serialize();
			},
			/**
			 * Redraw list
			 */
redraw: function() {
			this.newElement.innerHTML = '';
			for (var i = 0; this.items[i]; i++) {
				this.items[i].init();
				this.newElement.appendChild(this.items[i].element);
			}
			if (this.withPlus) { // Bouton plus pour ajouter des champs
				newLi = document.createElement('li');
				newLi.style.display = 'inline';
				newLi.style.position = 'relative';
				newLi.parent = this;
				newLi.onclick = function() {
					this.parent.addItem(getLocalizedString('nouveau tag'));
				};
				newDiv = document.createElement('div');
				newDiv.style.background = 'url("'+IMGUrl+'tiplus.gif") center no-repeat';
				newLi.style.position = 'absolute';
				newDiv.style.width = '12px';
				newDiv.style.height = '1em';
				newLi.appendChild(newDiv);
				this.newElement.appendChild(newLi);
			}
		},
		/**
		 * Put a serialization of all items'value in value attribute of original input element.
		 * Concatenate all value and separate it with coma.
		 */
serialize: function() {
			   // retourne une chaine de chaque inputs.value séparés par des virgules
			   var str = '';
			   for (var i = 0; this.items[i]; i++) {
				   if (this.items[i].value != getLocalizedString('nouveau tag')) {
					   str += this.items[i].value;
					   if (this.items[i+1] && this.items[i+1].value != getLocalizedString('nouveau tag')) {
						   str += ',';
					   }
				   } else {
					   str = '';
				   }
			   }
			   this.element.value = str;
		   },
		   /**
			* Get position of an OB_AutoInputItem into inputs array
			* @param {OB_AutoInputItem} OB_AutoInputItem to get its position
			* @returns Position or false if not found
			* @type {Integer}
			*/
getInputPosition: function(input) {
					  for (var i = 0; this.items[i]; i++) {
						  if (this.items[i] == input) {
							  return i;
						  }
					  }
					  return false;
				  },
				  /**
				   * Add Focus Event
				   */
addFocusEvent: function(func) {
				   this.focusEvent = func;
			   },
			   /**
				* Destroy Auto Input
				*/
destroy: function() {
			 this.serialize();
			 this.newElement.parentNode.removeChild(this.newElement);
			 this.element.style.display = 'inline';
		 },
		 /**
		  * Get a string representation of object
		  * @returns String representation of object
		  * @type String
		  */
toString: function() {
			  return 'OB_AutoInput_'+this.id;
		  }
};
/**
 * Return an OB_AutoInput object which contains OB_AutoInputItem in parameter
 * @param {OB_AutoInputItem} OB_AutoInputItem contained into OB_AutoInput you're looking for
 * @returns OB_AutoInput
 * @type OB_AutoInput
 */
OB_AutoInput.getAutoInputByItem = function(item) {
	for (var i = 0; OB_AutoInputs[i]; i++) {
		for (var j = 0; OB_AutoInputs[i].items[j]; j++) {
			if (OB_AutoInputs[i].items[j] == item) {
				return OB_AutoInputs[i];
			}
		}
	}
	return false;
};









var OB_AutoInputItems = new Array();
/**
 * Create a new OB_AutoInputItem object
 * @param {String} str Value of item
 * @deprecated
 * @constructor
 */
var OB_AutoInputItem = function(str) {
	/**
	 * Value of item
	 * @type String
	 */
	this.value = str;
	/**
	 * Element which represents item
	 * @type Element
	 */
	this.element = null;
	/**
	 * Id of item
	 * @type Integer
	 */
	this.id = null;
	////////////////////////////////
	OB_AutoInputItems.push(this);
	this.id = OB_AutoInputItems.length;
	this.init();
};
OB_AutoInputItem.prototype = {
	/**
	 * Initialization.
	 * Create HTML elements and add events.
	 */
init: function() {
		  this.element = document.createElement('li');
		  this.element.style.display = 'inline';
		  this.element.style.marginRight = '0.2em';
		  this.element.style.position = 'relative';

		  // Text
		  var newSpan = document.createElement('span');
		  newSpan.innerHTML = this.value+',';
		  this.element.appendChild(newSpan);
		  this.element.newSpan = newSpan;

		  // Input
		  var newInput = document.createElement('input');
		  newInput.value = this.value;
		  newInput.style.display = 'none';
		  newInput.style.border = '1px solid #ccc';
		  newInput.style.width = (this.value.length+1)*0.7+'em';
		  newInput.style.fontFamily = 'monospace';
		  newInput.parent = this;
		  newInput.onblur = function() {
			  if (this.value == '') {
				  OB_AutoInput.getAutoInputByItem(this.parent).deleteItem(this.parent)
			  } else {
				  this.value = this.value.replace(new RegExp('<.*?>', 'gi'), ''); // Striptags
				  this.parent.value = this.value;
				  newSpan.innerHTML = this.parent.value+',';
				  if (OB_AutoInput.getAutoInputByItem(this.parent)) {
					  OB_AutoInput.getAutoInputByItem(this.parent).serialize();
				  }
				  newInput.style.display = 'none';
				  newSpan.style.display = 'inline';
			  }
			  if (OB_AutoInput.getAutoInputByItem(this.parent).blurEvent) {
				  OB_AutoInput.getAutoInputByItem(this.parent).blurEvent();
			  }
		  };
		  newInput.onkeydown = function(event) {
			  var e =  _YUE.getEvent(event);
			  if (e.keyCode == 13) {
				  return false;
			  }
		  };
		  newInput.onkeypress = function(event) {
			  if (parseInt(this.value.length) < 3) {
				  this.style.width = '2em';
			  } else {
				  this.style.width = (this.value.length+1)*0.6+'em';
			  }
		  };
		  newInput.onfocus = function() {
			  setTimeout(function() {newInput.select();}, 1);
			  if (OB_AutoInput.getAutoInputByItem(this.parent).focusEvent) {
				  OB_AutoInput.getAutoInputByItem(this.parent).focusEvent();
			  }
		  };
		  this.element.appendChild(newInput);

		  // Close button
		  var newButton = document.createElement('div');
		  newButton.style.background = 'url("'+IMGUrl+'ticlose.gif") center no-repeat';
		  newButton.style.width = '12px';
		  newButton.style.height = '1em';
		  newButton.style.position = 'absolute';
		  newButton.style.top = 0;
		  newButton.style.left = 0;
		  newButton.style.visibility = 'hidden';
		  newButton.onclick = function() {
			  var OBItem = OB_AutoInputItem.getAutoInputItemByElmt(this.parentNode);
			  OB_AutoInput.getAutoInputByItem(OBItem).deleteItem(OBItem);
		  };
		  this.element.appendChild(newButton);
		  this.element.style.paddingLeft = '12px';

		  // Events
		  this.element.onmouseover = function() {
			  newButton.style.visibility = 'visible';
		  };
		  this.element.onmouseout = function() {
			  newButton.style.visibility = 'hidden';
		  };
		  this.element.onclick = function() {
			  newSpan.style.display = 'none';
			  newInput.style.display = 'inline';
			  //setTimeout(function() {newInput.select();newInput.focus();}, 1);
			  newInput.focus();
		  };

	  },
	  /**
	   * Get a string representation of object
	   * @returns String representation of object
	   * @type String
	   */
toString: function() {
			  return 'OB_AutoInputItem_'+this.id;
		  }
};
/**
 * Get an OB_AutoInputItem object by its Element
 * @param {Element/String} elmt Element or its id
 * @returns OB_AutoInputItem object which contains elmt
 * @type OB_AutoInputItem
 */
OB_AutoInputItem.getAutoInputItemByElmt = function(elmt) {
	for (var i = 0; OB_AutoInputItems[i]; i++) {
		if (OB_AutoInputItems[i].element == getElmt(elmt)) {
			return OB_AutoInputItems[i];
		}
	}
	return false;
};




var OB_Editors = new Array();
/**
 * OB_Editor class
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_Editor = function(elmt, params)
{
	/**
	 * Element
	 * @type Element
	 */
	this.element = getElmt(elmt);
	/**
	 * ID
	 * @type String
	 */
	this.id = null;
	/**
	 * Parameters
	 * @type Object
	 */
	this.params = params ?
		params :
		{};
	/**
	 * Function to fire on editor init
	 * @type Function
	 */
	this.onEditorInit = new Function();
	if (this.element)
	{
		OB_Editors.push(this);
		if (this.element.id)
		{
			this.id = this.element.id;
		}
		else
		{
			this.id = 'OB_Editor_' + OB_Editors.length;
			this.element.id = this.id;
		}
		this.init();
	}
	else
	{
		throw "No element specified. Can't initialize OB_Editor.";
	}
};
OB_Editor.prototype =
{
	/**
	 * Init
	 */
	init: function()
	{
		this.tmceParams = null;
		this.tmceParams = {
			mode: 'exact',
			elements: this.id
		};

		// If locales is not well set
		if (!this.params.lang |
				this.params.lang != 'fr' &&
				this.params.lang != 'en' &&
				this.params.lang != 'de' &&
				this.params.lang != 'it' &&
				this.params.lang != 'es')
		{
			this.params.lang = 'fr';
		}

		// paramètres de la toolbar
		this._getToolbar(
			this.params.toolbar ?
			this.params.toolbar :
			null
		);

		// Paramètres globaux
		this.tmceParams.theme = 'advanced';
		this.tmceParams.skin = 'OB';
		this.tmceParams.paste_auto_cleanup_on_paste = false;
		this.tmceParams.inlinepopups_skin = 'OBinlineDialog';
		this.tmceParams.theme_advanced_toolbar_location = 'top';
		this.tmceParams.theme_advanced_toolbar_align = 'left';
		this.tmceParams.theme_advanced_resizing = false;
		this.tmceParams.theme_advanced_styles = getLocalizedString('style.Citation') + ' = hitcitation; ' +
			getLocalizedString('style.Encart') + ' = hitencart; ' +
			getLocalizedString('style.Important') + ' = hitimportant; ' +
			getLocalizedString('style.perso1') + ' = hitperso1; ' +
			getLocalizedString('style.perso2') + ' = hitperso2';
		this.tmceParams.extended_valid_elements = '*[*],img[*],object[*|type|id],em[*|class],b[*|class]';
		this.tmceParams.font_size_style_values = '8pt,10pt,12pt,14pt,18pt,24pt,36pt';
		if (this.params.normalNewLines)
		{
			this.tmceParams.force_br_newlines = false;
			this.tmceParams.forced_root_block = 'p';
		}
		else
		{
			this.tmceParams.force_br_newlines = true;
			this.tmceParams.forced_root_block = '';
		}

		if (this.params.cssUrl)
		{
			this.tmceParams.content_css = this.params.cssUrl;
		}

		// url absolues
		this.tmceParams.convert_urls = false;

		if (this.params.width)
		{
			this.tmceParams.width = this.params.width;
		}
		if (this.params.height)
		{
			this.tmceParams.height = this.params.height;
		}
		this.tmceParams.language = this.params.lang ?
			this.params.lang :
			'fr';
		if (this.params.urls)
		{
			this.tmceParams.urls = this.params.urls;
		}

		if (this.params.onInit)
		{
			this.onEditorInit = this.params.onInit;
		}
		if (this.params.onKeyPress)
		{
			this.tmceParams.onKeyPress = this.params.onKeyPress;
			this.tmceParams.setup = function(ed)
			{
				ed.onKeyPress.add(ed.settings.onKeyPress);
			}
		}

		// On editor instanciation, set this.editor and class to body
		this.tmceParams.init_instance_callback = function(inst)
		{
			var obe = OB_Editor.getById(
				this.editorId
			);
			obe.editor = this;
			if (obe.params &&
					obe.params.bodyClass)
			{
				this.getBody().className = obe.params.bodyClass;
			}
			if (obe.onEditorInit)
			{
				obe.onEditorInit();
			}
		}
		// Initialisation
		tinymce.EditorManager.init(
			this.tmceParams
		);
		tinymce.editor = true;
	},
	/**
	 * _getToolbar
	 */
	_getToolbar: function(toolbar)
	{
		switch (toolbar)
		{
			// 1
			case OB_Editor.TOOLBAR_ADVANCED:
				this.tmceParams.plugins = 'safari,style,table,advimage,advlink,iespell,inlinepopups,media,searchreplace,OB_ContextMenu,paste,fullscreen,visualchars,spellchecker,OB_Align,OB_Smileys';
				//Theme options
				var tn = 1;
				if (this.params.urls)
				{
					var sep = '';
					this.tmceParams['theme_advanced_buttons' + tn] = '';
					if (this.params.urls.OB_Pictures)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Pictures,|';
						this.tmceParams.plugins += ',OB_Pictures';
						sep = ',';
					}
					if (this.params.urls.OB_Videos)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Videos,|';
						this.tmceParams.plugins += ',OB_Videos';
						sep = ',';
					}
					if (this.params.urls.OB_Music)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Music,|';
						this.tmceParams.plugins += ',OB_Music';
						sep = ',';
					}
					if (this.params.urls.OB_Links_add)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Links_Add,|,OB_Links_Rm';
						this.tmceParams.plugins += ',OB_Links';
						sep = ',';
					}
					tn ++;
				}
				this.tmceParams['theme_advanced_buttons' + tn] = 'bold,italic,underline,strikethrough,|,sub,sup,|,forecolor,backcolor,|,OB_Align_Left,OB_Align_Center,OB_Align_Right,OB_Align_Justify,|,bullist,numlist,|,outdent,indent,|,link,unlink,|,removeformat,fullscreen,OB_Smileys';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = 'fontselect,fontsizeselect' + (this.params.cssUrl ? ',styleselect' : '') + ',formatselect';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = 'code,|,undo,redo,|,hr,|,cut,copy,paste,pastetext,pasteword,|,search,replace,|,charmap,spellchecker,|,tablecontrols';
				this.tmceParams.theme_advanced_statusbar_location = 'bottom';

				this._setSpellchecker();
				break;

				// 2
			case OB_Editor.TOOLBAR_TEXTELIBRE:
				this.tmceParams.plugins = 'safari,style,table,advimage,advlink,iespell,inlinepopups,media,searchreplace,OB_ContextMenu,paste,fullscreen,visualchars,spellchecker,OB_Align,OB_Smileys';
				//Theme options
				var tn = 1;
				if (this.params.urls)
				{
					var sep = '';
					this.tmceParams['theme_advanced_buttons' + tn] = '';
					if (this.params.urls.OB_Pictures)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Pictures,|';
						this.tmceParams.plugins += ',OB_Pictures';
						sep = ',';
					}
					if (this.params.urls.OB_Videos)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Videos,|';
						this.tmceParams.plugins += ',OB_Videos';
						sep = ',';
					}
					if (this.params.urls.OB_Music)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Music,|';
						this.tmceParams.plugins += ',OB_Music';
						sep = ',';
					}
					if (this.params.urls.OB_Links_add)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Links_Add,|,OB_Links_Rm';
						this.tmceParams.plugins += ',OB_Links';
						sep = ',';
					}
					tn ++;
				}
				this.tmceParams['theme_advanced_buttons' + tn] = 'bold,italic,underline,|,forecolor,backcolor,|,OB_Align_Justify,OB_Align_Left,OB_Align_Center,OB_Align_Right,|,bullist,numlist,|,cut,copy,paste,pasteword,|,search,replace,|,link,unlink,|,undo,redo,|,removeformat,OB_Smileys';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = 'code,|,fontselect,fontsizeselect' + (this.params.cssUrl ? ',styleselect' : '') + ',|,tablecontrols';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = '';
				break;

				// 3
			case OB_Editor.TOOLBAR_COMMENTS:
				this.tmceParams.plugins = 'safari,inlinepopups,paste,OB_Align,OB_Smileys,OB_lightlink,OB_lightimg';
				// Theme options
				this.tmceParams.theme_advanced_buttons1 = 'bold,italic,underline,|,forecolor,backcolor,|,OB_Align_Left,OB_Align_Center,OB_Align_Right,bullist,|,OB_Smileys,OB_lightlink,OB_lightimg,undo,redo';
				this.tmceParams.theme_advanced_buttons2 = '';
				this.tmceParams.theme_advanced_buttons3 = '';
				this.tmceParams.theme_advanced_buttons4 = '';
				break;

				// 3
			case OB_Editor.TOOLBAR_RESPONSE:
				this.tmceParams.plugins = 'safari,inlinepopups,paste,OB_Align,OB_Smileys,OB_lightlink,OB_lightimg';
				// Theme options
				this.tmceParams.theme_advanced_buttons1 = 'bold,italic,underline,|,forecolor,backcolor,|,OB_Align_Left,OB_Align_Center,OB_Align_Right,OB_Align_Justify,|,bullist,numlist,|,OB_lightimg,OB_Smileys,OB_lightlink,unlink,|,undo,redo,|,code';
				this.tmceParams.theme_advanced_buttons2 = '';
				this.tmceParams.theme_advanced_buttons3 = '';
				this.tmceParams.theme_advanced_buttons4 = '';
				break;

										// 4
			case OB_Editor.TOOLBAR_FORUM:
				this.tmceParams.plugins = 'safari,style,OB_lightlink,inlinepopups,paste,visualchars,emotions';
				// Theme options
				this.tmceParams.theme_advanced_buttons1 = 'bold,italic,underline,|,bullist,numlist,|,OB_lightlink,unlink,|,undo,redo,|,emotions';
				this.tmceParams.theme_advanced_buttons2 = '';
				this.tmceParams.theme_advanced_buttons3 = '';
				this.tmceParams.theme_advanced_buttons4 = '';
				break;

                                                 // 3
			case OB_Editor.TOOLBAR_SA:
				this.tmceParams.plugins = 'safari,inlinepopups,paste,OB_Align,OB_lightlink';
				// Theme options
				var tn = 1;
				if (this.params.urls)
				{
					this.tmceParams['theme_advanced_buttons' + tn] = '';
					if (this.params.urls.OB_Pictures)
					{
						this.tmceParams.theme_advanced_buttons1 = 'OB_Pictures';
						this.tmceParams.plugins += ',OB_Pictures';
					}
					tn ++;
				}
				this.tmceParams['theme_advanced_buttons' + tn] = 'bold,italic,underline,|,forecolor,backcolor,|,OB_Align_Left,OB_Align_Center,OB_Align_Right,OB_Align_Justify,|,bullist,numlist,|,OB_Smileys,OB_lightlink,unlink,|,undo,redo,|,code';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = '';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = '';
				break;
			
			// 7
			case OB_Editor.TOOLBAR_BLOGPOOL:
				this.tmceParams.plugins = 'safari,inlinepopups,OB_Smileys,OB_lightlink,OB_lightimg';
				this.tmceParams.theme_advanced_buttons1 = 'bold,italic,underline,|,forecolor,backcolor,|,OB_lightlink,OB_lightimg,|,undo,redo,|,code';
				this.tmceParams.theme_advanced_buttons2 = '';
				this.tmceParams.theme_advanced_buttons3 = '';
				this.tmceParams.theme_advanced_buttons4 = '';
				break;

				// 0
			case OB_Editor.TOOLBAR_SIMPLE:
			default:
				this.tmceParams.plugins = 'safari,style,table,advimage,advlink,iespell,inlinepopups,media,searchreplace,OB_ContextMenu,paste,fullscreen,visualchars,spellchecker,OB_Align,OB_Smileys';
				//Theme options
				var tn = 1;
				if (this.params.urls)
				{
					var sep = '';
					this.tmceParams['theme_advanced_buttons' + tn] = '';
					if (this.params.urls.OB_Pictures)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Pictures,|';
						this.tmceParams.plugins += ',OB_Pictures';
						sep = ',';
					}
					if (this.params.urls.OB_Videos)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Videos,|';
						this.tmceParams.plugins += ',OB_Videos';
						sep = ',';
					}
					if (this.params.urls.OB_Music)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Music,|';
						this.tmceParams.plugins += ',OB_Music';
						sep = ',';
					}
					if (this.params.urls.OB_Links_add)
					{
						this.tmceParams.theme_advanced_buttons1 += sep + 'OB_Links_Add,|,OB_Links_Rm';
						this.tmceParams.plugins += ',OB_Links';
						sep = ',';
					}
					tn ++;
				}
				this.tmceParams['theme_advanced_buttons' + tn] = 'bold,italic,underline,|,forecolor,backcolor,|,OB_Align_Justify,OB_Align_Left,OB_Align_Center,OB_Align_Right,|,bullist,|,outdent,indent,|,undo,redo,|,hr,|,cut,copy,paste,pastetext,pasteword,|,spellchecker,|,search,OB_Smileys';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = ',fontselect,fontsizeselect,styleselect';
				tn++;
				this.tmceParams['theme_advanced_buttons' + tn] = '';

				this._setSpellchecker();

				break;
		}
	},
	/**
	 * _setSpellchecker
	 */
	_setSpellchecker: function()
	{
		this.tmceParams.spellchecker_rpc_url = '/_tiny_mce/plugins/spellchecker/rpc.php';
		this.tmceParams.spellchecker_languages = (this.params.lang == 'fr' ?
				'+' :
				'') +
			'French=fr,' +
			(this.params.lang == 'en' ?
			 '+' :
			 '') +
			'English=en,' +
			(this.params.lang == 'de' ?
			 '+' :
			 '') +
			'German=de,' +
			(this.params.lang == 'it' ?
			 '+' :
			 '') +
			'Italian=it,' +
			(this.params.lang == 'es' ?
			 '+' :
			 '') +
			'Spanish=es';
	},
	/**
	 * putValueInElmt
	 */
	putValueInElmt: function()
	{
		this.editor.save();
		return true;
	},
	/**
	 * get
	 */
	_get: function()
	{
		this.editor = tinymce.EditorManager.get(
			this.id
		);
	},
	/**
	 * Switch toolbar
	 * @param {Integer} mode Toolbar
	 */
	switchToolbar: function(toolbar)
	{
		this.params.toolbar = toolbar;
		this.editor.remove();
		this.init();
	},
	/**
	 * Destroy editor
	 */
	destroy: function()
	{
		try
		{
			tinyMCE.execCommand(
				'mceRemoveControl',
				true,
				this.id
			);
		}
		catch (e){};
		var eds = [];
		for (var i in OB_Editors)
		{
			if (OB_Editors[i] != this)
			{
				eds.push(OB_Editors[i]);
			}
		}
		OB_Editors = eds;
	},
	/**
	 * Set error style
	 */
	setError: function(borderColor)
	{
		YAHOO.util.Dom.setStyle(
			[YAHOO.util.Dom.getElementsByClassName(
				'mceLayout',
				'table',
				this.editor.getContainer()
			)[0],
			YAHOO.util.Dom.getElementsByClassName(
				'mceToolbar',
				'td',
				this.editor.getContainer()
			)[0],
			YAHOO.util.Dom.getElementsByClassName(
				'mceIframeContainer',
				'td',
				this.editor.getContainer()
			)[0]],
			'border-color',
			borderColor
		);
	}
};
/**
 * Get an OB_Editor by its ID
 */
OB_Editor.getById = function(id)
{
	for (var i = 0; OB_Editors[i]; i++)
	{
		if (OB_Editors[i].id == id)
		{
			return OB_Editors[i];
		}
	}
	return false;
}
OB_Editor.TOOLBAR_SIMPLE = 0;
OB_Editor.TOOLBAR_ADVANCED = 1;
OB_Editor.TOOLBAR_TEXTELIBRE = 2;
OB_Editor.TOOLBAR_COMMENTS = 3;
OB_Editor.TOOLBAR_RESPONSE = 5;
OB_Editor.TOOLBAR_FORUM = 4;
OB_Editor.TOOLBAR_SA = 6;
OB_Editor.TOOLBAR_BLOGPOOL = 7;





var OB_CheckForms = new Array();
/**
 * OB_CheckForm class - Check all inputs of a a form by criterias as mail, password, not null, etc
 * Each input must have a className corresponding to the test you want it pass :
 * - notNull : check if value is not null,
 * - checkPass : check if value don't contains certains characters
 * - checkMail : check if value is a mail
 * - checkBlogName : check if value is a blog name
 * - dateOk : check if date has correct format (DD/MM/YYYY)
 * - isNumeric : check if value has only numbers
 * - isEqualTo_idOfElement : check if value is equal to value of element 'idOfElement'
 * @param {Element/String} form Form Element or its ID
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_CheckForm = function(form) {
	/**
	 * Form to inspect
	 * @type Element
	 */
	this.element = getElmt(form);
	/**
	 * Form's Inputs
	 * @type Array
	 */
	this.inputs = new Array();
	/**
	 * isOk
	 * @type Boolean
	 */
	this.isOk = true;
	this.init();
};
OB_CheckForm.prototype = {
	/**
	 * Create OB_CheckInput's object with all this form's inputs
	 */
init: function() {
		  var elements = this.element.getElementsByTagName('*');
		  for (var i = 0; elements[i]; i++) {
			  if (elements[i].nodeName == 'INPUT' ||
					  elements[i].nodeName == 'TEXTAREA') {
				  var newInput = new OB_CheckInput(elements[i]);
				  this.inputs.push(newInput);
			  }
		  }
	  },
	  /**
	   * Check all inputs of this form and return if all inputs are good or not
	   * @returns True if all inputs pass their tests succesfully, false if not
	   * @type Boolean
	   */
checkForm: function() {
			   // Konqueror plante lamentablement avec cette fonction, donc on la lui désactive…
			   if (getBrowser() == 'kq') {
				   return true;
			   }

			   this.isOk = true;
			   for (var i = 0; this.inputs[i]; i++) {
				   if (this.isOk) {
					   this.isOk = this.inputs[i].isOk();
				   } else {
					   this.inputs[i].isOk();
				   }
			   }
			   return this.isOk;
		   },
		   /**
			* Get CheckInput object by element
			* @param {Element/String} element Element or its ID
			* @returns OB_CheckInput object
			* @type OB_CheckInput
			*/
getInputByElmt: function(element) {
					for (var i = 0; this.inputs[i]; i++) {
						if (this.inputs[i].element == getElmt(element)) {
							return this.inputs[i];
						}
					}
					return false;
				},
				/**
				 * Reset Form
				 */
reset: function() {
		   for (var i = 0; this.inputs[i]; i++) {
			   this.inputs[i].setOk();
		   }
	   }
};










var OB_CheckInputs = new Array();
/**
 * OB_CheckInput class
 * @deprecated
 * @param {Element/String} element Input element or its ID to check
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_CheckInput = function(element) {
	/**
	 * Element
	 * @type Element
	 */
	this.element = getElmt(element);
	/**
	 * Value
	 * @type String
	 */
	this.value = null;
	/**
	 * Not Null
	 * @type Boolean
	 */
	this.notNull = true;
	/**
	 * passOk
	 * @type Boolean
	 */
	this.passOk = true;
	/**
	 * Variable description
	 * @type Boolean
	 */
	this.mailOk = true;
	/**
	 * Variable description
	 * @type Boolean
	 */
	this.isValidURL = true;
	/**
	 * blogNameOk
	 * @type Boolean
	 */
	this.blogNameOk = true;
	/**
	 * Date format Ok
	 * @type Boolean
	 */
	this.dateOk = true;
	/**
	 * Is numeric
	 * @type Boolean
	 */
	this.isNumeric = true;
	/**
	 * Is Equal To
	 * @type Boolean
	 */
	this.isEqualTo = true;
	/**
	 * Is More Than
	 * @type Boolean
	 */
	this.isMoreThan = true;
	/**
	 * Is Less Than
	 * @type Boolean
	 */
	this.isLessThan = true;
	/**
	 * Is checked
	 * @type Boolean
	 */
	this.isChecked = true;
	/**
	 * Minimum Characters
	 * @type Boolean
	 */
	this.minChars = true;

	OB_CheckInputs.push(this);
	this.init();
};
OB_CheckInput.prototype = {
	/**
	 * Initialize values
	 */
init: function() {
		  this.value = this.element.value;
		  this.notNull = true;
		  this.passOk = true;
		  this.mailOk = true;
		  this.isValidURL = true;
		  this.blogNameOk = true;
		  this.dateOk = true;
		  this.isNumeric = true;
		  this.isEqualTo = true;
		  this.isMoreThan = true;
		  this.isLessThan = true;
		  this.isChecked = true;
		  this.minChars = true;
	  },
	  /**
	   * Test if value is not null
	   */
testNotNull: function() {
				 if (this.value.length == 0) {
					 this.notNull = false;
					 return false;
				 }
			 },
			 /**
			  * Test if value don't have characters ^, \, $, %, _, *
			  */
testPass: function() {
			  if (this.value.length < 32 && this.value.length > 3) {
				  var reg = /[\\\^\$%_\* ]/;
				  if (this.value.search(reg) != -1 &&
						  this.value.length > 0) {
					  this.passOk = false;
				  }
			  } else {
				  this.passOk = false;
			  }
		  },

		  /**
		   * Test if value has a mail form
		   */
testMail: function() {
			 var regexp = /^((([a-z]|[0-9]|!|#|$|%|&|'|\*|\+|\-|\/|=|\?|\^|_|`|\{|\||\}|~)+(\.([a-z]|[0-9]|!|#|$|%|&|'|\*|\+|\-|\/|=|\?|\^|_|`|\{|\||\}|~)+)*)@((((([a-z]|[0-9])([a-z]|[0-9]|\-){0,61}([a-z]|[0-9])\.))*([a-z]|[0-9])([a-z]|[0-9]|\-){0,61}([a-z]|[0-9])\.)[\w]{2,4}|(((([0-9]){1,3}\.){3}([0-9]){1,3}))|(\[((([0-9]){1,3}\.){3}([0-9]){1,3})\])))$/;
			 if (this.value.search(regexp) == -1 && this.value.length > 0) {
				 this.mailOk = false;
			 }
		  },

		  /**
		   * Test if value is a valid URL
		   */
testURL: function() {
				 var regexp = /^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/;
				 if (this.value.search(regexp) == -1 && this.value.length > 0) {
					 this.isValidURL = false;
				 }
			 },

		  /**
		   * Test if value has at least 4 characters, and have a correct blog name form
		   */
testBlogName: function() {
				  if (this.value.length == 0 ||
						  (this.value.length > 3 &&
						   this.value.length<64)) {
					  var reg = /^[0-9a-z]+((\.|\-)[a-z0-9]+)*[a-z0-9]*$/;
					  if (this.value.search(reg) == -1 &&
							  this.value.length > 0) {
						  this.blogNameOk = false;
					  }
				  } else {
					  this.blogNameOk = false;
				  }
			  },
			  /**
			   * Test if value is in date format
			   * @param {Integer} format Date format (1: mm/dd/yyyy)
			   */
testDate: function(format) {
			  var valueLgt = 0;
			  var regexp = null;
			  switch (format) {
				  case 1:
					  valueLgt = 10;
					  regexp = /^\d{2}\/\d{2}\/\d{4}$/;
					  break;
			  }
			  if (this.value.length == 0 ||
					  this.value.length == valueLgt) {
				  if (this.value.search(regexp) == -1 &&
						  this.value.length == valueLgt) {
					  this.dateOk = false;
				  }
			  } else {
				  this.dateOk = false;
			  }
		  },
		  /**
		   * Test if value is numeric with dots or comas
		   */
testNumeric: function() {
				 var regexp = /^(\+|\d)([ \-\.\,]?\d)+$/;
				 if (this.value.search(regexp) == -1 && this.value.length > 0) {
					 this.isNumeric = false;
				 }
			 },
			 /**
			  * Test if two field are equals
			  */
testIsEqualTo: function(id) {
				   if (this.value != getElmt(id).value &&
						   this.value != id) {
					   this.isEqualTo = false;
				   }
			   },
			   /**
				* Test if number is superior to another
				*/
testIsMoreThan: function(value) {
					if (this.value < parseInt(value)) {
						this.isMoreThan = false;
					}
				},
				/**
				 * Test if number is inferior to another
				 */
testIsLessThan: function(value) {
					if (this.value > parseInt(value)) {
						this.isLessThan = false;
					}
				},
				/**
				 * Test if input is cheked
				 */
testIfIsChecked: function() {
					 this.isChecked = this.element.checked;
				 },
				 /**
				  * testNbrOfChars
				  */
testNbrOfChars: function(nbr) {
					if (this.value.length > 0 && this.value.length < nbr) {
						this.minChars = false;
					}
				},
				/**
				 * Test if this input passes all its tests
				 */
isOk: function() {
		  this.init();
		  var className = this.element.getAttribute('class')?this.element.getAttribute('class'):this.element.getAttribute('className');
		  if (className) {
			  var classes = className.split(' ');
			  for (var i = 0; classes[i]; i++) {
				  switch (classes[i]) {
					  case 'notNull':
						  this.testNotNull();
						  break;
					  case 'checkPass':
						  this.testPass();
						  break;
					  case 'checkMail':
						  this.testMail();
						  break;
					  case 'checkURL':
						  this.testURL();
						  break;
					  case 'checkBlogName':
						  this.testBlogName();
						  break;
					  case 'checkDateDDMMYYYY':
						  this.testDate(1);
						  break;
					  case 'checkNumeric':
						  this.testNumeric();
						  break;
					  case 'checkIsChecked':
						  this.testIfIsChecked();
						  break;
				  }
				  if (classes[i].indexOf('isEqualTo_') != -1) {
					  this.testIsEqualTo(classes[i].substr('isEqualTo_'.length));
				  }
				  if (classes[i].indexOf('isMoreThan_') != -1) {
					  this.testIsMoreThan(classes[i].substr('isMoreThan_'.length));
				  }
				  if (classes[i].indexOf('isLessThan_') != -1) {
					  this.testIsLessThan(classes[i].substr('isLessThan_'.length));
				  }
				  if (classes[i].indexOf('minChars_') != -1) {
					  this.testNbrOfChars(classes[i].substr('minChars_'.length));
				  }
			  }
			  if (this.notNull &&
					  this.passOk &&
					  this.mailOk &&
					  this.isValidURL &&
					  this.blogNameOk &&
					  this.dateOk &&
					  this.isNumeric &&
					  this.isEqualTo &&
					  this.isMoreThan &&
					  this.isLessThan &&
					  this.isChecked &&
					  this.minChars) {

				  this.setOk();
				  return true;
			  } else {
				  this.setNotOk();
				  return false;
			  }
		  } else {
			  this.setOk();
			  return true;
		  }
	  },
	  /**
	   * Set element bad
	   */
setNotOk: function() {
			  // DO nothing
		  },
		  /**
		   * Set element good
		   */
setOk: function() {
		   // Do nothing
	   }
};

/**
 * Get an Object by its element
 * @param {Element/String} element Element or its ID
 * @returns OB_CheckInput object
 * @type OB_CheckInput
 */
OB_CheckInput.getObjectByElmt = function(element) {
	for (var i = 0; OB_CheckInputs[i]; i++) {
		if (OB_CheckInputs[i].element == getElmt(element)) {
			return OB_CheckInputs[i];
		}
	}
	return false;
};

/**
 * Delete statistic call script
 */
function del_stat_tag()
{
	var res = getElmt('stat_script');
	res.parentNode.removeChild(res);
};

/**
 * Add statistic call script
 */
function add_stat_tag()
{
	var js = document.createElement('script');
	js.setAttribute('src','http://js.cybermonitor.com/overblog.js');
	js.setAttribute('type','text/javascript');
	js.setAttribute('id','stat_script');
	document.body.appendChild(js);
};

/**
 * Returns <br /> instead of new lines
 * @param {String} text the string to be converted
 * @returns the converted string
 */
function nl2br(text)
{
	text = escape(text);
	re_nlchar = "";
	if (text.indexOf('%0D%0A') > -1)
	{
		re_nlchar = /%0D%0A/g ;
	}
	else if (text.indexOf('%0A') > -1)
	{
		re_nlchar = /%0A/g ;
	}
	else if (text.indexOf('%0D') > -1)
	{
		re_nlchar = /%0D/g ;
	}
	return unescape(
			text.replace(
				re_nlchar,
				'<br />'
				)
			);
};


/**
 * Returns \nl instead of <br />
 * @param {String} text the string to be converted
 * @returns the converted string
 * @type String
 */
function br2nl(text)
{
	/* Escapes all singe quotes with \' */
	var out = "<br />"; // replace this
	var add = "\n"; // with this
	var temp = "" + text; // temporary holder

	while (temp.indexOf(out) > -1)
	{
		var pos = temp.indexOf(out);
		temp = "" + (temp.substring(0, pos) + add +
				temp.substring((pos + out.length), temp.length));
	}
	return temp;
};


/**
 * Checks if the date is a 2K date
 * @param {Integer} number the string to be converted
 * @returns the converted string
 * @type String
 */
function y2k (number) {
	return (number < 1000) ? number + 1900 : number;
};

/**
 * checks if date passed is valid
 * will accept dates in following format:
 * isDate(dd,mm,ccyy), or
 * isDate(dd,mm) - which defaults to the current year, or
 * isDate(dd) - which defaults to the current month and year.
 * Note, if passed the month must be between 1 and 12, and the
 * year in ccyy format.
 * @param {Integer} day Day
 * @param {Integer} month Month
 * @param {Integer} year Year
 * @returns true if is valid
 * @type Boolean
 */
function isDate (day,month,year) {
	// checks if date passed is valid
	// will accept dates in following format:
	// isDate(dd,mm,ccyy), or
	// isDate(dd,mm) - which defaults to the current year, or
	// isDate(dd) - which defaults to the current month and year.
	// Note, if passed the month must be between 1 and 12, and the
	// year in ccyy format.

	var today = new Date();
	year = ((!year) ? y2k(today.getYear()):year);
	month = ((!month) ? today.getMonth():month-1);
	if (!day)
	{
		return false;
	}
	var test = new Date(year,month,day);
	if ((y2k(test.getYear()) == year) &&
			(month == test.getMonth()) &&
			(day == test.getDate()))
	{
		return true;
	}
	else
	{
		return false
	}
};



////////////////////////////////////////////////////////////////////////////////
// OB Dialog.js by hadrien at over-blog dot com                                  //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
/*
   Copyright © 2006, JFG Networks, All rights reserved
   */
var globDials = new Array();
/**
 * Create a new Yahoo UI Dialog
 * @constructor
 */
var OB_Dialog = function() {
	if (!YAHOO) {
		return false;
	}
	/**
	 * Dialog width
	 * @type Integer/String
	 */
	this.width = 400;
	/**
	 * Dialog height
	 * @type Integer/String
	 */
	this.height = 400;
	/**
	 * Dialog first button
	 * @type Object
	 */
	this.button1 = {};
	/**
	 * Dialog second button
	 * @type Object
	 */
	this.button2 = {};
	/**
	 * Dialog title
	 * @type String
	 */
	this.title = null;
	/**
	 * Dialog content
	 * @type Element
	 */
	this.content = null;
	/**
	 * onSuccess
	 * @type Function
	 */
	this.onSuccess = null;
	/**
	 * onFailure
	 * @type Function
	 */
	this.onFailure = null;
	/**
	 * modal
	 * @type Boolean
	 */
	this.modal = true;
	/**
	 * close button
	 * @type Boolean
	 */
	this.closeB = true;
	/**
	 * key listeners
	 * @type Array
	 */
	this.keys = new Array();
	this.keys['esc'] = true;
	this.keys['enter'] = true;
	/**
	 * Move
	 * @type Boolean
	 */
	this.move = true;
	/**
	 * YAHOO.widget.Dialog object
	 * @type YAHOO.widget.Dialog
	 */
	this.yuiDialog = null;
	////////////////////////////////////////////
};
OB_Dialog.prototype = {
	/**
	 * Render a YUI dialog with params
	 * @returns YUI Dialog
	 * @type YAHOO.widget.Dialog
	 */
	getInstance: function()
	{
		globDials.push(this);
		this.createYuiDialog();
		return this.yuiDialog;
	},
	/**
	 * Instanciate YUI Dialog with params
	 */
	createYuiDialog: function()
	{
		/*var newDiv = document.createElement('div');
		newDiv.id = "OB_Dialog" + globDials.length;
		document.body.appendChild(newDiv);*/
		
		this.yuiDialog = new YAHOO.widget.Dialog(
			"OB_Dialog" + globDials.length,
			{
				width: this.width,
				height: this.height,
				effect: {
					effect:YAHOO.widget.ContainerEffect.FADE,
					duration:0.25
				},
				fixedcenter: false,
				modal: this.modal,
				draggable: this.move,
				constraintoviewport : true,
				close: this.closeB,
				underlay: this.underlay ?
					this.underlay :
					'shadow'
			}
		);
		// Titre du dialogue
		this.yuiDialog.setHeader(this.title);
		// Body du dialogue
		this.yuiDialog.setBody(this.content);
		// Body du dialogue
		if (this.footer)
		{
			this.yuiDialog.setFooter(this.footer);
		}
		
		// Ajout des boutons
		if (this.button1.text)
		{
			if (this.button2.text)
			{
				var confirmButtons = [this.button2, this.button1];
			}
			else
			{
				confirmButtons = [this.button1];
			}
			
			this.yuiDialog.cfg.queueProperty("buttons", confirmButtons);
		}
		
		
		// Key listener
		var listeners = new Array();
		if (this.keys['esc'])
		{
			// Esc
			var kl = new YAHOO.util.KeyListener(
					document,
					{
						keys:27
					},
					{
						fn:this.yuiDialog.destroy,
						scope:this.yuiDialog,
						correctScope:true
					}
				);
			listeners.push(kl);
		}
		if (this.keys['enter'])
		{
			// Enter
			var kok = new YAHOO.util.KeyListener(
				document,
				{
					keys:13
				},
				{
					fn: function()
					{
						if (this.dial.yuiDialog._aButtons[1])
						{
							this.dial.yuiDialog._aButtons[1].fireEvent('click');
						}
					},
					scope:this,
					correctScope:true
				}
			);
			listeners.push(kok);
		}
		if (listeners.length > 0)
		{
			this.yuiDialog.cfg.queueProperty('keylisteners', listeners);
		}
		
		
		// Events
		this.yuiDialog.formSubmitEvent = null;
		this.yuiDialog.callback.success = this.onSuccess;
		this.yuiDialog.callback.failure = this.onFailure;
		this.yuiDialog.callback.scope = this;
		this.yuiDialog.render(document.body);

		// Ajout de classe à l'element
		if (this.newclass)
		{
			_YUD.addClass(
				getElmt(this.yuiDialog.id),
				this.newclass
			);
		}
		_YUD.setStyle(
			getElmt(this.yuiDialog.id).parentNode,
			'z-index',
			999999
		);
		if (this.modal)
		{
			_YUD.setStyle(
				getElmt(this.yuiDialog.id + '_mask'),
				'z-index',
				999998
			);
		}
		
		// Affichage du dialogue
		this.yuiDialog.show();
		// change size if browser is too little
		var region =  _YUD.getRegion(this.yuiDialog.element);
		var h_w = new Array((region.bottom-region.top), (region.right-region.left));
		if (h_w[0] >  _YUD.getViewportHeight()) {
			this.yuiDialog.configHeight(
				null,
				[ _YUD.getViewportHeight()+'px'],
				null
			);
		}
		/*if (h_w[1] >  _YUD.getViewportWidth()) {
		  this.yuiDialog.configWidth(null, [ _YUD.getViewportWidth()+'px'], null);
		  }*/
		window.scrollTo(0, window.scrollY);
		this.yuiDialog.center();

		var forms = this.yuiDialog.element.getElementsByTagName('form');
		for (var i = 0; forms[i]; i++)
		{
			forms[i].dial = this;
			forms[i].onsubmit = function()
			{
				if (this.dial.yuiDialog._aButtons[1])
				{
					this.dial.yuiDialog._aButtons[1].fireEvent('click');
				}
				return false;
			};
		}
	},
	/**
	 * Set dialog dimensions
	 * @param {Integer/String} width Dialog width
	 * @param {Integer/String} height Dialog height
	 */
	setDims: function(width, height)
	{
		 this.width = width;
		 this.height = height;
	},
	/**
	 * Set button 1
	 * @param {String} label Button label
	 * @param {Function} func Function executed while pushing the button
	 * @param {Boolean} isDef Set if button is default or not
	 */
	setButton1: function(label, func, isDef)
	{
		this.button1 = {
			text: label,
			handler: func,
			isDefault: true//isDef?true:false
		};
	},
	/**
	 * Set button 2
	 * @param {String} label Button label
	 * @param {Function} func Function executed while pushing the button
	 * @param {Boolean} isDef Set if button is default or not
	 */
	setButton2: function(label, func, isDef)
	{
		this.button2 = {
			text: label,
			handler: func,
			isDefault: false//isDef?true:false
		};
	},
	/**
	 * Set dialog title
	 * @param {String} title Dialog title
	 */
	setTitle: function(title)
	{
		this.title = title;
	},
	/**
	 * Set dialog Footer
	 * @param {String} title Dialog title
	 */
	setFooter: function(text)
	{
		this.footer = text;
	},
	/**
	 * Set dialog content
	 * @param {Element} content Dialog content
	 */
	setContent: function(content)
	{
		this.content = content;
	}
};
OB_Dialog.getDialogByElmt = function(elmt) {
	for (var i = 0; globDials[i]; i++) {
		if (globDials[i].yuiDialog.element == getElmt(elmt)) {
			return globDials[i];
		}
	}
	return false;
};









OB_Confirm.prototype = new OB_Dialog();
OB_Confirm.prototype.constructor = OB_Dialog;
/**
 * Create a new confirm dialog
 * @constructor
 * @param {String} title Title of dialog
 * @param {String} str Dialog message
 * @param {Object} params object of parameters : handleYes Function to execute while clicking Yes button, handleNo Function to execute while clicking No button, label1 Button 1 label, label2 Button 2 label, width Dialog width, height Dialog height
 */
function OB_Confirm(title, str, params) {
	/**
	 * parent OB_Dialog object
	 * @type OB_Dialog
	 */
	this.dialog = new OB_Dialog();
	this.init(title, str, params?params:{});
};
/**
 * Initialize confirm dialog
 * @param {String} title Title of dialog
 * @param {String} str Dialog message * @param {Object} params object of parameters : handleYes Function to execute while clicking Yes button, handleNo Function to execute while clicking No button, label1 Button 1 label, label2 Button 2 label, width Dialog width, height Dialog height
 */
OB_Confirm.prototype.init = function(title, str, params) {
	content = document.createElement('div');
	content.innerHTML = str;
	document.body.appendChild(content);

	this.setDims(
			params.width ?
			params.width :
			'600px',
			params.height ?
			params.height :
			'auto'
			);
	this.setButton1(
			params.label1 ?
			params.label1 :
			getLocalizedString('Oui'),
			function()
			{
			if (params.handleYes)
			{
			params.handleYes(this);
			}
			this.hide();
			setTimeout(
				function(dialog)
				{
				if (dialog)
				{
				dialog.destroy();
				}
				},
				500,
				this
				);
			},
		false
			);
	this.setButton2(
			params.label2 ?
			params.label2 :
			getLocalizedString('Non'),
			function()
			{
			if (params.handleNo)
			{
			params.handleNo(this);
			}
			this.cancel();
			setTimeout(
				function(dialog)
				{
				if (dialog)
				{
				dialog.destroy();
				}
				},
				500,
				this
				);
			},
		true
			);

	if (params.close == false)
	{
		this.closeB = false;
	}
	if (params.modal == false)
	{
		this.modal = false;
	}
	if (params.enterKey == false)
	{
		this.keys['enter'] = false;
	}
	if (params.escKey == false)
	{
		this.keys['esc'] = false;
	}
	if (params.move == false)
	{
		this.move = false;
	}
	this.setTitle(title);
	this.setContent(content);
	instance =  this.getInstance();
	if (params.handleNo)
	{
		this.yuiDialog.cancelEvent.subscribe(
				params.handleNo
				);
	}
	return instance;
};










OB_FormDialog.prototype = new OB_Dialog();
OB_FormDialog.prototype.constructor = OB_Dialog;
/**
 * Create a new form dialog
 * @constructor
 * @param {String} title Title of dialog
 * @param {Element} form Form to include inside dialog
 * @param {Object} params object of parameters : handleYes Function to execute while clicking Yes button, handleNo Function to execute while clicking No button, label1 Button 1 label, label2 Button 2 label, width Dialog width, height Dialog height, onSuccess: Function callback on request success function, onFailure: Function callback on request failure function
 */
function OB_FormDialog(title, form, params) {
	/**
	 * parent OB_Dialog object
	 * @type OB_Dialog
	 */
	this.dialog = new OB_Dialog();
	this.init(title, form, params?params:{});
};
/**
 * Initialize form dialog
 * @param {String} title Title of dialog
 * @param {Element} form Form to include inside dialog
 * @param {Object} params object of parameters : handleYes Function to execute while clicking Yes button, handleNo Function to execute while clicking No button, label1 Button 1 label, label2 Button 2 label, width Dialog width, height Dialog height, onSuccess: Function callback function on success, onFailure: Function callback function on failure
 */
OB_FormDialog.prototype.init = function(title, form, params)
{
	this.setDims(
			params.width ?
			params.width :
			'600px',
			params.height ?
			params.height :
			'auto'
			);
	this.setButton1(
			params.label1 ?
			params.label1 :
			getLocalizedString('Oui'),
			function()
			{
			if (params.handleYes)
			{
			params.handleYes(this);
			}

			if (!this.clicked)
			{
			this.submit();
			this.clicked = true;
			}
			//this.hide();
			setTimeout(
				function(dialog)
				{
				if(dialog)
				{
				dialog.destroy();
				}
				},
				500,
				this
				);
			},
		params.def_button == 1 ?
			true :
			false
			);
	if (!params.oneButton)
	{
		this.setButton2(
				params.label2 ?
				params.label2 :
				getLocalizedString('Non'),
				function()
				{
				if (params.handleNo)
				{
				params.handleNo(this);
				}
				this.cancel();
				//this.hide();
				setTimeout(
					function(dialog)
					{
					if (dialog)
					{
					dialog.destroy();
					}
					},
					500,
					this
					);
				},
			params.def_button != 1 ?
				true :
				false
				);
	}
	if (params.close == false)
	{
		this.closeB = false;
	}
	if (params.modal == false)
	{
		this.modal = false;
	}
	if (params.enterKey == false)
	{
		this.keys['enter'] = false;
	}
	if (params.escKey == false)
	{
		this.keys['esc'] = false;
	}
	if (params.move == false)
	{
		this.move = false;
	}
	this.setTitle(title);
	this.setContent(form);
	this.onSuccess = params.onSuccess?params.onSuccess:null;
	this.onFailure = params.onFailure?params.onFailure:null;
	instance =  this.getInstance();
	if (params.handleNo) {
		this.yuiDialog.cancelEvent.subscribe(
				params.handleNo
				);
	}
	return instance;
};









OB_Alert.prototype = new OB_Dialog();
OB_Alert.prototype.constructor = OB_Dialog;
/**
 * Create an alert dialog
 * @constructor
 * @param {String} title Alert dialog title
 * @param {String} str Alert dialog message
 * @param {String} label Button label (default : 'Fermer')
 */
function OB_Alert(title, str, params)
{
	/**
	 * parent OB_Dialog object
	 * @type OB_Dialog
	 */
	this.dialog = new OB_Dialog();
	this.init(title, str, params?params:{});
};
/**
 * Initialize alert dialog
 * @param {String} title Alert dialog title
 * @param {String} str Alert dialog message
 * @returns OB_Dialog object
 * @type OB_Dialog
 */
OB_Alert.prototype.init = function(title, str, params)
{
	content = document.createElement('div');
	content.innerHTML = str;
	document.body.appendChild(content);

	this.setDims(
			params.width ?
			params.width :
			'600px',
			params.height ?
			(parseInt(params.height) + 80) + 'px' :
			'auto'
			);
	this.setButton1(
			params.label ?
			params.label :
			getLocalizedString('Fermer'),
			function()
			{
			if (params.handleYes && params.handleYes != 'destroy')
			{
				params.handleYes(this);
			}
			this.cancel();
			setTimeout(
				function(dialog)
				{
				if (dialog)
				{
				dialog.destroy();
				}
				},
				500,
				this
				);
			},
		true
			);
	this.closeB = false;
	if (params.modal == false)
	{
		this.modal = false;
	}
	this.escKey = true;
	if (params.escKey == false)
	{
		this.keys['esc'] = false;
	}
	this.setTitle(title);
	this.setContent(content);
	instance =  this.getInstance();

	if (params.handleYes && params.handleYes == 'destroy')
	{
		this.yuiDialog.cancelEvent.subscribe(
			instance.destroy
			);
	}
	else if(params.handleYes)
	{
		this.yuiDialog.cancelEvent.subscribe(
		params.handleYes
		);
	}

	if (params.height)
	{
		instance.body.style.height = params.height;
		instance.footer.style.paddingTop = '10px';
	}
	return instance;
};

/**
 * OB_PostItDialog class
 * @extends OB_Dialog
 * @constructor
 * @author Hadrien Lanneau
 */
OB_PostItDialog = function(title, str, params) {
	this.superclass = OB_Dialog;
	this.init(title, str, params?params:{});
};
OB_PostItDialog.prototype = new OB_Dialog();

OB_PostItDialog.prototype.init = function(title, str, params) {
	content = document.createElement('div');
	content.innerHTML = str;
	document.body.appendChild(content);

	this.setDims(
			'161px',
			params.height ?
			params.height :
			'auto'
			);

	this.modal = params.modal;
	this.underlay = 'none';

	this.newclass = 'OB_PostItDialog';
	this.setTitle(title);
	this.setContent(content);
	this.setFooter('&nbsp;');
	instance =  this.getInstance();
	this.yuiDialog.configXY(
			null,
			[['10px', '10px']],
			null
			);
	if (params.handleNo)
	{
		this.yuiDialog.cancelEvent.subscribe(
				params.handleNo
				);
	}

	_YUD.setStyle(
			getElmt(this.yuiDialog.id).parentNode,
			'z-index',
			1000000
			);

	return instance;
};
/**
 * String representation of objet
 * @returns String representation of objet
 * @type String
 */
OB_PostItDialog.prototype.toString = function() {
	return 'OB_PostItDialog object';
};
var OB_TooltipDialog = OB_PostItDialog;







var OB_PulseAlerts = new Array();
/**
 * OB_PulseAlert class
 * @param {String} title Titre
 * @param {String} str Contenu
 * @param {Object} params Paramètres : 'id' (id de l'alerte), 'parent' (id de l'élémént parent), 'style' (style de l'alerte), 'effect' (effet d'apparition)
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_PulseAlert = function(
		title,
		str,
		params)
{
	/**
	 * element
	 * @type Element
	 */
	this.element = null;
	/**
	 * title
	 * @type String
	 */
	this.title = title ? title : '';
	/**
	 * content
	 * @type String
	 */
	this.content = str ? str : '';
	/**
	 * style
	 * @type String
	 */
	this.params = params ? params : {};
	/**
	 * anim
	 * @type YAHOO.util.ColorAnim
	 */
	this.anim = null;
	/**
	 * id
	 * @type Integer
	 */
	this.id = this.params.id ? this.params.id : 'OB_PulseAlert';
	/**
	 * effect
	 * @type Object
	 */
	this.effect = null;

	OB_PulseAlerts.push(this);

	this.init();
};

// Constantes
// Effects
OB_PulseAlert.EFFECT_FADEOUT = 1;
OB_PulseAlert.EFFECT_SLIDE = 2;
// Styles
OB_PulseAlert.STYLE_ERROR = 1;
OB_PulseAlert.STYLE_INFO = 2;
OB_PulseAlert.STYLE_OK = 3;

OB_PulseAlert.prototype = {
	/**
	 * Initialize
	 */
	init: function()
	{
		if (!getElmt(this.id))
		{
			this.element = document.createElement('p');
		}
		else
		{
			this.element = getElmt(this.id);
		}

		this.element.innerHTML =
			'<strong>' +
			this.title +
			'</strong><br />' +
			this.content;
		this.element.id = this.id;

		document.body.appendChild(this.element);

		// Desactivation of parent param. Element is now centered on screenview

		this.element.setAttribute('class', '');
		this.element.setAttribute('className', '');

		YAHOO.util.Dom.addClass(
				this.element,
				this.id
				);

		if (this.params.className)
		{
			YAHOO.util.Dom.addClass(
				this.element,
				this.params.className
			);
		}
		if (this.params.style)
		{
			var styleClass = '';
			switch (this.params.style)
			{
				case OB_PulseAlert.STYLE_ERROR:
					styleClass += ' ctn_z_errorbox borderSolid';
					break;
				case OB_PulseAlert.STYLE_OK:
					styleClass += ' ctn_z_okbox borderSolid';
					break;
				case OB_PulseAlert.STYLE_INFO:
				default:
					styleClass += ' ctn_z_infobox borderSolid';
					break;
			}
			YAHOO.util.Dom.addClass(
					this.element,
					styleClass
					);
		}

		// Reset des styles
		this.element.style.position = 'absolute';
		this.element.style.overflow = 'hidden';
		this.element.style.opacity = 100;
		this.element.style.MozOpacity = 100;
		this.element.style.filters = "alpha(opacity=100)";

		// Choix de l'effet
		switch (this.params.effect)
		{
			case OB_PulseAlert.EFFECT_SLIDE:
				this.effect = {
					height:
					{
						to: 0
					}
				};
				break;
				case OB_PulseAlert.EFFECT_FADEOUT:
				default:
					this.effect = {
						opacity:
						{
							from: 1,
							to: 0
						}
					};
		}
		this.pulse();
	},
	/**
	 * Make dialog appear and pulsing
	 */
	pulse: function()
	{
		if (this.element)
		{
			this.stopAll();

			// Centering element on screenview
			this.element.style.top = (_YUD.getViewportHeight() + _YUD.getDocumentScrollTop() - 142) + 'px';
			this.element.style.right = 0;

			this.anim = new YAHOO.util.ColorAnim(
				this.element.id,
				this.effect,
				this.params.delay ?
				parseFloat(this.params.delay) :
				3,
				YAHOO.util.Easing.easeInStrong
			);
			this.anim.onComplete.subscribe(
				function()
				{
					this.getEl().style.display = 'none';
				}
			);
			this.anim.onStart.subscribe(
				 function()
				{
					this.getEl().style.display = 'block';
				}
			);
			this.anim.getEl().anim = this.anim;
			this.anim.getEl().onclick = function()
			{
				this.anim.stop(true);
			};
			this.anim.animate();
		}
		else
		{
			return false;
		}
	},
	/**
	 * Stop animations of all pulse alerts
	 */
	stopAll: function()
	{
		for (var i = 0; OB_PulseAlerts[i]; i++)
		{
			if (OB_PulseAlerts[i].anim)
			{
				OB_PulseAlerts[i].anim.stop();
			}
		}
	}
};



////////////////////////////////////////////////////////////////////////////////
// OB Sortable.js by hadrien at over-blog dot com                                  //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////
/*
   Copyright © 2006, JFG Networks, All rights reserved
   */
var OB_Sortables = new Array();
/**
 * OB_Sortable class
 * @constructor
 * @author Hadrien Lanneau
 * @param {Element/String} list UL/OL Element
 */
var OB_Sortable = function(list) {
	/**
	 * List Element
	 * @type Element
	 */
	this.element = getElmt(list);
	/**
	 * Array of items
	 * @type Array
	 */
	this.items = new Array();
	/**
	 * Clone Container
	 * @type Element
	 */
	this.cloneContainer = document.createElement('div');
	/**
	 * lastMovedItem
	 * @type OB_SortableItem
	 */
	this.lastMovedItem = null;
	/**
	 * Id
	 * @type String
	 */
	this.id = null;

	OB_Sortables.push(this);
	if (this.element){
		this.init();
	}
};
OB_Sortable.prototype = {
	/**
	 * Initialize
	 */
init: function() {
		  YAHOO.util.Dom.addClass(this.element, 'OB_Sortable_List');
		  if (getBrowser() != 'ie') {
			  YAHOO.util.Dom.addClass(this.cloneContainer, 'OB_Sortable_List');
		  }
		  this.cloneContainer.style.position = 'absolute';
		  this.cloneContainer.style.top = 0;
		  this.cloneContainer.style.height = '1px';
		  //this.cloneContainer.style.zIndex = 99999;
		  this.element.parentNode.appendChild(this.cloneContainer);
		  this.id = this.element.getAttribute('id')?this.element.getAttribute('id'):this+OB_Sortables.length;
		  var lis = this.element.getElementsByTagName('li');
		  if (lis.length > 0) {
			  for (var i = 0; lis[i]; i++) {
				  var newItem = new OB_SortableItem(lis[i], this);
				  this.items.push(newItem);
			  }
		  }
	  },
	  /**
	   * Destroy object
	   */
destroy: function() {
			 /*this.cloneContainer.parentNode.removeChild(this.cloneContainer);
			   for (var i = 0; this.items[i]; i++) {
			   this.items[i].element.style.visibility = 'hidden';
			   }*/
			 if (configDial && configDial.yuiDialog.element) {
				 configDial.yuiDialog.cancel();
			 }
			 setTimeout(function(){configDial = null;}, 300);
		 },
		 /**
		  * Serialize items order
		  * @returns String representation of items order
		  * @type String
		  */
serialize: function() {
			   var serial = '';
			   var coma = '';
			   var lis = this.element.getElementsByTagName('li');
			   for (var i = 0; lis[i]; i++) {
				   var item = OB_SortableItem.getObjectByElmt(lis[i]);
				   serial += coma+item.id;
				   coma = ',';
			   }
			   return serial;
		   },
		   /**
			* Move an item
			* @param {OB_SortableItem} from Item to move
			* @param {OB_SortableItem} to Destination item
			* @param {String} place Up or down
			*/
move: function(from, to, place) {
		  switch(place) {
			  case 'up':
				  this.element.insertBefore(from.element, to.element);
				  break;
			  case 'down':
				  var nextLi = this.getNextLi(to.element);
				  if (!nextLi) {
					  this.element.appendChild(from.element);
				  } else {
					  this.element.insertBefore(from.element, nextLi);
				  }
				  break;
		  }
	  },
	  /**
	   * Is last li
	   * @param {Element} item Li element to look for
	   * @returns False if it's the last li, next LI if not
	   */
getNextLi: function(item) {
			   var lis = this.element.getElementsByTagName('li');
			   for (var i = 0; lis[i]; i++) {
				   if (lis[i] == item) {
					   if (!lis[i+1]) {
						   return false;
					   } else {
						   return lis[i+1];
					   }
				   }
			   }
			   return false;
		   },
		   /**
			* On Change
			* @param {Function} func Function to call on list order change
			*/
onChange: function(func) {
			  if (func) {
				  this.customOnChange = func;
			  }
			  for (var i = 0; this.items[i]; i++) {
				  this.items[i].onChange(this.customOnChange);
			  }
		  },
		  /**
		   * customOnChange
		   */
customOnChange: function(func) {
					//
				}
};

var configDial = null;

var OB_SortableItems = new Array();
/**
 * OB_SortableItem class
 * @constructor
 * @author Hadrien Lanneau
 * @param {Element/String} item LI item
 * @param {OB_Sortable} parent OB_Sortable parent object
 */
var OB_SortableItem = function(item, parent) {
	/**
	 * Item sortable
	 * @type Element
	 */
	this.element = getElmt(item);
	/**
	 * Parent list
	 * @type Element
	 */
	this.parent = parent;
	/**
	 * YUIDrag
	 * @type YAHOO.util.DD
	 */
	this.YUIDrag = null;
	/**
	 * Drag Clone element
	 * @type Element
	 */
	this.dragEl = this.element.cloneNode(true);
	/**
	 * ID
	 * @type String
	 */
	this.id = null;

	OB_SortableItems.push(this);
	this.init();
};
OB_SortableItem.prototype = {
	/**
	 * Initialize
	 */
init: function() {
		  this.dragEl.style.visibility = 'hidden';
		  this.element.setAttribute('id', this.element.getAttribute('id')?this.element.getAttribute('id'):this+'['+this.parent.id+']'+OB_SortableItems.length);
		  this.id = this.element.getAttribute('id');

		  var newSpan = document.createElement('div');
		  if (this.element.firstChild.nodeName == 'A') {
			  this.element.linkNode = this.element.firstChild;
			  this.element.removeChild(this.element.linkNode);
			  newSpan.innerHTML = this.element.linkNode.innerHTML;
		  } else {
			  newSpan.appendChild(this.element.firstChild);
		  }
		  newSpan.setAttribute('id', 'child'+this.id);
		  this.element.label = newSpan;
		  YAHOO.util.Dom.addClass(newSpan, 'OB_SortableItem_Content');
		  this.element.appendChild(newSpan);

		  this.dragEl.setAttribute('id', 'dragEl'+this.element.getAttribute('id'));
		  this.parent.cloneContainer.appendChild(this.dragEl);

		  this.YUIDrag = new YAHOO.util.DDProxy('child'+this.id, this.parent.id, {dragElId:this.dragEl.getAttribute('id')});
		  this.YUIDrag.setXConstraint(0,0);
		  this.YUIDrag.startDrag = this.startDrag;
		  this.YUIDrag.onDragOver = this.onDragOver;
		  this.YUIDrag.endDrag = this.endDrag;
		  this.YUIDrag.parent = this;

		  new YAHOO.util.DDTarget(this.id, this.parent.id);
	  },
	  /**
	   * Start Drag event
	   * @param {Integer} x X position of mouse
	   * @param {Integer} y Y position of mouse
	   */
startDrag: function(x, y) {
			   this.parent.element.style.visibility = 'hidden';
		   },
		   /**
			* get db id
			*/
getDBId: function() {
			 return this.id.substr(5);
		 },
		 /**
		  * On Drag Enter event
		  * @param {Event} e Event object
		  * @param {String} id ID of hovered element
		  */
onDragOver: function(e, id) {
				var target = OB_SortableItem.getObjectByElmt(id);
				var thisPos = YAHOO.util.Event.getXY(e);
				var posTarget = YAHOO.util.Dom.getRegion(target.element);
				var middle = parseInt(posTarget.top+((posTarget.bottom-posTarget.top)/2));
				if (thisPos[1] < middle) {
					this.parent.parent.move(this.parent, target, 'up');
				} else {
					this.parent.parent.move(this.parent, target, 'down');
				}
			},
			/**
			 * On Drag Drop
			 * @param {Event} e Event object
			 * @param {String} id ID of hovered element
			 */
endDrag: function(e, id) {
			 this.parent.element.style.visibility = 'visible';
		 },
		 /**
		  * On Change
		  * @param {Function} func Function called when items order change
		  */
onChange: function(func) {
			  this.YUIDrag.endDrag = function() {
				  this.parent.parent.lastMovedItem = this.parent;
				  this.parent.element.style.visibility = 'visible';
				  func();
			  }
		  },
		  /**
		   * Create a link fieldset
		   */
createLinkFieldset: function() {
						// On ferme le précédent dialogue si il existe
						if (configDial && configDial.yuiDialog.element) {
							configDial.yuiDialog.cancel();
						}

						// On vire les noeuds sinon IE7 rale
						if (getElmt('libelleLink')) {
							getElmt('libelleLink').parentNode.removeChild(getElmt('libelleLink'));
						}
						if (getElmt('urlLink')) {
							getElmt('urlLink').parentNode.removeChild(getElmt('urlLink'));
						}

						// On crée le formulaire
						var titre = getLocalizedString('Editer un lien');
						var form = '<form class="ob_form">\
								   <fieldset>\
								   <label for="libelleLink" style="width:150px; display: block; float: left;">Libellé : </label>\
								   <input type="text" id="libelleLink" value="'+this.parentNode.linkNode.innerHTML+'" style="width: 300px; border: 1px solid black;" />\
								   <br />\
								   <div style="clear:both;height: 5px;"></div>\
								   <label for="urlLink" style="width:150px; display: block; float: left;"><accronym title="Uniformed Resources Locator">URL</accronym> : </label>\
								   <input type="text" id="urlLink" value="'+this.parentNode.linkNode.getAttribute('href')+'" style="width: 300px; border: 1px solid black;" />\
								   </fieldset>\
								   </form>';
								

						// On affiche le dialogue
						configDial = new OB_Confirm(
							titre,
							form,
							{
								label1: getLocalizedString('Valider'),
								label2: getLocalizedString('Annuler'),
								handleYes: function()
								{
									var item = OB_SortableItem.getObjectByElmt(
										configDial.link.parentNode
									);
									item.element.label.innerHTML =
										getElmt('libelleLink').value != '' ?
											getElmt('libelleLink').value :
											getLocalizedString('Nouveau Lien');
									item.element.linkNode.innerHTML =
										getElmt('libelleLink').value != '' ?
											getElmt('libelleLink').value :
											getLocalizedString('Nouveau Lien');
									item.element.linkNode.setAttribute(
										'href',
										getElmt('urlLink').value
									);
									item.dragEl.innerHTML = '<a href="' +
										getElmt('urlLink').value +
										'">' +
										getElmt('libelleLink').value != '' ?
										getElmt('libelleLink').value :
										getLocalizedString('Nouveau Lien') +
										'</a>';
									item.updateLink(
										getElmt('libelleLink').value,
										getElmt('urlLink').value
									);
								},
								modal: true,
								close: false
							}
						);
						_YUD.setStyle(
							configDial.yuiDialog.element,
							'z-index',
							99999999
						);
						configDial.link = this;
					},
					/**
	 				 * Update Link
	 				 * @param {String} linkName Link name
	 				 * @param {String} linkUrl Link URL
	 				 */
					updateLink: function(linkName, linkUrl)
					{ },
			/**
			 * Remove Link Fieldset
			 * @param {Object} node Node to remove
			 */
removeLinkFieldset: function(node) {
						node.parentNode.parentNode.removeChild(this.linkField);
						this.linkField = null;
						var noLinkFieldset = true;
						for (var i = 0; this.parent.items[i]; i++) {
							if (this.parent.items[i].linkField) {
								noLinkFieldset = false;
							}
						}
						if (noLinkFieldset) {
							YAHOO.util.DragDropMgr.unlock();
						}
					},
					/**
					 * Event fired on clik on suppr button
					 * @param {Function} func Function to fire
					 */
onSupprClick: function(func) {
				  if (func) {
					  this.customSupprFunction = func;
				  }
				  if (this.element.supprButton) {
					  this.element.supprButton.onclick = function() {
						  this.parent.customSupprFunction();
						  this.parent.parent.element.removeChild(this.parent.element);
					  };
				  }
			  },
			  /**
			   * Custom Suppr Function
			   */
customSupprFunction: function() {
						 //actions
					 },
					 /**
					  * Change Config button on click event
					  */
onConfClick: function(func) {
				 if (this.element.confButton) {
					 this.element.confButton.onclick = func;
				 }
			 },
			 /**
			  * String representation of object
			  * @returns String representation of object
			  * @type String
			  */
toString: function() {
			  return 'OB_SortableItem';
		  }
};
/**
 * Get object by its element
 * @param {Element/String} element Element to look for
 * @returns OB_SortableItem linked to this element
 * @type OB_SortableItem
 */
OB_SortableItem.getObjectByElmt = function(element) {
	for (var i = 0; OB_SortableItems[i]; i++) {
		if (OB_SortableItems[i].element == getElmt(element)) {
			return OB_SortableItems[i];
		}
	}
	return false;
};









/**
 * OB_SortableLinks class
 * @extends OB_Sortable
 * @constructor
 * @author Hadrien Lanneau
 */
OB_SortableLinks = function(list) {
	this.superclass = OB_Sortable;
	this.superclass(list);
};
OB_SortableLinks.prototype = new OB_Sortable();
/**
 * init
 */
OB_SortableLinks.prototype.init = function() {
	this.superclass.prototype.init.call(this);
	for (var i = 0; this.items[i]; i++) {
		var item = this.items[i].element;
		// Suppr link Button
		item.supprButton = document.createElement('input');
		item.supprButton.setAttribute(
				'type',
				'button'
				);
		YAHOO.util.Dom.addClass(
				item.supprButton,
				'OB_SortableLinks_SupprButton'
				);

		// Config link Button
		if (item.linkNode)
		{
			item.confButton = document.createElement('input');
			item.confButton.setAttribute(
					'type',
					'button'
					);
			YAHOO.util.Dom.addClass(
					item.confButton,
					'OB_SortableLinks_ConfButton'
					);
			item.confButton.value = 'O';
			item.insertBefore(
					item.confButton,
					item.firstChild
					);
		}
		item.supprButton.value = 'X';
		item.insertBefore(item.supprButton, item.firstChild);
		item.supprButton.parent = this.items[i];
		this.items[i].onConfClick(this.items[i].createLinkFieldset);
	}
	// New Link Button
	var newDiv = document.createElement('div');
	_YUD.setStyle(
			newDiv,
			'text-align',
			'center'
			);
	_YUD.setStyle(
			newDiv,
			'padding',
			'5px'
			);

	var addLink = document.createElement('input');
	addLink.setAttribute(
			'type',
			'button'
			);
	addLink.value = localizedString['Ajouter un lien'];
	YAHOO.util.Dom.addClass(
			addLink,
			'buttonAction'
			);
	newDiv.appendChild(
			addLink
			);
	this.element.parentNode.insertBefore(
			newDiv,
			this.element
			);
	this.element.addLink = new YAHOO.widget.ActionButton(
			addLink
			);
	this.element.addLink.parent = this;
	this.element.addLink.on(
			'click',
			function()
			{
			// On ferme le précédent dialogue si il existe
			if (configDial && configDial.yuiDialog.element) {
			configDial.yuiDialog.cancel();
			}

			// On vire les noeuds sinon IE7 rale
			if (getElmt('libelleLink')) {
			getElmt('libelleLink').parentNode.removeChild(getElmt('libelleLink'));
			}
			if (getElmt('urlLink')) {
			getElmt('urlLink').parentNode.removeChild(getElmt('urlLink'));
			}

			// On crée le formulaire
			var titre = getLocalizedString('Ajouter un lien');
			var form = '<form class="ob_form">\
			<fieldset>\
			<label for="libelleLink" style="width:150px; display: block; float: left;">' + getLocalizedString('libelle') + '</label>\
			<input type="text" id="libelleLink" value="'+getLocalizedString('Nouveau Lien')+'" style="width: 300px; border: 1px solid black;" />\
			<br />\
			<div style="clear:both;height: 5px;"></div>\
			<label for="urlLink" style="width:150px; display: block; float: left;"><accronym title="Uniformed Resources Locator">URL</accronym> : </label>\
			<input type="text" id="urlLink" value="http://" style="width: 300px; border: 1px solid black;" />\
			</fieldset>\
			</form>';

	// On affiche le dialogue
	configDial = new OB_Confirm(
		titre,
		form,
		{
			label1: getLocalizedString('Valider'),
			label2: getLocalizedString('Annuler'),
			handleYes: function()
			{
				var item = configDial.link.parent;
				item.addNewLink(
					getElmt('libelleLink').value,
					getElmt('urlLink').value
				);
			},
			modal: true,
			close: false
		}
	);
	_YUD.setStyle(
		configDial.yuiDialog.element,
		'z-index',
		99999999
	);
	configDial.link = this;
	}
);
};
/**
 * Add new link
 */
OB_SortableLinks.prototype.addNewLink = function(label, url)
{
	this.customAddNewLink(
			label,
			url
			);
	var item = document.createElement('li');
	item.linkNode = document.createElement('a');

	// Url du lien
	item.linkNode.setAttribute(
			'href',
			url ?
			url :
			'http://'
			);
	// Label du lien
	item.linkNode.innerHTML = label ?
		label :
		getLocalizedString('Nouveau Lien');

	item.appendChild(
			item.linkNode
			);

	this.element.appendChild(item);
	var newItem = new OB_SortableItem(
			item,
			this
			);
	this.items.push(newItem);


	// Config link Button
	if (newItem.element.linkNode)
	{
		newItem.element.confButton = document.createElement('input');
		newItem.element.confButton.setAttribute(
				'type',
				'button'
				);
		YAHOO.util.Dom.addClass(
				newItem.element.confButton,
				'OB_SortableLinks_ConfButton'
				);
		newItem.element.confButton.value = 'O';
		newItem.element.insertBefore(
				newItem.element.confButton,
				newItem.element.firstChild
				);
	}
	// Suppr link Button
	newItem.element.supprButton = document.createElement('input');
	newItem.element.supprButton.setAttribute(
			'type',
			'button'
			);
	YAHOO.util.Dom.addClass(
			newItem.element.supprButton,
			'OB_SortableLinks_SupprButton'
			);
	newItem.element.supprButton.value = 'X';
	newItem.element.insertBefore(
			newItem.element.supprButton,
			newItem.element.firstChild
			);
	item.supprButton.parent = newItem;
	newItem.onConfClick(
			newItem.createLinkFieldset
			);
	this.onSupprClick();
	this.setUpdateLink();
	this.onChange();
};
/**
 * Set Add New Link function
 */
OB_SortableLinks.prototype.setAddNewLink = function(func) {
	this.customAddNewLink = func;
};
/**
 * custom Add new link
 */
OB_SortableLinks.prototype.customAddNewLink = function() {
};

/**
 * onSupprClick
 */
OB_SortableLinks.prototype.onSupprClick = function(func) {
	if (func) {
		this.customSupprClick = func;
	}
	for (var i = 0; this.items[i]; i++) {
		this.items[i].onSupprClick(this.customSupprClick);
	}
};
/**
 * Custom Suppr on click function
 */
OB_SortableLinks.prototype.customSupprClick = function() {
	//Actions
};

/**
 * Change Config button on click event
 */
OB_SortableLinks.prototype.onConfClick = function(func) {
	for (var i = 0; this.items[i]; i++) {
		this.items[i].onConfClick(func);
	}
};
/**
 * Set Update Link function
 */
OB_SortableLinks.prototype.setUpdateLink = function(func) {
	if (func) {
		this.customUpdateLinkFunction = func;
	}
	for (var i = 0; this.items[i]; i++) {
		this.items[i].updateLink = this.customUpdateLinkFunction;
	}
};
/**
 * Custom Update Link Function
 */
OB_SortableLinks.prototype.customUpdateLinkFunction = function() {
	//Actions
};

/**
 * String representation of objet
 * @returns String representation of objet
 * @type String
 */
OB_SortableLinks.prototype.toString = function() {
	return 'OB_SortableLinks object';
};



/* ////////////////////////////// */
/* OB_Tooltip                     */
/* ////////////////////////////// */
// Deprecated : see OB.Tooltip.js
var OB_Tooltips = new Array();
/**
 * OB_Tooltip class
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_Tooltip = function(elmt, params) {
	/**
	 * element
	 * @type Element
	 */
	this.element = getElmt(elmt);
	/**
	 * Panel
	 * @type Element
	 */
	this.panel = null;
	/**
	 * Parameters
	 * @type Object
	 */
	this.params = params ? params : {};

	OB_Tooltips.push(this);
	this.init();
};
OB_Tooltip.prototype =
{
	/**
	 * Initialize
	 */
	init: function()
	{
		this.panel = this._insertInDOM();

		// Insertion du texte
		this.panel.bd.innerHTML = this.params.text ?
			this.params.text :
			this.element.title ?
				this.element.title :
				this.element.alt ?
					this.element.alt :
					'';
		// Enlevage des éventuels title et alt
		this.element.setAttribute(
			'alt',
			''
		);
		this.element.setAttribute(
			'title',
			''
		);

		this.hide();

		this.element.tooltip = this;
		// Events
		this.element.onmousemove = function(e)
		{
		    this.tooltip.show(e);
		};
		this.element.onmouseout = function()
		{
		    this.tooltip.hide();
		};
	},
	/**
	 * Generate panel in DOM
	 */
	_insertInDOM: function()
	{
		var newDiv = document.createElement('div');
		newDiv.hd = document.createElement('div');
		newDiv.hd.appendChild(
			document.createTextNode('')
		);
		newDiv.bd = document.createElement('div');
		newDiv.bd.appendChild(
			document.createTextNode('')
		);
		newDiv.ft = document.createElement('div');
		newDiv.ft.appendChild(
			document.createTextNode('')
		);
		newDiv.appendChild(
			newDiv.hd
		);
		newDiv.appendChild(
			newDiv.bd
		);
		newDiv.appendChild(
			newDiv.ft
		);
		
		newDiv.hd.className = 'hd';
		newDiv.bd.className = 'bd';
		newDiv.ft.className = 'ft';
		newDiv.className = 'yui-tt' + (this.params.className ?
			' ' + this.params.className :
			'');
		newDiv.style.position = 'absolute';
		newDiv.style.display = 'none';
		
		
		
		YAHOO.util.Event.onDOMReady(
			function(e)
			{
				try
				{
					var body = YAHOO.util.Dom.getAncestorByTagName(
						this.element,
						'body'
					);
				}
				catch (e)
				{
					body = document.body;
				}
				
				body.appendChild(newDiv);
			},
			this,
			true
		);
		
		return newDiv;
	},
	/**
	 * hide
 	 */
	hide: function(e)
	{
		this.panel.style.display = 'none';
	},
	/**
	 * show
	 */
	show: function(e)
	{
		try
		{
			var evt = _YUE.getEvent(e);
			this.panel.style.display = 'block';
			var pos = _YUE.getXY(evt);
			var reg = _YUD.getRegion(this.panel);

			this.panel.style.top = (pos[1] + 20) + 'px';
			this.panel.style.left = this.params.marginLeft ?
				(pos[0] - parseInt(this.params.marginLeft)) + 'px' :
				(pos[0] - (reg.right - reg.left) / 2 + 2) + 'px';
		}
		catch (ex)
		{}
	},
	/**
	 * destroy
	 */
	destroy: function()
	{
		this.panel.parentNode.removeChild(
			this.panel
		);
		this.element = null;
	}
};
/**
 * Get an OB_Tooltip object by its element
 */
OB_Tooltip.getByEl = function(el)
{
	for (var i = 0; OB_Tooltips[i]; i++)
	{
		if (OB_Tooltips[i].element == getElmt(el))
		{
			return OB_Tooltips[i];
		}
	}
	return false;
}


var OB_TagLists = new Array();
/**
 * OB_TagList class
 * @constructor
 * @param {Element/String} elmt Element or ID of input
 * @param {Array} dataSource Datasource for autocompletion
 * @param {Object} params Object of parameters (maxInputs : max number of tags; width : inputs width)
 * @author Hadrien Lanneau
 */
var OB_TagList = function(elmt, dataSource, params) {
	/**
	 * element
	 * @type Element
	 */
	this.element = getElmt(elmt);
	/**
	 * tags
	 * @type Array
	 */
	this.tags = null;
	/**
	 * liste
	 * @type Element
	 */
	this.liste = document.createElement('ul');
	/**
	 * params
	 * @type Object
	 */
	this.params = params ? params : {};
	/**
	 * dataSource
	 * @type Array
	 */
	this.dataSource = dataSource ? dataSource : new Array();
	/**
	 * Query length
	 * @type Integer
	 */
	this.queryLength = 0;

	OB_TagLists.push(this);
	/**
	 * id
	 * @type Integer
	 */
	this.id = OB_TagLists.length;

	if (this.element)
	{
		this.init();
	}
};
OB_TagList.prototype =
{
	/**
	 * Initialize
	 */
init: function()
	  {
		  // Default values
		  if (!this.params.maxInputs)
		  {
			  this.params.maxInputs = 10;
		  }
		  if (!this.params.width)
		  {
			  this.params.width = 'auto';
		  }
		  else
		  {
			  this.params.width = parseInt(this.params.width)+'px';
		  }

		  if (this.params.queryLength)
		  {
			  this.queryLength = this.params.queryLength;
		  }
		
		if (this.element.parentNode)
		{
			this.element.parentNode.insertBefore(
				  this.liste,
				  this.element
				  );
		}

		  this.element.style.display = 'none';

		  // Tags in an array
		  this.tags = this.element.value.split(',');
		  //
		  for (var i = 0; i < this.tags.length; i++)
		  {
			  if (this.tags[i] != '')
			  {
				  this.addInput(this.tags[i]);
			  }
		  }

		  this.tryAddInput();

		  // Classes
		  _YUD.addClass(
				  this.liste,
				  'OB_TagList'
				  );
	  },
	  /**
	   * Serialize all inputs in an hidden input
	   */
serialize: function()
		   {
			   var inputs = this.liste.getElementsByTagName('input');
			   var virg = '';
			   var tagsString = '';

			   for (var i = 0; inputs[i]; i++)
			   {
				   if (inputs[i].value != '')
				   {
					   tagsString += virg+inputs[i].value;
					   virg = ',';
				   }
			   }
			   this.element.value = tagsString;
		   },
		   /**
			* Add a new input
			* @param {String} value Value to put in input
			*/
addInput: function(value)
		  {
			  var inputs = this.liste.getElementsByTagName('input');
			  if (inputs.length+1 > this.params.maxInputs)
			  {
				  return false;
			  }

			  if (!value)
			  {
				  value = ' ';
			  }

			  // Li element
			  var aLi = document.createElement('li');

			  // Div element for autocomplete
			  var aDiv = document.createElement('div');
			  aDiv.style.position = 'absolute';
			  aDiv.setAttribute(
					  'id',
					  'OB_TagList'+this.id+'AutoCompletePanel'+inputs.length
					  );
			  _YUD.addClass(
					  aDiv,
					  'OB_TagListAutoCompletePanel'
					  );

			  // Input element
			  var anInput = document.createElement('input');

			  // Attributes
			  anInput.setAttribute(
					  'type',
					  'text'
					  );
			  anInput.setAttribute(
					  'id',
					  'OB_TagList'+this.id+'Item'+inputs.length
					  );
			  anInput.setAttribute(
					  'value',
					  trim(value)
					  );
			  anInput.style.width = this.params.width;

			  anInput.parent = this;


			  // Events
			  _YUE.addListener(
					  anInput,
					  'keyup',
					  function()
					  {
					  this.parent.serialize();
					  this.parent.tryAddInput();
					  },
					  this
					  );
			  _YUE.addListener(
					  anInput,
					  'focus',
					  function()
					  {
					  _YUD.addClass(
						  this,
						  'focus'
						  );
					  },
					  this
					  );
			  _YUE.addListener(
					  anInput,
					  'blur',
					  function()
					  {
					  _YUD.removeClass(
						  this,
						  'focus'
						  );
					  },
					  this
					  );

			  // Appends to parents
			  aLi.appendChild(
					  anInput
					  );
			  aLi.appendChild(
					  aDiv
					  );
			  this.liste.appendChild(
					  aLi
					  );

			  // Placement du div
			  setTimeout(
					  function()
					  {
					  var pos = _YUD.getRegion(
						  anInput.getAttribute('id')
						  );
					  _YUD.setXY(
						  aDiv,
						  [pos.left, pos.bottom]
						  );
					  },
					  1000
					  );

			  // Autocomplete
			  anInput.autoComplete = new YAHOO.widget.AutoComplete(
					  anInput.getAttribute('id'),
					  aDiv.getAttribute('id'),
					  new YAHOO.widget.DS_JSArray(this.dataSource)
					  );
			  anInput.autoComplete.delimChar = "";
			  anInput.autoComplete.animHoriz = true;
			  anInput.autoComplete.autoHighlight = false;
			  anInput.autoComplete.highlightClassName = 'hightlight';
			  anInput.autoComplete.queryDelay = 0;
			  anInput.autoComplete.typeAhead = true;
			  anInput.autoComplete.minQueryLength = this.queryLength;

			  // Bonus esthétique : placement de la virgule
			  if (inputs.length > 1)
			  {
				  inputs[inputs.length-2].parentNode.appendChild(
						  document.createTextNode(', ')
						  );
			  }
		  },
		  /**
		   * Test if list contains void input
		   * @returns Boolean
		   * @type Boolean
		   */
hasVoidInput: function()
			  {
				  var inputs = this.liste.getElementsByTagName('input');

				  for (var i = 0; inputs[i]; i++)
				  {
					  if (inputs[i].value == '')
					  {
						  return true;
					  }
				  }
				  return false;
			  },
			  /**
			   * Try to add a void input
			   */
tryAddInput: function()
			 {
				 if (!this.hasVoidInput())
				 {
					 this.addInput('');
				 }
			 }
};

var OB_SortLists = new Array();
/**
 * OB_SortList class
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_SortList = function(el, params) {
	/**
	 * element
	 * @type Element
	 */
	this.element = getElmt(el);
	/**
	 * yuiDDTarget
	 * @type YAHOO.util.DDTarget
	 */
	this.yuiDDTarget = null;
	/**
	 * params
	 * @type Object
	 */
	this.params = params ? params : {};
	/**
	 * outInput
	 * @type Element
	 */
	this.outInput = document.createElement('input');
	/**
	 * independant
	 * @type Boolean
	 */
	this.independant = false;

	OB_SortLists.push(this);
	/**
	 * id
	 * @type Integer
	 */
	this.id = OB_SortLists.length;

	if (this.element)
	{
		this.init();
	}
};
OB_SortList.prototype = {
	/**
	 * Initialisation
	 */
init: function() {
		  if (!this.element.getAttribute('id'))
		  {
			  this.element.setAttribute(
					  'id',
					  'OB_SortList'+this.id
					  );
		  }

		  this.yuiDDTarget = new YAHOO.util.DDTarget(
				  this.element
				  );

		  this.tempLi = document.createElement('li');
		  this.tempLi.innerHTML = '&nbsp;';
		  _YUD.addClass(
				  this.tempLi,
				  'tempLi'
				  );

		  this.outInput.setAttribute(
				  'type',
				  'hidden'
				  );
		  this.outInput.setAttribute(
				  'name',
				  this.params.name ? this.params.name : 'OB_SortList'+this.id
				  );

		  this.element.parentNode.insertBefore(
				  this.outInput,
				  this.element
				  );
	  },
	  /**
	   * addTempItem
	   */
addTempItem: function(item, params) {
				 if (this.params.no_sort)
				 {
					 return false;
				 }
				 if (!params)
				 {
					 return false;
				 }

				 var beforeEl = null;

				 if (params.after)
				 {
					 // Down
					 var lis = this.element.getElementsByTagName('li');
					 for (var i = 0; lis[i]; i++)
					 {
						 if (lis[i] == params.after.element &&
								 i < lis.length-1)
						 {
							 beforeEl = lis[i+1];
						 }
					 }
					 //params.after.element
				 }
				 if (params.before)
				 {
					 beforeEl = params.before.element;

				 }
				 if (beforeEl)
				 {
					 this.element.insertBefore(
							 this.tempLi,
							 beforeEl
							 );
				 }
				 else
				 {
					 this.element.appendChild(
							 this.tempLi
							 );
				 }
			 },
			 /**
			  * additem
			  */
addItem: function(item)
		 {
			 if (this.tempLi.parentNode == this.element)
			 {
				 this.element.insertBefore(
						 item.element,
						 this.tempLi
						 );
			 }
			 else
			 {
				 this.element.appendChild(item.element);
			 }
			 item.element.style.top = 'auto';
			 item.element.style.left = 'auto';
		 },
		 /**
		  * removeTempLi
		  */
removeTempLi: function()
			  {
				  if (this.tempLi.parentNode &&
						  this.tempLi.parentNode == this.element)
				  {
					  this.element.removeChild(
							  this.tempLi
							  );
				  }
			  },
			  /**
			   * getEl
			   */
getEl: function() {
		   return this.element;
	   },
	   /**
		* serialize
		*/
serialize: function() {
			   var lis = this.element.getElementsByTagName('li');

			   var serialLis = '';
			   var virg = '';

			   for (var i = 0; lis[i]; i++)
			   {
				   if (OB_SortListItem.getObjByEl(lis[i]))
				   {
					   serialLis += virg + lis[i].id;
					   virg = ',';
				   }
			   }

			   this.outInput.value = serialLis;
			   return this.outInput.value;
		   },
		   /**
			* destroyAll
			*/
destroy: function() {
			 if (this.element &&
					 this.element.parentNode)
			 {
				 this.element.parentNode.removeChild(this.element);
			 }
			 if (this.tempLi &&
					 this.tempLi.parentNode)
			 {
				 this.tempLi.parentNode.removeChild(this.tempLi);
			 }
			 if (this.outInput &&
					 this.outInput.parentNode)
			 {
				 this.outInput.parentNode.removeChild(this.outInput);
			 }
		 }
};
/**
 * Get object By id
 */
OB_SortList.getObjById = function(id) {
	for (var i = 0; OB_SortLists[i]; i++)
	{
		if (OB_SortLists[i].getEl() &&
				OB_SortLists[i].getEl().getAttribute('id') == id)
		{
			return OB_SortLists[i];
		}
	}
	return false;
};
/**
 * Get object By element
 */
OB_SortList.getObjByEl = function(el) {
	for (var i = 0; OB_SortLists[i]; i++)
	{
		if (OB_SortLists[i].getEl() == el)
		{
			return OB_SortLists[i];
		}
	}
	return false;
};
/**
 * destroyAll
 */
OB_SortList.destroyAll = function() {
	for (var i = OB_SortLists.length - 1; OB_SortLists[i]; i--)
	{
		OB_SortLists[i].destroy();
	}
	OB_SortLists = new Array();
};

/**
 *
 */
OB_SortList.moveFromTo = function(from, to)
{
	from = OB_SortList.getObjByEl(from);
	to = OB_SortList.getObjByEl(to);
	if (!from || !to)
	{
		return false;
	}
	var lis = from.getEl().getElementsByTagName('li');
	if (lis.length == 0)
	{
		return false;
	}
	while (lis.length > 0)
	{
		var item = OB_SortListItem.getObjByEl(lis[0]);

		if (item)
		{
			to.addItem(item);
		}
	}
	from.serialize();
	to.serialize();
};




var OB_SortListItems = new Array();
/**
 * OB_SortListItem class
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_SortListItem = function(el, handle)
{
	/**
	 * element
	 * @type Element
	 */
	this.element = getElmt(el);
	/**
	 * yuiDD
	 * @type YAHOO.util.DD
	 */
	this.YUIDD = null;

	OB_SortListItems.push(this);

	/**
	 * id
	 * @type Integer
	 */
	this.id = OB_SortListItems.length;

	if (this.element)
	{
		this.init(handle);
	}
};
OB_SortListItem.prototype = {
	/**
	 * Initialisation
	 */
init: function(handle) {
		  if (!this.element.getAttribute('id'))
		  {
			  this.element.setAttribute(
					  'id',
					  'OB_SortListItem'+this.id
					  );
		  }

		  this.YUIDD = new YAHOO.util.DD(
				  this.element
				  );

		  this.YUIDD.parent = this;

		  // Avant de déplacer
		  // Avant de déplacer
		  this.YUIDD.b4StartDrag = function()
		  {
			  _YUD.setStyle(
					  this.getEl(),
					  'z-index',
					  999999
					  );
			  _YUD.setStyle(
					  this.getEl(),
					  'opacity',
					  0.8
					  );
			  // Ignoble patch pour IE6 qui merdoit encore et encore…
			  if (getBrowser() == 'ie')
			  {
				  _YUD.setStyle(
						  _YUD.getElementsByClassName(
							  'handle',
							  'div',
							  this.getEl()
							  ),
						  'margin-left',
						  '20px'
						  );
			  }
		  };

		  // Après drop
		  this.YUIDD.b4EndDrag = function()
		  {
			  _YUD.setStyle(
					  this.getEl(),
					  'z-index',
					  9999
					  );
			  _YUD.setStyle(
					  this.getEl(),
					  'opacity',
					  1
					  );
		  };

		  //On drag over
		  this.YUIDD.onDragOver = function(e, id)
		  {
			  if (OB_SortList.getObjById(id) &&
					  OB_SortList.getObjById(id) != OB_SortList.getObjByEl(this.parent.element.parentNode))
			  {
				  // Si on est au dessus d'un target autre que celui de départ, on lui met une classe hover
				  _YUD.addClass(
						  OB_SortList.getObjById(id).getEl().parentNode,
						  'OB_SortList_hover'
						  );
			  }
			  if (OB_SortListItem.getObjById(id))
			  {
				  var thisTarget = OB_SortListItem.getObjById(id);

				  var region = _YUD.getRegion(thisTarget.element);
				  var mouse = _YUE.getXY(e)[1];
				  var mid = parseInt(region.top + (region.bottom - region.top) / 2);

				  if (mouse < mid)
				  {
					  // au dessus
					  thisTarget.getParentTarget().addTempItem(
							  this,
							  {
before: thisTarget
}
);
					  }
else
{
	// au dessous
	thisTarget.getParentTarget().addTempItem(
			this.parent,
			{
after: thisTarget
}
);
	}
}
};

//On drag out
this.YUIDD.onDragOut = function(e, id)
{
	_YUD.removeClass(
			getElmt(id).parentNode,
			'OB_SortList_hover'
			);

	if (OB_SortList.getObjById(id))
	{
		OB_SortList.getObjById(id).removeTempLi();
	}
};

// On drag and drop
this.YUIDD.onDragDrop = function(e, id)
{
	_YUD.removeClass(
			getElmt(id).parentNode,
			'OB_SortList_hover'
			);

	var list = OB_SortList.getObjById(id);

	if (list)
	{
		if (list.tempLi.parentNode == list.element ||
				!list.independant)
		{
			var oldList = this.parent.getParentTarget();
			list.addItem(this.parent);
			list.removeTempLi();
			oldList.serialize();
			list.serialize();
			this.parent.onDragDrop();
		}
		else
		{
			this.onInvalidDrop();
		}
	}

};

// On invalid drag and drop
this.YUIDD.onInvalidDrop = function()
{
	// Animation de retour au point de départ
	attributes = {
points: {
to: [
		this.startPageX,
	this.startPageY
		]
		},
opacity: {
to: 1
		 }
	};
	var anim = new YAHOO.util.Motion(
			this.dragElId,
			attributes,
			0.2,
			YAHOO.util.Easing.easeOut
			);
	anim.animate();
};

// Ajout du handle
if (handle)
{
	this.handle = document.createElement('div');
	this.handle.className = handle;
	this.element.appendChild(
			this.handle
			);
	this.YUIDD.setHandleElId(
			this.handle
			);
}
},
	/**
	 * getEl
	 */
getEl: function()
{
	return this.element;
},
	/**
	 * getParentTarget
	 */
getParentTarget: function()
{
	return OB_SortList.getObjByEl(
			this.element.parentNode
			);
},
	/**
	 * onDragDrop
	 */
onDragDrop: function() {

			},
			/**
			 * destroy
			 */
destroy: function() {
			 if (this.element &&
					 this.element.parentNode)
			 {
				 this.element.parentNode.removeChild(this.element);
			 }
		 }
};
OB_SortListItem.getObjById = function(id)
{
	for (var i = 0; OB_SortListItems[i]; i++)
	{
		if (OB_SortListItems[i].getEl().getAttribute('id') == id)
		{
			return OB_SortListItems[i];
		}
	}
	return false;
};
OB_SortListItem.getObjByEl = function(el)
{
	for (var i = 0; OB_SortListItems[i]; i++)
	{
		if (OB_SortListItems[i].getEl() == el)
		{
			return OB_SortListItems[i];
		}
	}
	return false;
};
/**
 * destroyAll
 */
OB_SortListItem.destroyAll = function() {
	for (var i = 0; OB_SortListItems[i]; i++)
	{
		OB_SortListItems[i].destroy();
	}
	OB_SortListItems = new Array();
};





OB_NavTabs = new Array();
/**
 * pageEditor.tab class
 * @constructor
 * @author Hadrien Lanneau
 */
OB_NavTab = function(id)
{
	/**
	 * element
	 * @type Element
	 */
	this.id = id;
	/**
	 * element
	 * @type Element
	 */
	this.element = getElmt(id);

	if (this.element)
	{
		OB_NavTabs.push(this);

		this.init();
	}
	else
	{
		return null;
	}
};
OB_NavTab.prototype = {
	/**
	 * Initialization
	 */
init: function()
	  {
		  this.value = this.element.innerHTML.substr(
				  1,
				  this.element.innerHTML.length-2
				  );
	  },
	  /**
	   * Set value
	   */
setValue: function(value)
		  {
			  this.value = value;
			  this.element.innerHTML =
				  '(' + value + ')';
		  },
		  /**
		   * increment value
		   */
increment: function(value) {
			   if (!value)
			   {
				   value = 1;
			   }
			   this.setValue(
					   parseInt(this.value) + 1
					   );
			   this.toggle();
		   },
		   /**
			* increment value
			*/
decrement: function(value) {
			   if (!value)
			   {
				   value = 1;
			   }
			   this.setValue(
					   parseInt(this.value) - 1
					   );
			   this.toggle();
		   },
		   /**
			* toggle
			*/
toggle: function() {
			if (this.value > 0)
			{
				this.element.parentNode.style.display = 'block';
			}
			else
			{
				this.element.parentNode.style.display = 'none';
			}
		}
};
OB_NavTab.toggle = function()
{
	for (var i = 0; OB_NavTabs[i]; i++)
	{
		OB_NavTabs[i].toggle();
	}
};

/**
 * Add blur and focus events on inputs label linked by their for attribute
 *		Exemple :
 *			YAHOO.OB.linkInputFor(
 *				function(el)
 *				{
 *					el.style.color = 'red';
 *				},
 *				function(el)
 *				{
 *					el.style.color = 'black';
 *				}
 *			);
 * @param {Function} fnFocus Function called on input focus
 * @param {Function} fnBlur Function called on input blur
 */
var OB_LinkInputFor = function(fnFocus, fnBlur)
{
	var formElsBruts = new Array();
	formElsBruts.push(
			document.getElementsByTagName('input')
			);
	formElsBruts.push(
			document.getElementsByTagName('select')
			);
	formElsBruts.push(
			document.getElementsByTagName('textarea')
			);

	var formEls = new Array();
	for (var i = 0; formElsBruts[i]; i++)
	{
		for (var j = 0; formElsBruts[i][j]; j++)
		{
			formEls.push(
					formElsBruts[i][j]
					);
		}
	}

	for (i = 0; formEls[i]; i++)
	{
		formEls[i].fors = _YUD.getElementsBy(
				function(el)
				{
				return (el.getAttribute('for') == formEls[i].id);
				}
				);
		formEls[i].onfocus = function()
		{
			for (j = 0; this.fors[j]; j++)
			{
				fnFocus(this.fors[j]);
			}
		};

		formEls[i].onblur = function()
		{
			for (j = 0; this.fors[j]; j++)
			{
				fnBlur(this.fors[j]);
			}
		};
	}
};

if (YAHOO &&
		YAHOO.widget &&
		YAHOO.widget.Button)
{
	/**
	 * Deactivate button and change its label
	 * @param {String} str new label
	 */
	YAHOO.widget.Button.prototype.deactivate = function(str)
	{
		if (this.__yui_events.click.subscribers[1])
		{
			this._oldOnClick = this.__yui_events.click.subscribers[1].fn;
		}

		this.unsubscribe(
				'click'
				);

		this.on(
				'click',
				function()
				{
				return false;
				}
			   );
		if (str)
		{
			this.oldLabel = this.get('label');

			this.setAttributes(
					{
label: str
}
);
			}

this._deactivated = true;
};

/**
 * Re-activate button and change its label
 * @param {String} str new label
 */
YAHOO.widget.Button.prototype.reactivate = function(str)
{
	if (!this._deactivated)
	{
		return false;
	}
	this.unsubscribe(
			'click'
			);
	if (this._oldOnClick)
	{

		this.on(
				'click',
				this._oldOnClick,
				this,
				this
			   );
	}

	if (str)
	{
		this.setAttributes(
				{
label: str
}
);
		}
else if(this.oldLabel)
{
	this.setAttributes(
			{
label: this.oldLabel
}
);
	}

this._deactivated = false;
};

/**
 * Action Button (orange) class
 * @extends YAHOO.widget.Button
 * @constructor
 * @author Hadrien Lanneau
 */
YAHOO.widget.ActionButton = function(id, params)
{
	YAHOO.widget.ActionButton.superclass.constructor.call(this, id, params);
	this.addClass('default');
};

YAHOO.lang.extend(
		YAHOO.widget.ActionButton,
		YAHOO.widget.Button
		);

/**
 * Search Button (blue) class
 * @extends YAHOO.widget.Button
 * @constructor
 * @author Hadrien Lanneau
 */
YAHOO.widget.SearchButton = function(id, params)
{
	YAHOO.widget.ActionButton.superclass.constructor.call(this, id, params);
	this.addClass('search');
};

YAHOO.lang.extend(
		YAHOO.widget.SearchButton,
		YAHOO.widget.Button
		);


YAHOO.widget.Buttons = {};
YAHOO.widget._buttons = new Array();

YAHOO.widget.Buttons.ACTION = 1;
YAHOO.widget.Buttons.SEARCH = 2;
/**
 * Morph inputs into YAHOO.widget.Button
 */
YAHOO.widget.Buttons.createButtons = function(className, action)
{
	if (getBrowser() == 'ie')
	{
		return false;
	}
	try
	{
		buttons = _YUD.getElementsByClassName(className);
		for (var i = 0; buttons[i]; i++)
		{
			if (!_YUD.hasClass(
						buttons[i],
						'noYui'
						))
			{
				if (action &&
						action == YAHOO.widget.Buttons.ACTION)
				{
					buttons[i].newButton = new YAHOO.widget.ActionButton(
							buttons[i]
							);
				}
				else if (action &&
						action == YAHOO.widget.Buttons.SEARCH)
				{
					buttons[i].newButton = new YAHOO.widget.SearchButton(
							buttons[i]
							);
				}
				else
				{
					buttons[i].newButton = new YAHOO.widget.Button(
							buttons[i]
							);
				}
				if (buttons[i].onclick)
				{
					buttons[i].newButton.on(
							'click',
							buttons[i].onclick,
							buttons[i],
							buttons[i]
							);
				}
				if (buttons[i].style)
				{
					for (var j = 0; buttons[i].style[j]; j++)
					{
						if (buttons[i].style[j])
						{
							var style = buttons[i].style[j];
							// Remplacement des noms css en noms JS
							if (style == 'font-size')
							{
								style = 'fontSize';
							}
							// Penser à rajouter les autres au fur à mesure

							buttons[i].newButton._button.style[style] =
								buttons[i].style[style];
						}
					}
				}

				// Debug width IE
				buttons[i].newButton._button.style.width =
					buttons[i].style['width'];


				YAHOO.widget._buttons.push(
						buttons[i].newButton
						);
			}
		}
	}
	catch (e) {}
};
YAHOO.widget.Buttons.getById = function(id)
{
	for (var i = 0; YAHOO.widget._buttons[i]; i++)
	{
		if (YAHOO.widget._buttons[i]._button.parentNode.parentNode.id == id)
		{
			return YAHOO.widget._buttons[i];
		}
	}
	return false;
};
}



var OB_Checks = new Array();
/**
 * OB_Check class
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_Check = function(form, params)
{
	/**
	 * element
	 * @type Element
	 */
	this.element = getElmt(form);
	/**
	 * params
	 * @type Object
	 */
	this.params = params ?
		params :
		{};
	/**
	 * Inputs
	 * @type Object
	 */
	this.inputs = this.params.inputs ?
		this.params.inputs :
		{};
	/**
	 * valid
	 * @type Boolean
	 */
	this.valid = false;

	this.init();
};
OB_Check.prototype =
{
	/**
	 * Initialization
	 */
init: function()
	  {
		  for (name in this.inputs)
		  {
			  var input = this.element[name];
			  input.ob_check = this;
			  input.params = this.inputs[name];
			  input.onblur = function()
			  {
				  // Event on blur
				  if (this.ob_check.params.events &&
						  this.ob_check.params.events.onBlur)
				  {
					  this.ob_check.params.events.onBlur(this);
				  }
				  // custom event
				  if (this.params.fn)
				  {
					  this.params.fn(this);
				  }
				  var invalid = false;
				  for (test in this.params.tests)
				  {
					  var res = this.ob_check.check(
							  this,
							  test,
							  this.params.tests[test].arg
							  );
					  if (res === 1)
					  {
						  return;
					  }
					  if (!res)
					  {
						  invalid = this.params.tests[test].error;
					  }
				  }
				  if (!invalid)
				  {
					  this.parentNode.parentNode.className = 'ok';
					  this.parentNode.parentNode.getElementsByTagName(
							  'td'
							  )[2].getElementsByTagName('p')[0].innerHTML =
						  this.params.ok;
				  }
				  else
				  {
					  this.parentNode.parentNode.className = 'error';
					  this.parentNode.parentNode.getElementsByTagName(
							  'td'
							  )[2].getElementsByTagName('p')[0].innerHTML =
						  invalid;
				  }
			  };
			  input.onfocus = function()
			  {
				  if (this.ob_check.params.events &&
						  this.ob_check.params.events.onFocus)
				  {
					  this.ob_check.params.events.onFocus(this);
				  }
			  }
		  }

		  this.element.ob_check = this;
		  this.element.onsubmit = function()
		  {
			  return this.ob_check.checkAll();
		  }
	  },
	  /**
	   * Check
	   */
check: function(el, test, arg)
	   {
		   var value = el.value;
		   switch (test)
		   {
			   // Test eMail
			   case 'email':
				   return value.match(
						/^((([a-z]|[0-9]|!|#|$|%|&|'|\*|\+|\-|\/|=|\?|\^|_|`|\{|\||\}|~)+(\.([a-z]|[0-9]|!|#|$|%|&|'|\*|\+|\-|\/|=|\?|\^|_|`|\{|\||\}|~)+)*)@((((([a-z]|[0-9])([a-z]|[0-9]|\-){0,61}([a-z]|[0-9])\.))*([a-z]|[0-9])([a-z]|[0-9]|\-){0,61}([a-z]|[0-9])\.)[\w]{2,4}|(((([0-9]){1,3}\.){3}([0-9]){1,3}))|(\[((([0-9]){1,3}\.){3}([0-9]){1,3})\])))$/i
				   );

			   // Check if it's a valid URL
			   case 'url':
				   return value.match(
						/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/
				   );

				   // Test alphanum min 4 chars
			   case 'password':
				   return value.match(
						   /^[a-zA-Z0-9]{4,}$/
						   );

				   // Test same value as arg.value
			   case 'sameas':
				   return value == getElmt(arg).value;

				   // Test if value is null
			   case 'notNull':
				   return value != '';

				   // Test if input is checked
			   case 'checked':
				   return el.checked;

				   // Custom test
			   case 'custom':
				   return arg(el);

			   case 'maxLength':
				   return value.length < arg;
		   }
		   return true;
	   },
	   /**
		* checkAll
		*/
checkAll: function()
		  {
			  var allValid = true;
			  for (name in this.inputs)
			  {
				  var invalid = false;
				  for (test in this.inputs[name].tests)
				  {
					  if (!this.check(
								  this.element[name],
								  test,
								  this.inputs[name].tests[test].arg
								  ))
					  {
						  invalid = this.inputs[name].tests[test].error;
					  }
				  }
				  if (invalid === null)
				  {
					  return;
				  }
				  if (!invalid)
				  {
					  this.element[name].parentNode.parentNode.className = 'ok';
					  this.element[name].parentNode.parentNode.getElementsByTagName(
							  'td'
							  )[2].getElementsByTagName('p')[0].innerHTML =
						  this.inputs[name].ok;
				  }
				  else
				  {
					  this.element[name].parentNode.parentNode.className = 'error';
					  this.element[name].parentNode.parentNode.getElementsByTagName(
							  'td'
							  )[2].getElementsByTagName('p')[0].innerHTML =
						  invalid;

					  allValid = false;
				  }
			  }

			  return allValid;
		  }
}

var OB_Calendar = new Array();
/**
 * OB_Calendar class
 * @constructor
 * @author Hadrien Lanneau
 */
var OB_Calendar = function(form, container, renderer)
{
	/**
	 * element
	 * @type Element
	 */
	this.element = getElmt(form);
	/**
	 * container
	 * @type Element
	 */
	this.container = getElmt(container)

	/**
	 * Custom renderer
	 *
	 */
	this.renderer = renderer

	this.cal = null;

	this.init();
};
OB_Calendar.prototype =
{
	/**
	 * Initialization
	 */
	init: function()
	{
		  // Span element for calendar
		var aSpan = document.createElement('span');
		aSpan.style.position = 'absolute';
		aSpan.setAttribute(
				'href',
				'#'
				);
		aSpan.setAttribute(
				'id',
				'trigger'
				);
		aSpan.setAttribute(
				'style',
				'cursor: pointer;'
				);

		var aImg = document.createElement('img');
		aImg.setAttribute(
			'src',
			IMGUrl + 'p_calendrier.gif'
		);
		aImg.setAttribute(
			'alt',
			'calendar'
		);


		// Appends to parents
		aSpan.appendChild(
  			  this.container
			  );
		aSpan.appendChild(
  			  aImg
  			  );
		aSpan.parent = this;

		this.element.parentNode.appendChild(aSpan);

		this.cal  = new YAHOO.widget.Calendar(
				'yui_calendar'+this.element.id,
				this.container.id,
				{
					selected: this.element ?
						this.element.value :
						0,
					SHOW_WEEKDAYS: true,
					close: true
				}
			);
	// Event
			this.cal.selectEvent.subscribe(
				function(type, args, _this)
				{
					date = _this.getSelectedDates()[0];

					oldDate = new Date(
						getElmt('publicationDate').value
					);
					getElmt('publicationDate').value =
						((date.getDate() < 10) ?
							('0' + date.getDate()) :
							date.getDate()) +
						'/' +
						((date.getMonth()+1 < 10) ?
							('0' + (date.getMonth()+1)) :
							(date.getMonth()+1)) +
						'/' +
						date.getFullYear() +
						' ' +
						((oldDate.getHours() < 10) ?
							('0' + oldDate.getHours()) :
							(oldDate.getHours())) +
						':' +
						((oldDate.getMinutes() < 10) ?
							('0' + oldDate.getMinutes()) :
							(oldDate.getMinutes()));
					this.cal.hide();
				},
				this.cal
			);
			// Config
			this.cal.cfg.setProperty(
				"MONTHS_LONG",
				[
					getLocalizedString('Janvier'),
					getLocalizedString('Fevrier'),
					getLocalizedString('Mars'),
					getLocalizedString('Avril'),
					getLocalizedString('Mai'),
					getLocalizedString('Juin'),
					getLocalizedString('Juillet'),
					getLocalizedString('Aout'),
					getLocalizedString('Septembre'),
					getLocalizedString('Octobre'),
					getLocalizedString('Novembre'),
					getLocalizedString('Decembre')
				]
			);
			this.cal.cfg.setProperty(
				"WEEKDAYS_SHORT",
				[
					getLocalizedString('Dim'),
					getLocalizedString('Lun'),
					getLocalizedString('Mar'),
					getLocalizedString('Mer'),
					getLocalizedString('Jeu'),
					getLocalizedString('Ven'),
					getLocalizedString('Sam')
				]
			);
			this.cal.cfg.setProperty(
				"START_WEEKDAY",
				1
			);
			// render
			this.cal.render();
			// Hiding
			this.cal.hide();

			// Events
			aSpan.onclick = function()
			{
				var divElmt = this.parent.container;
				if (divElmt.style.display == 'none')
				{
					this.parent.cal.show();
				}
				else
				{
					this.parent.cal.hide();
				}
				return false;
			}
		}


	};

