






var EditableContent = new Class({
	_defaultTargetUrl: null,
	_defaultEditMode: null,
	_observedElements: null,
	_bindings: null,
	
	/**
	 * Constructor, is called when a new instance is created
	 */
	initialize: function(config) {
		if ($chk(config.defaultTargetUrl)) {
			this._defaultTargetUrl = config.defaultTargetUrl;
		}
		
		if ($chk(config.defaultEditMode)) {
			this._defaultEditMode = config.defaultEditMode;
		}
		
		this._observedElements = new Hash();
		this._bindings = new Hash();
	},
	
	observeElements: function(elms) {
		var i, elm, elmInfo;
		
		for (i = 0; i < elms.length; i++) {
			elmInfo = new Hash(elms[i]);
			this._observeElement(elmInfo)
		}
	},
	
	_observeElement: function(elmInfo) {	
		// Check config integrity
		if (!elmInfo.has('editMode')) {
			elmInfo.editMode = this._defaultEditMode;
		}
		
		if (!elmInfo.has('targetUrl')) { 
			elmInfo.targetUrl = this._defaultTargetUrl;
		}
		
		if (!elmInfo.has('id') || !elmInfo.has('dbId') || !elmInfo.has('targetUrl') || !elmInfo.has('editMode')) {
			alert('Element with index ' + i + ' is not correctly configured!');
			return;
		}
		
		elmInfo.contentBackup = '';
		
		elm = $(elmInfo.id);
		elm.addClass('editable');
		
		this._bindings.set('observe_click_' + elmInfo.id, this._editContent.bindWithEvent(this));
		elm.addEvent('click', this._bindings.get('observe_click_' + elmInfo.id));
		
		this._observedElements.set(elmInfo.id, elmInfo);
	},
	
	_editContent: function(e) {
		var elm = $(e.target);
		e.stop();
		
		if (!this._observedElements.has(elm.id)) {
			alert ('Element with id "' + elm.id + '" is not editable!');
			return;
		}

		var elmInfo = this._observedElements.get(elm.id);
				
		// Remove doubleclick event
		elm.removeEvent('click', this._bindings.get('observe_click_' + elmInfo.id));

		// Remove editable-empty CSS class
        elm.removeClass('editable-empty');

		
		// Get content
		var content = elm.get('html').trim();
		
		// Backup content
		elmInfo.contentBackup = content;

		// Create input element
		var elmField;
		switch (elmInfo.editMode) {
			case 'textarea':
				elmField = new Element('textarea', {text: content});
				break;
			case 'input':
				elmField = new Element('input', {value: content, maxlength: 140, onfocus: 'this.focus();this.select()'});
				break;
			default:
				alert ('EditMode "' + elmInfo.editMode + '" is not defined!');
				return;
		}
		
		// Add blur event
		elmField.addEvent('blur', this._onBlur.bindWithEvent(this));
		
		// Add key events
		elmField.addEvent('keydown', this._observeInputField.bindWithEvent(this));
		
		// Erase content
		elm.set('html', '');
		
		// Insert input
		elmField.inject(elm);
		
		this._observedElements.set(elm.id, elmInfo);
		
		elmField.focus();
	},
	
	_restoreContent: function(e) {
		var elmField = $(e.target);
		var elm = elmField.getParent();
		e.stop();
				
		var elmInfo = this._observedElements.get(elm.id);
		
		// Get content
		elm.set('html', elmInfo.contentBackup);
        
        if (elmInfo.contentBackup == '') {
            elm.addClass('editable-empty');
        } else {
            elm.removeClass('editable-empty');
        }
		this._observeElement(elmInfo);
	},
	
	_saveContent: function(e) {
		var elmField = $(e.target);
		var elm = elmField.getParent();
		e.stop();
				
		var elmInfo = this._observedElements.get(elm.id);
		
		switch (elmInfo.editMode) {
			case 'input':
			case 'textarea':
				newContent = elmField.value;
				break;
			default:
				alert ('EditMode "' + elmInfo.editMode + '" is not defined!');
				return;
		}
        
        newContent = newContent.trim();
		
		// Get content
		elm.set('html', newContent);
        
        // If content is empty, add a special class, otherwise remove it
        if (newContent == '') {
            elm.addClass('editable-empty');
        } else {
            elm.removeClass('editable-empty');
        }
        
		this._observeElement(elmInfo);
		
		// Save content
		var postData = new Hash({
			content: newContent,
			id: elmInfo.dbId
		})
		
		var request = new Request.JSON({
			url: elmInfo.targetUrl,
			method: 'post',
			data: postData,
			onSuccess: function(result) {
				if (result.success != true) {
					alert(result.error);
				}
			},
			onFailure: function(instance) {
				alert(elmInfo.targetUrl + ': ' + instance.statusText + ' (' + instance.status + ')');
			}
		}).send();
	},
	
	_observeInputField: function(e) {
		var conf;
		var elmField = $(e.target);
		
		var elm = elmField.getParent();				
		var elmInfo = this._observedElements.get(elm.id);
		
		switch (e.key) {
			case 'enter':
				switch(elmInfo.editMode) {
					case 'input':
						if (this._contentChanged(e)) {
							elmField.removeEvents('blur');
//							conf = confirm('Save changes?');
//							if (conf == true) {
								this._saveContent(e);
//							}
						}
						break;
				}
				break;
			case 'esc':
//				if (!this._contentChanged(e)) {
					this._restoreContent(e);
//				}
//				else {
//					elmField.removeEvents('blur');
//					conf = confirm('Save changes?');
//					if (conf == true) {
//						this._saveContent(e);
//					}
//					else {
//						this._restoreContent(e);
//					}
//				}
				break;
		}
	},
	
	_onBlur: function(e) {		
		if (this._contentChanged(e)) {
			var conf = confirm('Save changes?');
			if (conf == true) {
				this._saveContent(e);
			} else {
				this._restoreContent(e);
			}
		}
		else {
			this._restoreContent(e);
		}
	},
	
	_contentChanged: function(e) {
		var elmField = $(e.target);
		var elm = elmField.getParent();
		e.stop();
				
		var elmInfo = this._observedElements.get(elm.id);
		
		var newContent;
		
		switch (elmInfo.editMode) {
			case 'input':
			case 'textarea':
				newContent = elmField.value;
				break;
			default:
				alert ('EditMode "' + elmInfo.editMode + '" is not defined!');
				return;
		}

		if (newContent != elmInfo.contentBackup) {
			return true; // Content has changed
		}
		
		return false;
	}
});

			window.addEvent('domready', function() {
				var config = {
					defaultTargetUrl: '/ajax/status_update.php',
					defaultEditMode: 'input'
				}
				this.EditableContent = new EditableContent(config);
				this.EditableContent.observeElements([
					{id: 'p1', dbId: 1}
				]);
			});

