/*—~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C L A S S E S.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ E D I T   I N   P L A C E.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

editInPlace = new Class({
	options: {
		formTag: 'input',
		formItems: false,
		xhrsuccess: false
	},

	initialize: function(tagList, options) {
		options = $merge(this.options, options);
		$splat(tagList).each(function(tagObj) {
			tagObj.addEvents({
				'click': function() {
					if ($chk(tagObj.valueOriginal)) return;
					tagObj.valueOriginal = tagObj.get('text');
					tagObj.empty();
					tagObj.formTag = new Element(options.formTag, {
						'value': tagObj.valueOriginal,
						'styles': {
							'padding': '0px',
							'margin': '0px',
							'width': tagObj.getStyle('width'),
							'border': '0px',
							'color': '#ffffff',
							'background-color': 'transparent'
						},
						'events': {
							'blur': function() {
								tagObj.valueCurrent = (options.formTag == 'select') ? this.getElement('option[selected]').get('text').trim() : this.get('value').trim();
								if (tagObj.valueCurrent != tagObj.valueOriginal) {
									tagObj.value = this.get('value').trim();
									messageBox.messageBoxShow({
										title: "Sauvegarde",
										duration: false,
										xhr: $merge(editListingOptions, tagObj.getParent().options, tagObj.options, {
											'xhrAct': 'updateData',
											'dbTableFieldData': tagObj.value
										}),
										xhrsuccess: function() {
											if (!$('messageBoxContent').get('text').test('erreur', 'i')) {
												tagObj.set('text', tagObj.valueCurrent);
												options.xhrsuccess.run();
											} else
												tagObj.set('text', tagObj.valueOriginal);
											delete tagObj.valueOriginal, tagObj.valueCurrent;
											tagObj.formTag.destroy();
										}						
									});
								} else {
									tagObj.set('text', tagObj.valueOriginal);
									delete tagObj.valueOriginal, tagObj.valueCurrent;
									this.destroy();
								}
							},
							'change': function() {
								if (options.formTag == 'select')
									this.blur();
								return;
							},
							'keydown': function(event) {
								if ((event.key=="enter") || (event.key=="tab") || (event.key=="esc"))
									this.blur(); return;
							}
						}
					});
					// Select options
					if ($chk(options.formItems)) {
						$each(options.formItems, function(formItem, i) {
							var formOption = new Element('option', {'value': i}).set('text', formItem).inject(tagObj.formTag);
							if (formItem == tagObj.valueOriginal)
								formOption.set('selected', 'selected');
						});
					}
					tagObj.formTag.inject(tagObj).focus();
				}
			});
		});
	}

});




/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ F U N C T I O N.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TOOL FUNCTIONS.
	function fieldOnFocus(tagField) {
		fieldErase = window.setInterval( function() {
			tagField.set('value', tagField.get('value').substr(0, (tagField.get('value').length-1)));
			if (tagField.get('value') == null || tagField.get('value') == '') {
				if (tagField.get('name').test('password', 'i'))
					tagField.set('type', 'password');
				window.clearInterval(fieldErase);
			}
		}, 25);
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ DATE-TIME CLOCK.
	function clockCompute() {
		if (!$chk(this.date)) {
			this.date = this.get('text').replace(/\W+/g, " ").trim().split(" ");
			this.dateHours = this.date[4].toInt();
			this.dateMinutes = this.date[5].toInt();
			this.dateSeconds = this.date[6].toInt();
		}
		this.dateSeconds += 1;
		if (this.dateSeconds == 60) {
			this.dateSeconds = 0;
			this.dateMinutes += 1;
			if (this.dateMinutes == 60) {
				this.dateMinutes = 0;
				this.dateHours += 1;
				if (this.dateHours == 24) {
					this.dateHours = 0;
					delete this.date;
					$clear(clockLoop);
					this.get('load', $merge(mainXhrOptions, {
						data: {'xhrAct':'dateDisplay'},
						onSuccess: function() {
							clockLoop = clockCompute.periodical(1000, this);
						}.bind(this)
					})).send();
				}
			}
		}
		this.set('text', this.date[0]+" "+this.date[1]+" "+this.date[2]+" "+this.date[3]+" ("+stringUnshift(this.dateHours.toString(),'0',2)+":"+stringUnshift(this.dateMinutes.toString(),'0',2)+":"+stringUnshift(this.dateSeconds.toString(),'0',2)+")");
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ EMAIL ADDRESS VALIDITY.
	function emailCheck(str) {
		var regExp = /^\w([-_.]?\w)*@\w([-_.]?\w)*\.([a-zA-Z]{2,4})$/;
		return (regExp.test(str));
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ URL-REWRITING.
	function urlRewriting(str, cut) {
		str = (cut) ? stringCut(str, cut) : str;
		str =str.replace(/\s/g, " ");
		str = str.replace(/['’‘´'\`]+/g, "'");
		str = str.replace(/[«»“”\"<{\(\[\]\)}>–—•]+/g, "");
		str = str.replace(/\&/g, "and");
		str = str.replace(/œ/g, "oe");
		str = htmlEntities(str, "HTML_ENTITIES", "ENT_NOQUOTES");
		str = str.replace(/&([a-z])[a-z]+;/gi, "$1");
		str = str.toLowerCase();
		str = str.replace(/\b[a-z]?\'/g, "-");
		str = str.replace(/[^0-9a-z]+/g, "-");
		return stringTrim(str, "-");
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STRING CUT.
	function stringCut(str, len) {
		if (str.length > len) {
			while (str.substr(len, 1) != " ")
				len--;
			str = str.substr(0, len);
		}
		return str;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STRING UNSHIFT.
	function stringUnshift(str, fill, len) {
		for (var i=str.length; i<len; i++)
			str = fill+str;
		return str;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STRING UCFIRST.
	function stringUcfirst(str) {
		return str.charAt(0).toUpperCase()+str.substr(1);
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STRING UCFIRST.
	function stringUcwords(str) {
		return (str).replace(/^(.)|\s(.)/g, function ($1) {
			return $1.toUpperCase();
		});
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STRING TRIM.
	function stringTrim(str, charlist) {
		var whitespace, l=0, i=0;
		str += "";
		if (!charlist) {
			whitespace = " \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";
		} else {
			charlist += "";
			whitespace = charlist.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '$1');
		}
		l = str.length;
		for (i=0; i<l; i++) {
			if (whitespace.indexOf(str.charAt(i)) === -1) {
				str = str.substring(i);
				break;
			}
		}
		l = str.length;
		for (i=l-1; i>=0; i--) {
			if (whitespace.indexOf(str.charAt(i)) === -1) {
				str = str.substring(0, i + 1);
				break;
			}
		}
		return whitespace.indexOf(str.charAt(0)) === -1 ? str : "";
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ STRING UCFIRST.
	function utf8Decode(str) {
		var arr=[], i=0, ac=0, c1=0, c2=0, c3=0;
		str += "";
		while (i < str.length) {
			c1 = str.charCodeAt(i);
			if (c1 < 128) {
				arr[ac++] = String.fromCharCode(c1);
				i++;
			} else if ((c1 > 191) && (c1 < 224)) {
				c2 = str.charCodeAt(i+1);
				arr[ac++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
				i += 2;
			} else {
				c2 = str.charCodeAt(i+1);
				c3 = str.charCodeAt(i+2);
				arr[ac++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return arr.join('');
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HTML ENTITIES.
	function htmlEntities(str, table, quoteStyle) {
		var histogram={}, symbol="", entity="";
		str = str.toString();	
		if (false === (histogram = getHtmlTranslationTable(table, quoteStyle)))
			return false;
		for (symbol in histogram) {
			entity = histogram[symbol];
			str = str.split(symbol).join(entity);
		}
		return str;
	}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HTML TRANSLATION TABLE.
	function getHtmlTranslationTable(table, quoteStyle) {
		var entities={}, histogram={}, decimal=0, symbol="";
		var constMappingTable={}, constMappingQuoteStyle={};
		var useTable={}, useQuoteStyle={};
		
		useTable = (table ? table.toUpperCase() : "HTML_SPECIALCHARS");
		useQuoteStyle = (quoteStyle ? quoteStyle.toUpperCase() : "ENT_COMPAT");
	
		constMappingTable[0] = "HTML_SPECIALCHARS";
		constMappingTable[1] = "HTML_ENTITIES";
		constMappingQuoteStyle[0] = "ENT_NOQUOTES";
		constMappingQuoteStyle[2] = "ENT_COMPAT";
		constMappingQuoteStyle[3] = "ENT_QUOTES";
		
		if (!isNaN(useTable))
			useTable = constMappingTable[useTable];
		if (!isNaN(useQuoteStyle))
			useQuoteStyle = constMappingQuoteStyle[useQuoteStyle];
	
		if (useTable == "HTML_SPECIALCHARS") {
			entities['38'] = "&amp;";
			if (useQuoteStyle != "ENT_NOQUOTES")
				entities['34'] = "&quot;";
			if (useQuoteStyle == "ENT_QUOTES")
				entities['39'] = "&#039;";
			entities['60'] = "&lt;";
			entities['62'] = "&gt;";
	
		} else if (useTable == "HTML_ENTITIES") {
			entities['38']  = "&amp;";
			if (useQuoteStyle != "ENT_NOQUOTES")
				entities['34'] = "&quot;";
			if (useQuoteStyle == "ENT_QUOTES")
				entities['39'] = "&#039;";
			entities['60']  = "&lt;";
			entities['62']  = "&gt;";
			entities['160'] = "&nbsp;";
			entities['161'] = "&iexcl;";
			entities['162'] = "&cent;";
			entities['163'] = "&pound;";
			entities['164'] = "&curren;";
			entities['165'] = "&yen;";
			entities['166'] = "&brvbar;";
			entities['167'] = "&sect;";
			entities['168'] = "&uml;";
			entities['169'] = "&copy;";
			entities['170'] = "&ordf;";
			entities['171'] = "&laquo;";
			entities['172'] = "&not;";
			entities['173'] = "&shy;";
			entities['174'] = "&reg;";
			entities['175'] = "&macr;";
			entities['176'] = "&deg;";
			entities['177'] = "&plusmn;";
			entities['178'] = "&sup2;";
			entities['179'] = "&sup3;";
			entities['180'] = "&acute;";
			entities['181'] = "&micro;";
			entities['182'] = "&para;";
			entities['183'] = "&middot;";
			entities['184'] = "&cedil;";
			entities['185'] = "&sup1;";
			entities['186'] = "&ordm;";
			entities['187'] = "&raquo;";
			entities['188'] = "&frac14;";
			entities['189'] = "&frac12;";
			entities['190'] = "&frac34;";
			entities['191'] = "&iquest;";
			entities['192'] = "&Agrave;";
			entities['193'] = "&Aacute;";
			entities['194'] = "&Acirc;";
			entities['195'] = "&Atilde;";
			entities['196'] = "&Auml;";
			entities['197'] = "&Aring;";
			entities['198'] = "&AElig;";
			entities['199'] = "&Ccedil;";
			entities['200'] = "&Egrave;";
			entities['201'] = "&Eacute;";
			entities['202'] = "&Ecirc;";
			entities['203'] = "&Euml;";
			entities['204'] = "&Igrave;";
			entities['205'] = "&Iacute;";
			entities['206'] = "&Icirc;";
			entities['207'] = "&Iuml;";
			entities['208'] = "&ETH;";
			entities['209'] = "&Ntilde;";
			entities['210'] = "&Ograve;";
			entities['211'] = "&Oacute;";
			entities['212'] = "&Ocirc;";
			entities['213'] = "&Otilde;";
			entities['214'] = "&Ouml;";
			entities['215'] = "&times;";
			entities['216'] = "&Oslash;";
			entities['217'] = "&Ugrave;";
			entities['218'] = "&Uacute;";
			entities['219'] = "&Ucirc;";
			entities['220'] = "&Uuml;";
			entities['221'] = "&Yacute;";
			entities['222'] = "&THORN;";
			entities['223'] = "&szlig;";
			entities['224'] = "&agrave;";
			entities['225'] = "&aacute;";
			entities['226'] = "&acirc;";
			entities['227'] = "&atilde;";
			entities['228'] = "&auml;";
			entities['229'] = "&aring;";
			entities['230'] = "&aelig;";
			entities['231'] = "&ccedil;";
			entities['232'] = "&egrave;";
			entities['233'] = "&eacute;";
			entities['234'] = "&ecirc;";
			entities['235'] = "&euml;";
			entities['236'] = "&igrave;";
			entities['237'] = "&iacute;";
			entities['238'] = "&icirc;";
			entities['239'] = "&iuml;";
			entities['240'] = "&eth;";
			entities['241'] = "&ntilde;";
			entities['242'] = "&ograve;";
			entities['243'] = "&oacute;";
			entities['244'] = "&ocirc;";
			entities['245'] = "&otilde;";
			entities['246'] = "&ouml;";
			entities['247'] = "&divide;";
			entities['248'] = "&oslash;";
			entities['249'] = "&ugrave;";
			entities['250'] = "&uacute;";
			entities['251'] = "&ucirc;";
			entities['252'] = "&uuml;";
			entities['253'] = "&yacute;";
			entities['254'] = "&thorn;";
			entities['255'] = "&yuml;";
			entities['8364'] = "&euro;";
		} else {
			throw Error("Table: "+useTable+' not supported');
			return false;
		}
	
		for (decimal in entities) {
			symbol = String.fromCharCode(decimal);
			histogram[symbol] = entities[decimal];
		}
	
		return histogram;
	}
