(function($) {

	// Nom du Plugin
	$.fn.editable = function(method) {

		// Méthodes publiques
		//
		// Elles peuvent être appelées depuis l'extérieur par
		// element.zoomPhoto('methodName', arg1, arg2, ... argn)
		// où "element" est un objet du DOM auquel on attache la méthode
		//
		// ou, de l'intérieur par
		// methods.methodName(arg1, arg2, ... argn)
		var methods = {

			// Constructeur
			init: function(options) {

				// the plugin's final properties are the merged default and user-provided properties (if any)
				// this has the advantage of not polluting the defaults, making them re-usable
				this.editable.settings = $.extend({}, this.editable.defaults, options);

				// Boucle sur les éléments attachés au plugin
				return this.each( function() {
					var $element = $(this), // reference to the jQuery version of the current DOM element
					element = this;  // reference to the actual DOM element

					// On stocke les options dans l'objet pour éviter les confusions si le plugin est appelé plusieurs fois
					// $element.data('settings', $.fn.editable.settings);					
					$element.css({
						'cursor': 'pointer',
						'position': 'relative'						
					});						
					$element.bind('click', helpers.onClick);
					
					if($.fn.editable.settings.image_edit)
						$('<img src="' + $.fn.editable.settings.image_edit + '" alt="Editer" style="display: block; position: absolute; top: 0; right: -24px" />').appendTo($element);	
					
				});
			}
		}

		// Méthodes privées
		// Elles ne peuvent être appelées que depuis l'intérieur du Plugin par
		// helpers.methodName(arg1, arg2, ... argn)
		var helpers = {
			getCss: function(elt){
				var css = {
					'display': 'block',
					'width': elt.css('width'),
					'height': elt.css('height'),
					'font-size': elt.css('font-size'),
					'font-family': elt.css('font-family'),
					'font-weight': elt.css('font-weight')
				};
				return css;
			},
			
			onClick: function(){					
				var self   = $(this);
				var css    = helpers.getCss(self);
				var classe = 'editable-textarea-' + $.fn.editable.settings.cpt;
				$.fn.editable.settings.cpt++;				
				var input  = $('<textarea class="' + classe + '" style="resize: none">' + self.text() + '</textarea>');
				input.css(css);
				self.html(input);				
				if($.fn.editable.settings.image_valid)
					$('<img src="' + $.fn.editable.settings.image_valid + '" alt="Valider" style="display: block; position: absolute; top: 0; right: -24px" />').appendTo(self);	
				self.unbind('click', helpers.onClick);										
				$('html').bind('mouseup', {input: input, self: self, classe: classe, css: css}, helpers.onMouseup);	
			},
			
			onMouseup: function(evt){	
				if(!$(evt.target).hasClass(evt.data.classe)){							
					var text = evt.data.input.val();
					evt.data.self.text(text);					
					$.ajax({
						url: $.fn.editable.settings.url,
						type: 'post',
						data: evt.data.self.attr('id') + '=' + text
					});					
					evt.data.input.remove();
					evt.data.self.css(evt.data.css);
					if($.fn.editable.settings.image_edit)
						$('<img src="' + $.fn.editable.settings.image_edit + '" alt="Editer" style="display: block; position: absolute; top: 0; right: -24px" />').appendTo(evt.data.self);	
					
					evt.data.self.bind('click', helpers.onClick);	
					$(this).unbind('mouseup', helpers.onMouseup);						
				}
			}
		}

		// if a method as the given argument exists
		if (methods[method]) {
			// call the respective method
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
			// if an object is given as method OR nothing is given as argument
		} else if (typeof method === 'object' || !method) {
			// call the initialization method
			return methods.init.apply(this, arguments);
			// otherwise
		} else {
			// trigger an error
			$.error('Method "' + method + '" does not exist in Editable plugin!');
		}

	}
	// Options par défaut
	$.fn.editable.defaults = {
		cpt: 0,
		image_edit: null,
		image_valid: null
	}

	// this will hold the merged default and user-provided options
	// you will have access to these options like:
	// this.pluginName.settings.propertyName from inside the plugin or
	// element.pluginName.settings.propertyName from outside the plugin, where "element" is the element the
	// plugin is attached to;
	$.fn.editable.settings = {}

})(jQuery);
