/**
 * 11/03/06 Loren Pipes, Selliken Systems LLC
 *
 * This is a re-write of json.js from http://json.org, placing all encode
 * functions into an object as opposed to adding them to the prototype of those
 * objects
 */



Json = {};

Json.encode = function(data) {
	switch(typeof(data)) {
		case 'string': return this.stringToJson(data);
		case 'boolean': return this.booleanToJson(data);
		case 'number': return this.numberToJson(data);
		case 'object': 
			if(data instanceof Array) { return this.arrayToJson(data); }
			else { return (data === null ? 'null' : this.objectToJson(data)); }
	}
	return '';
};

/*
Json.stringToJson = function(data) {
	return '"' + data + '"';
};
*/

Json.booleanToJson = function(data) {
	return String(data);
};

Json.numberToJson = function(data) {
	return (isFinite(data) ? String(data) : 'null');
};

Json.arrayToJson = function(data) {
	var a = ['['], init = true, item;
	for(var i=0, len=data.length; i<len; i++) {
		item = data[i];
		switch(typeof(item)) {
			case 'undefined':
			case 'function':
			case 'unknown':
				break;
			default:
				if(!init) {
					a.push(',');
				}
				a.push(this.encode(item));
				init = false;
		}
	}
	a.push(']');
	return a.join('');
};

Json.objectToJson = function(data) {
	var a = ['{'], init = true, item;
	for(var prop in data) {
		if(data.hasOwnProperty(prop)) {
			item = data[prop];
			switch(typeof(item)) {
				case 'undefined':
				case 'function':
				case 'unknown':
					break;
				default:
					if(!init) {
						a.push(',');
					}
					a.push(this.encode(prop) + ':' + this.encode(item));
					init = false;
			}
		}
	}
	a.push('}');
	return a.join('');
};

(function () {
	var m = {
		'\b': '\\b',
		'\t': '\\t',
		'\n': '\\n',
		'\f': '\\f',
		'\r': '\\r',
		'"' : '\\"',
		'\\': '\\\\'
	};
	
	Json.stringToJson = function (data) {
		if (/["\\\x00-\x1f]/.test(data)) {
			return '"' + data.replace(
				/([\x00-\x1f\\"])/g,
				function(a, b) {
					var c = m[b];
					if (c) {
						return c;
					}
					c = b.charCodeAt();
					return '\\u00' +
						Math.floor(c / 16).toString(16) +
						(c % 16).toString(16);
				}) + '"';
		}
		return '"' + data + '"';
	};
})();
