(function( $ ) {
	$.fn.eip = function( save_url, options ) {
		// Defaults
		var opt = {
			save_url			: save_url,

			save_on_enter		: true,
			cancel_on_esc		: true,
			focus_edit			: true,
			select_text			: false,
			edit_event			: "click",
			select_options		: false,
			data				: false,

			form_type			: "text", // text, textarea, select
			size				: false, // calculate at run time
			max_size			: 60,
			rows				: false, // calculate at run time
			max_rows			: 10,
			cols				: 60,

			savebutton_text		: "SAVE",
			savebutton_class	: "jeip-savebutton",
			cancelbutton_text	: "CANCEL",
			cancelbutton_class	: "jeip-cancelbutton",

			editor_class		: "jeip-editor",
			editfield_class		: "jeip-editfield",

			saving_text			: "Saving ...",
			saving_class		: "jeip-saving",

			saving				: '<span id="saving-#{id}" class="#{saving_class}" style="display: none;">#{saving_text}</span>',
			
			start_editor_form	: '<span id="editor-#{id}" class="#{editor_class}" style="display: none;">',
			stop_editor_form	: '</span>',

			start_form          : '<span id="edform-#{id}" class="#{edform_class}" style="display: none;">',
			form_buttons		: '<span><input type="button" id="save-#{id}" class="#{savebutton_class}" value="#{savebutton_text}" /> <input type="button" id="cancel-#{id}" class="#{cancelbutton_class}" value="#{cancelbutton_text}" /></span>',
			stop_form			: '</span>',

			text_form			: '<input type="text" id="edit-#{id}" class="#{editfield_class}" value="#{value}" /> <br />',
			textarea_form		: '<textarea cols="#{cols}" rows="#{rows}" id="edit-#{id}" class="#{editfield_class}">#{value}</textarea> <br />',
			start_select_form	: '<select id="edit-#{id}" class="#{editfield_clas}">',
			select_option_form	: '<option id="edit-option-#{id}-#{option_value}" value="#{option_value}" #{selected}>#{option_text}</option>',
			stop_select_form	: '</select>',

			on_error			: function( msg ) {
				if (msg!='') {
					alert( msg );
				} else {
					alert('Unknown ieip error');
				}
			}
		}; // defaults

		if( options ) {
			$.extend( opt, options );
		}

		this.each( function( ) {
			var self = this;

			$( this ).unbind( opt.edit_event);
			$( this ).bind( opt.edit_event, function( e ) {
				_editMode( this );
			} );
		} ); // this.each

		// Private functions
		var _editMode = function( self ) {
			var editid = $( self ).attr('field');
			var ttype = $( self ).attr('type');
			if ((ttype != undefined) && (ttype != '')) {
				opt.form_type = ttype;
			}

			$( self ).unbind( opt.edit_event );

			$( '#'+editid ).fadeOut("fast");
			$( self ).fadeOut( "fast", function( e ) {
				var id		= self.id;
				var editid  = $( self ).attr('field');
				var value	= $( '#'+editid ).html( );

				var safe_value	= value.replace( /</g, "&lt;" );
				safe_value		= value.replace( />/g, "&gt;" );
				safe_value		= value.replace( /"/g, "&quot;" );

				var orig_option_value = false;

				var form = _template( opt.start_editor_form, {
					id				: editid,
					editor_class	: opt.editor_class
				} );

				if( opt.form_type == 'text' ) {
					form += _template( opt.text_form, {
						id				: editid,
						editfield_class	: opt.editfield_class,
						value			: value
					} );
				} // text form
				else if( opt.form_type == 'textarea' ) {
					var length = value.length;
					var rows = ( length / opt.cols ) + 2;

					for( var i = 0; i < length; i++ ) {
						if( value.charAt( i ) == "\n" ) {
							rows++;
						}
					}

					if( rows > opt.max_rows ) {
						rows = opt.max_rows;
					}
					if( opt.rows != false ) {
						rows = opt.rows;
					}
					rows = parseInt( rows );

					form += _template( opt.textarea_form, {
						id				: editid,
						cols			: opt.cols,
						rows			: rows,
						editfield_class	: opt.editfield_class,
						value			: value
					} );
				} // textarea form
				else if( opt.form_type == 'select' ) {
					form += _template( opt.start_select_form, {
						id				: editid,
						editfield_class	: opt.editfield_class
					} );

					$.each( opt.select_options, function( k, v ) {
						var selected = '';
						if( v == value ) {
							selected = 'selected="selected"';
						}

						if( value == v ) {
							orig_option_value = k;
						}

						form += _template( opt.select_option_form, {
							id			: editid,
							option_value: k,
							option_text	: v,
							selected	: selected
						} );
					} );

					form += _template( opt.stop_select_form, { } );
				} // select form

				form += _template( opt.stop_editor_form, { } );

				var form2 = _template( opt.start_form, {
					id				: editid,
					editor_class	: opt.editor_class
				} );

				form2 += _template( opt.form_buttons, {
					id					: editid,
					savebutton_class	: opt.savebutton_class,
					savebutton_text		: opt.savebutton_text,
					cancelbutton_class	: opt.cancelbutton_class,
					cancelbutton_text	: opt.cancelbutton_text
				} );

				form2 += _template( opt.stop_form, {
					id				: editid,
					editor_class	: opt.editor_class
				} );

				$( '#' + editid ).after( form );
				$( self ).after( form2 );

				$( "#editor-" + editid ).fadeIn( "fast" );
				$( "#edform-" + editid ).fadeIn( "fast" );

				if( opt.focus_edit ) {
					$( "#edit-" + editid ).focus( );
				}

				if( opt.select_text ) {
					$( "#edit-" + editid ).select( );
				}

				$( "#cancel-" + editid ).bind( "click", function( e ) {
					_cancelEdit( self );
				} );

				$( "#edit-" + editid ).keydown( function( e ) {
					// cancel
					if( e.which == 27 ) {
						_cancelEdit( self );
					}

					// save
					if( opt.form_type != "textarea" && e.which == 13 ) {
						_saveEdit( self, orig_option_value );
					}
				} );

				$( "#save-" + editid ).bind( "click", function( e ) {
					return _saveEdit( self, orig_option_value );
				} ); // save click
			} ); // this fadeOut
		} // function _editMode

		var _template = function( template, values ) {
			var replace = function( str, match ) {
				return typeof values[match] === "string" || typeof values[match] === 'number' ? values[match] : str;
			};
			return template.replace( /#\{([^{}]*)}/g, replace );
		};

		var _trim = function( str ) {
			return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
		}

		var _cancelEdit = function( self ) {
			var editid  = $( self ).attr('field');
			$( "#editor-" + editid ).fadeOut( "fast" );
			$( "#editor-" + editid ).remove( );
			$( "#edform-" + editid ).fadeOut( "fast" );
			$( "#edform-" + editid ).remove( );

			$( self ).bind( opt.edit_event, function( e ) {
				_editMode( self );
			} );

			$( self ).fadeIn( "fast" );
			$( '#'+editid ).fadeIn( "fast" );
		};
		
		var _saveEdit = function( self, orig_option_value ) {
			var editid = $( self ).attr('field');
			var orig_value = $( '#'+editid ).html( );
			var new_value = $( "#edit-" + editid ).attr( "value" );
			var varkey = editid;
			if ($( self ).attr('key') != null) {
				varkey = $( self ).attr('key');
			}

			if( orig_value == new_value ) {
				_cancelEdit( self );
				return true;
			}

			$( "#editor-" + editid ).after( _template( opt.saving, {
				id			: editid,
				saving_class: opt.saving_class,
				saving_text	: opt.saving_text
			} ) );
			$( "#editor-" + editid ).fadeOut( "fast", function( ) {
				$( "#saving-" + editid).fadeIn( "fast" );
			} );

			var datasend = { ajax : '1' };
			datasend[varkey] = new_value;

			$( self ).fadeIn('fast');
			$( "#editor-" + editid ).fadeOut( "fast" );
			$( "#editor-" + editid ).remove( );
			$( "#edform-" + editid ).fadeOut( "fast" );
			$( "#edform-" + editid ).remove( );

			var posturl = $( self ).attr( "url" );
			if (posturl == null || posturl == '') {
				posturl = opt.save_url;
			}

			$.ajax( {
				url		: posturl,
				type	: "POST",
				dataType: "json",
				data	: datasend,
				error   : function (data) {
					var editid = $( self ).attr('field');
					alert('Ajax query failed. Try again.');
					$( "#saving-" + editid ).fadeOut( "fast" );
					$( "#saving-" + editid ).remove( );
					$( '#' + editid ).fadeIn('fast');

					$( self ).bind( opt.edit_event, function( e ) {
						_editMode( self );
					} );

				},
				success	: function( data ) {
					var editid = $( self ).attr('field');

					$( "#saving-" + editid ).fadeOut( "fast" );
					$( "#saving-" + editid ).remove( );

					$( self ).bind( opt.edit_event, function( e ) {
						_editMode( self );
					} );

					$( '#' + editid ).fadeIn('fast');

					awjs_json_handler(data);

				} // success
			} ); // ajax
		}; // _saveEdit


	}; // inplaceEdit
})( jQuery );

