Ext.ns('Nexts.plugins');

Nexts.plugins.EditorChange = function(config) {
	Ext.apply(this, config);
	
	if (typeof(this.changeDelay) != "number") {
		this.changeDelay = 1500;
	}
	
	this.addEvents('change');
	
	Nexts.plugins.EditorChange.superclass.constructor.call(this);
};

Ext.extend(Nexts.plugins.EditorChange, Ext.util.Observable, {
	changeDelay: 1500,
	
	fireOnValid: true,
	
	fireOnDirty: true,
	
	fireOnEnter: true,
	
	clearOnEsc: true,
	
	editors: {},
	
	init: function(editor) {
		this.editors[editor.id] = {
			editor: editor,
			value: editor.getValue()
		};
		
		editor.on({
			render: this.bind,
			scope: this
		});

		if (this.changeDelay > 0) {
			this.changeTask = new Ext.util.DelayedTask(this.fireChange, this);
		}
	},
	
	bind: function(editor) {
		editor.el.on({
			keyup: {
				fn: this.onEditorKeyUp,
				scope: this
			},
			change: {
				fn: this.onEditorChange,
				scope: this,
				delay: 100
			}
		});
	},

	onEditorKeyUp: function(event, target) {
		switch (event.getKey()) {
		case event.ENTER:
			event.stopEvent();
			if (this.changeTask) {
				this.changeTask.cancel();
			}
			this.fireChange("enter", target);
			break;
		case event.ESC:
			if (this.clearOnEsc) {
				event.stopEvent();
				var ed = this.findEditor(target.id);
				ed.editor.setValue(null);
			}
		default:
			if (this.changeTask) {
				this.lastTarget = target;
				this.changeTask.delay(this.changeDelay);
			}
			break;
		}
	},

	onEditorChange: function(event, target) {
		if (this.changeTask) {
			this.changeTask.cancel();
		}
		this.fireChange("change", target);
	},

	findEditor: function(id) {
		var ed;
		
		for (var k in this.editors) {
			if (k == id) {
				ed = this.editors[k];
				break;
			}
		}
	
		return ed;
	},
	
	fireChange: function(event, target) {
		target = target || this.lastTarget;
		if (!target) {
			return;
		}
		
		var ed = this.findEditor(target.id);
		
		if (!ed) {
			return;
		}
		
		if (this.fireOnValid && ed.editor.isValid()) {
			if (this.fireOnEnter && event == "enter") {
				this.fireEvent("change", ed.editor, event);
				return;
			}
			
			if (this.fireOnDirty) {
				if (ed.value != ed.editor.getValue()) {
					ed.value = ed.editor.getValue();
					this.fireEvent("change", ed.editor, event);
				}
			}
			else {
				ed.value = ed.editor.getValue();
				this.fireEvent("change", ed.editor, event);
			}
		}
	}

});

