W.Editable = function(param)
{
	var obj	= this;
	
	W.Dom.load(function() { obj.init(param); });
};



W.Editable.prototype = {
	
	fields		: null,
	mode		: '',
	xhr			: '',		// xhr url
	page_load	: null,		// use a function instead of location.href
	process		: null,		// array of additional functions to call before posting data
	
	
	
	init : function(param)
	{
		this.fields		= param.json;
		this.mode		= param.mode;
		this.xhr		= param.xhr;
		this.redirect_obj		= param.redirect_obj;
		this.redirect_method	= param.redirect_method;
		
		this.process	= this.process || [];
		this.call=param.call
		this.init_buttons();
		this.init_editables();
		
		if (this.mode == 'add') { W.Dom.addClassName(document.getElementsByTagName('body')[0], 'add_form'); }
		
		W.Event.add(this);
	},
	
	
	
	init_buttons : function()
	{
		var obj		= this;
		var submit	= W.$('submit');
		
		if (submit) { W.Event.add(submit, 'click', function(e) { obj.submit(e); }); }
	},
	
	
	
	init_editables : function(field)
	{
		var obj			= this;
		var editables	= [];
		
		if (field && W.$(field)) {
			field	= W.$(field);
			if (field.className == 'editable') {
				editables.push(W.$(field));
			}
		} else { 
			editables = W.Dom.getElementsByClassName('editable'); 			// TODO: right now only works for select lists
		}
		
		for (var i = editables.length; --i >= 0; ) {
			W.Event.add(editables[i], 'change', function() { obj.manage(this); });
		}
	},
	
	
	
	submit : function(e)
	{
		W.Event.stop(e);
		
		switch (this.mode) {
			case 'add' :
				this.add();
				break;
			case 'edit' :
				this.edit();
				break;
		}
		
	},
	
	
	
	add : function()
	{
		var param, 
			input, 
			string = '', 
			errors = [], 
			
			fields	= this.fields;
		for (var field in fields) {
			param		= fields[field];
			if (param == null) continue;
			input		= document.getElementsByName(field) || W.$(field);
			if (input.length == 1) { input = input[0]; }
			if (input.type == 'checkbox' && !(input.checked)) {continue}
	
			if (input && input.length != 0) {
				if (field.indexOf('[]') != -1) {
					if (!input.length) {
						string += field + '=' + encodeURIComponent(input.value) + '&';
					} else {
						if (!input.type) {								// if type is defined then it's a single select list with nothing selected
							for (var i = input.length; --i >= 0; ) {
								string += field + '=' + encodeURIComponent(input[i].value) + '&';
							}
						}
					}
				} else {
					$(input).removeClass("error")
					param.value	= encodeURIComponent(input.value);
					string		+= input.name + '=' + param.value + '&';	// use name because ID has name="id", but id="[field]"
				}	
				if (param.required && !param.value) { errors.push(field); }
			}
		}
		
		for (var proc in this.process) {
			string += this.process[proc]();
		}
		if(this.call!=''){
                    string += '&' +this.call
                }
		if (errors.length) { 
			this.display_errors(errors); 
			alert(errors);
		} else {
			var obj		= this;
			var params	= string;
			new W.Request('POST', this.xhr, params).call(obj.xhr_result.bind(obj));
		}
	},
	
	
	
	edit : function()
	{
		W.Event.broadcast('onEdit', {src: this});
		
		W.Dom.addClassName(document.getElementsByTagName('body')[0], 'edit_form');
		
		var param,
			elem,
			input,
			fields	= this.fields;
		
		for (var field in fields) {
			param	= fields[field];
			elem	= W.$(field + '_f');
			if (elem) {
				param.value	= (W.Dom.text(elem)) || '';
					switch (param.type) {
						case 'text':
							input = W.Dom.make('input', param);
							elem.innerHTML = '';
							W.Dom.append(elem, input);
							break;
						case 'select-one':
							this.select(param);
							break;
						case 'datetime':
							this.datetime(elem, param);
							break;
						case 'date':
							input = W.Dom.make('input', param);
							input.className = "calendar";
							elem.innerHTML = '';
							W.Dom.append(elem, input);
							break;
						case 'function':
							this.fn(elem, param.ajax);
							break;
						case 'wysiwyg':
							delete param.type;
							input = W.Dom.make('textarea', param);
							input.value = param.value;
							elem.innerHTML = '';
							W.Dom.append(elem, input);
							break;
						case 'checkbox':
							checked = ($(elem).text() == "Yes")
							$(elem).html("<input type='checkbox' name="+param.name+" id="+param.name+" value='yes' />");
							if (checked) $("input", elem)[0].checked = true;
							break;
					}
				
			}
		}
		
		W.$('submit').innerHTML = 'save';
		this.mode = 'add';
	},
	
	
	
	remove : function(name, xhr)
	{
		new W.Popup().confirm('Are you sure you wish to delete ' + name + '?', xhr);
	},
	
	
	
	fn : function(elem, fn_name)
	{
		new W.Request('GET', this.xhr + '?ajax=' + fn_name + '&id=' + encodeURIComponent(W.$('id').value)).load(elem);
		
		W.Event.broadcast('onUpdate', {src: this, mode: this.mode, fn_name: fn_name, elem: elem});
	},
	
	
	
	datetime : function(elem, param)
	{
		new W.Request('GET', this.xhr + '?ajax=' + param.name + '&' + param.name + '=' + encodeURIComponent(param.value) + '&id=' + encodeURIComponent(W.$('id').value)).load(elem);
	},
	
	
	
	select : function(param)
	{
		var obj	= this;
		
		new W.Request('GET', this.xhr + '?ajax=' + param.name + '&' + param.name + '=' + encodeURIComponent(param.value)).call(obj.populate_select.bind(obj, param.name));
	},
	
	
	
	populate_select : function(req, field)
	{
		W.$(field + '_f').innerHTML = req.responseText;
		this.init_editables(field);
	},
	
	

	display_errors : function(errors)
	{
		for (var i = errors.length; --i >= 0; ) {
			W.Dom.addClassName(W.$(errors[i]), 'error');
		}
	},
	
	
	
	add_process : function(fn)
	{
		if (!this.process) {
			this.process	= [];
		}
		
		this.process.push(fn);
	},
	
	
	
	xhr_result : function(req)
	{
		var result = eval('(' + req.responseText + ')');
				
		if (result.redirect) {
			location.href = result.redirect;
			if (this.redirect_obj) { this.redirect_obj[this.redirect_method](result.redirect); }
		}
	},
	
	
	
	clone : function(elem)
	{
		if (elem.tagName.toUpperCase() == 'SELECT' && elem.value === '') { return; }
		
		var obj		= this;
		var clone	= elem.cloneNode(true);
		clone.selectedIndex	= 0;
		
		if (!clone.onchange) { clone.onchange = function() { obj.clone(this); }; }
		
		var parent	= elem.parentNode;
		parent.appendChild(document.createElement('br'));
		parent.appendChild(clone);
	},
	
	
	
	manage : function(elem)
	{
		var table = elem.id.substring(0, elem.id.indexOf('_'));
		if (elem.value === '0') { new W.Popup({width: 400, height: 300, xhr: 'xhr/ListManager.inc.php?table=' + table}); }
	},
	
	
	
	onBeforePageChange : function()
	{
		if (this.mode == 'add') {
			this.mode 	= '';
			var name	= W.$('name');
			if (name) { W.$('name_f').innerHTML = name.value; }
		}
	}
};

