
function dump(o) {
	var html = [];
	for (var k in o) html.push(k + ' => ' + o[k]);
	return html.join('\n');
}

function debug(o) {
    alert(dump(o));
}

/*** Internal Classes ***/

// Handles asynchronous ajax calls.
var AjaxDataLoader = Class.create();
AjaxDataLoader.prototype = {
    className: null,
    loadMethod: null,
    onLoadSuccess: function(v) {},
    onLoadError: function(e) {},
    saveMethod: null,
    onSaveSuccess: function(v) {},
    onSaveError: function(e) {},    
    data: null,
    lastError: null,
    // methods
    initialize: function(args) {
        if (args != null) {
            Object.extend(this, args);
        }
    },
   	load: function(arg1, arg2, arg3) {
		if (this.loadMethod != null && this.className != null) {
		    var method = this.className + '.' + this.loadMethod;		    
		    var argInsert = (arg1 == null) ? '' : '\'' + escape(arg1) + '\', '; 
		    argInsert += (arg2 == null) ? '' : '\'' + escape(arg2) + '\', '; 
		    argInsert += (arg3 == null) ? '' : '\'' + escape(arg3) + '\', '; 
		    var js = method + '(' + argInsert + 'this.loadCallback.bind(this))';
			try { eval(js); } catch (e) {this._loadError(e); }
		}			
		else {
			this.onLoadError('AjaxAutoForm.loadMethod not defined');
		}
	},
	// Saves the contents of this form via ajax.net pro.
	save: function(arg) {
	    if (arg != null) {
	        this.data = arg;
	    }
		if (this.saveMethod != null && this.className != null) {
		    var method = this.className + '.' + this.saveMethod;   
			var js = method + '(this.data, this.saveCallback.bind(this))';
		    //var js = method + '(this.data)';
			try { eval(js); } catch (e) { this._saveError(e); }
		}						
		else {
			this.onSaveError('AjaxAutoForm.saveMethod not defined.');
		}
	},
	loadCallback: function(res) {
		if (res.error) {
		    this._loadError(res.error);
		}
		else {
		    this.data = res.value;
			this.onLoadSuccess(res.value);				
		}
	},
	saveCallback: function(res) {
		if (res.error) {
		    this._saveError(res.error);
		}
		else {
			this.onSaveSuccess(res.value);
		}
	},
	_loadError: function(e) {
		this.lastError = e;
        this.onLoadError(e);	
	},
	_saveError: function(e) {
	    this.lastError = e;
		this.onSaveError(e);	    
	}
};
AjaxDataLoader.createInstance = function(args) {
    return new AjaxDataLoader(args);
}

// Helper class for AjaxForm.
var AjaxFormBinderClass = Class.create();
AjaxFormBinderClass.prototype = {
	// Default constructor
	initialize: function() {
	},
    // Populates all of the tags contained within a tag based on 
    // their ajaxkey attributes.
	setForm: function(divID, data) {
		if (data != null && $(divID) != null) {		    
			var list = $(divID).getElementsByTagName("*");
			for (var i = 0; i < list.length; i++) {			    
			    var key = list[i].getAttribute('ajaxkey');			    
				if (key != null && data[key] != null) {
					this.setValue(list[i], data[key]);
				}
			}
		}
		return data;		
	},    
		
	// Builds an object from all of the fields contained in a form,
	// based on their ajaxkey attributes.		
	getForm: function(divID) {
		var data = new Array();
		if ($(divID) != null) {
		    var list = $(divID).getElementsByTagName("*");
		    for (var i = 0; i < list.length; i++) {		
			    var key = list[i].getAttribute('ajaxkey');			    
			    if (key != null) {
				    data[key] = this.getValue(list[i]);
			    }
		    }		    
		}
		return data;
	},
	// Copies data from a form to an object.
	copyForm: function(obj, divID) {
		if (obj != null) {
			var data = this.getForm(divID);
			for (var key in data) {
				obj[key] = data[key];
			}
		}
		return obj;
	},
	// Sets the value for many different html elements.
	setValue: function(el, value) {
	    var type = el.type == null ? 'undefined' : el.type.toLowerCase();	       
		switch (type) {
			case 'checkbox':
			    value = value.toLowerCase();
			    if(value == 'true' || value == '1' || value == 'yes'){
			        el.checked = true;}
			    else{
			        el.checked = false;}
			    break;
			case 'text':
			case 'select-one':
			case 'input':
				el.value = value;		
				break;
			case 'undefined':
			default:				
				el.innerHTML = value;
				break;
		}
	},
	// Gets the value from many different html elements.
	getValue: function(el) {
		switch (el.type + '') {
			case 'undefined':
				return el.innerHTML;
			case 'checkbox':
			    if(el.checked)
			    { return 'true'; } else { return 'false'; }
			case 'input':
			default:				
				return el.value == null ? $F(el) : el.value;		
		}
	}
}	
var AjaxFormBinder = new AjaxFormBinderClass();


