/*
 * jQuery .NET JSON Service Plugin
 */
 
(function($) { 

var _jsonsvc_table = { }
var _jsonsvc_global = function() { 
	this.add = function(name, url) {
		var cleanName = name.toLowerCase();
		_jsonsvc_table[cleanName] = url;
		
		return null;
	}
}
var _jsonsvc_specific = function(svcUrl) { 
	this._url = svcUrl;
	this._form = undefined;
	this._fatal = function() {};
	
	this.ajaxOptions = {
		type: "POST",
		contentType: "application/json; charset=utf-8",
		dataType: "json",
		success: null,
		error: null,
		beforeSend: null,
		complete: null
	}
	
	this.before = function(callback) {
		if(callback == null) {
			callback = function() {};
		}
		pack = function(fn, d) { return function() {
			var result = fn();
			if(result == false) {
				return false;
			}
			else {
				if(d._form !== undefined) {
					$(":input", d._form).attr("disabled", "disabled");
					$(d._form).addClass("working");
				}
			}
		} };
		this.ajaxOptions.beforeSend = pack(callback, this);
		return this;
	}
	
	this.ok = function(callback) {
		if(callback == null) {
			callback = function() {};
		}
		pack = function(fn) { return function(o) { fn(o.d); } };
		this.ajaxOptions.success = pack(callback);
		return this;
	}
	
	this.error = function(callback) {
		if(callback == null) {
			callback = function() {};
		}
		pack = function(fn, d) { return function(o) {
			try {
				fn( JSON.parse(o.responseText) );
			}
			catch(e) {
				d._fatal(o.responseText);
			}
		} };
		this.ajaxOptions.error = pack(callback, this);
		return this;
	}
	
	this.fatal = function(callback) {
		if(callback == null) {
			callback = function() {};
		}
		this._fatal = callback;
	}
	
	this.after = function(callback) {
		if(callback == null) {
			callback = function() {};
		}
		pack = function(fn, d) { return function() {
			if(d._form !== undefined) {
				$(":input", d._form).removeAttr("disabled");
				$(d._form).removeClass("working");
			}
			fn();
		} };
		
		this.ajaxOptions.complete = pack(callback, this);
		return this;
	}
	
	this.withForm = function(form, opt_data) {
		this._form = $(form);
		return this;
	}
	
	this.call = function(name, opt_data) {
		this.ajaxOptions.url = this._url + "/" + name + "?nocache=" + (new Date()).getTime();
		
		var data = opt_data || {};
		if(this._form !== undefined) {
			var active_form = this._form;
			$(":input", this._form).each(function() {
				var name = $(this).attr("name"),
					exclude = $(this).hasClass("json-exclude");
				if(name !== undefined && name != "" && !exclude) {
					var value = $(this).val();
					//Handle checkboxes
					if( $(this).is(":checkbox") ) {
						if( $(this).is(":checked") ) {
							//if(value == "on") { 
								value = true; 
							//}
						}
						else {
							//if( value == "on") {
								value = false;
							//}
							//else {
							//	return;
							//}
						}
					}
					if(data[name] === undefined) {
						var sel = ":input[name='" + name + "']";
						if( $(sel, active_form).length > 1 ) {
							value = new Array(value);
						}
						data[name] = value;
					}
					else if( $.isArray(data[name]) ){
						data[name].push(value);
					}
					else {
						data[name] = new Array(data[name], value);
					}
				}
			});
		}
		this.ajaxOptions.data = JSON.stringify(data);
		$.ajax(this.ajaxOptions);
		delete this.ajaxOptions.data;
	}
	
	var printout = function(a) {
		if(window.console !== undefined) { window.console.log(a); }
	}
	var debug = function(e) {
		if(confirm("Fatal Internal Server Error.\n\nSee Details?")) {
			alert(e);
		}; 
	}
	
	this.ok(printout);
	this.error(printout);
	this.before(function() {});
	this.after(function() {});
	this.fatal(debug);
}

$.extend({ JSONService : function(opt_name) {
	if(opt_name === undefined) {
		return new _jsonsvc_global();
	}
	else {
		var name = opt_name.toLowerCase();
		if(_jsonsvc_table[name] === undefined) {
			throw "Cannot locate service named '" + name + "'.";
		}
		var url = _jsonsvc_table[name];
		return new _jsonsvc_specific(url);
	}
} }); 

}(jQuery));

/* json2.js 
 * 2008-01-17
 * Public Domain
 * No warranty expressed or implied. Use at your own risk.
 * See http://www.JSON.org/js.html
*/
if(!this.JSON){JSON=function(){function f(n){return n<10?'0'+n:n;}
Date.prototype.toJSON=function(){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};function stringify(value,whitelist){var a,i,k,l,r=/["\\\x00-\x1f\x7f-\x9f]/g,v;switch(typeof value){case'string':return r.test(value)?'"'+value.replace(r,function(a){var c=m[a];if(c){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+
(c%16).toString(16);})+'"':'"'+value+'"';case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
if(typeof value.toJSON==='function'){return stringify(value.toJSON());}
a=[];if(typeof value.length==='number'&&!(value.propertyIsEnumerable('length'))){l=value.length;for(i=0;i<l;i+=1){a.push(stringify(value[i],whitelist)||'null');}
return'['+a.join(',')+']';}
if(whitelist){l=whitelist.length;for(i=0;i<l;i+=1){k=whitelist[i];if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}else{for(k in value){if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}
return'{'+a.join(',')+'}';}}
return{stringify:stringify,parse:function(text,filter){var j;function walk(k,v){var i,n;if(v&&typeof v==='object'){for(i in v){if(Object.prototype.hasOwnProperty.apply(v,[i])){n=walk(i,v[i]);if(n!==undefined){v[i]=n;}}}}
return filter(k,v);}
if(/^[\],:{}\s]*$/.test(text.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof filter==='function'?walk('',j):j;}
throw new SyntaxError('parseJSON');}};}();}
