/**
 * JSON
 * 
 * Permite a conversao de Objetos para strings JSON,
 * assim como exibir o conteudo de um Objeto, funcao parecida com
 * "print_r" do PHP
 * 
 * @author Moisés Paes Sena <moisespsena@gmail.com>
 * @site http://www.moisespsena.com
 * @blog http://moisespsena.wordpress.com.br
 * @date 2009-01-19
 * @version 1.0
 * 
 * Metodos:
 * 		
 * 		Encode :
 * 			Coverte um objeto para uma string JSON.
 * 
 * 		Print :
 * 			Retorna uma String JSON de forma concatenada e de
 * 			facil visualizacao dos seus metodos e atributos.
 * 		
 * 		Decode :
 * 			Retorna um objeto a partir de uma string JSON valida.
 * 
 * Exemplos:
 * 
 * 		// SAIDA: '{"nome":"Mois\u00e9s","sobrenome":"Sena"}'
 * 		JSON.encode({ nome : "Moisés", sobrenome : 'Sena' });
 * 		
 * 		var obj = JSON.decode('{"nome":"Mois\u00e9s","sobrenome":"Sena"}');
 * 		
 * 		\/* SAIDA: {\n\tnome : "Moise's",\n\tsobrenome : "Sena",\n\tcontato : [\n\t\t"moisespsena@gmail.com",\n\t\t"www.cienti.com.br"\n\t]\n}'
 * 		 RENDERIZACAO:
 * 
 * 			{ 
 * 				nome : "Moisés",
 * 				sobrenome : "Sena",
 * 				contato : [ 
 * 					"moisespsena@gmail.com", 
 * 					"www.cienti.com.br" 
 * 				] 
 * 			}
 *		*\/ 
 * 		JSON.print({ nome : "Moisés", sobrenome : 'Sena', contato : [ 'moisespsena@gmail.com', 'www.cienti.com.br' ] });
 * 
 * 		
 */
;(function(){
	var JSON = window.JSON = function(){};
	JSON.id = 'ab231f0842d99acdcb7ea7a18596041f278b72da';
	JSON.info = 'Author : Moise\'s Paes Sena, contact : moisespsena@gmail.com, blog : moisespsena@wordpress.com.br.';
	
	JSON.util = function(){};
	JSON.util.charToUnicode = function(char) {
		if( /[\w\s\!\@\#\$\%\&\*\(\)\+\=\-\{\}\[\]\|\\\:\;\<\>\,\.\/\\\"\']/.test(char) )
			return char;
		else {
			var hexa = char.charCodeAt(0).toString(16);
			var prefix;
			
			if( hexa.length == 1 )
		        prefix = "\\u000";
		    else if( hexa.length == 2 )
		        prefix = "\\u00";
		    else if( hexa.length == 3 )
		        prefix = "\\u0";
		    else
		        prefix = "\\u";
		    
			return prefix + hexa;
		}
	};
	
	JSON.util.strToUnicode = function(num) {
		 var str = '';
		  for (i=0;i<num.length;i++)
		    str += JSON.util.charToUnicode(num.charAt(i));
		  
		  return str; 
	};
	
	JSON.util.escap = function(string){
		return string && string.constructor == String 
			? string.replace(/(['"\\])/gi,'\\$1') 
			: string;
	};
	
	JSON.util.count = function( obj ){
		var i = 0;
		for( var k in obj ) i++;
		return i;
	};
	
	JSON.util.isNumeric = function( num ) {
		var y = parseInt( num * 1 );
		if ( isNaN( y ) ) return false;
		return num == y && num.toString() == y.toString(); 
	};
	
	JSON.util.isNumericArray = function( obj ) {
		var i = 0;
		for( var k in obj ) {
			if( k != i++ ) return false;
		}
		return true;
	};
	
	JSON.util.jsonFormat = {
		object : {
			start : '{',
			end : '}'
		},
		array : {
			start : '[',
			end : ']'
		},
		key : ':',
		toUnicode : true
	};
	
	JSON.util.phpArrayFormat = {
		object : {
			start : 'array(',
			end : ')'
		},
		array : {
			start : 'array(',
			end : ')'
		},
		key : '=>',
		toUnicode : false
	};
	
	JSON.compile = function( object, quebra, format ){
		var m=0;
		function json( c, m, quebra ){
			var val = [], 
				value,
	        		qnt = JSON.util.count( c ), 
	        		i = 0, 
	        		m = m ? m : 0, 
	        		_m = m ? m + 1 : 1, 
	        		t = '', 
	        		_t = '', 
	        		r = '', 
	        		b = [ format.object.start, format.object.end ], 
	        		n = '', 
	        		s = '', 
	        		a = ['"','"'], 
	        		si = true;
	        
	        	if( JSON.util.isNumericArray( c ) && !quebra ){
	        		b = [ format.array.start, format.array.end ];
	        		si = false;
	        	}
	        	
	        	if( quebra ){
	        		for( var j = 0; j < _m; j++ ) _t += '\t';
	        		for( var j = 0; j < m; j++ ) t += '\t';
	        		n = '\n';
	        		s = ' ';
	        		a[ 0 ] = '';
	        	}
	        	
	        	for( var y in c ){
	        		r += n+_t;
	        		if( typeof c[ y ] == 'object' 
	        		    && c[ y ] ) 
	        		{
	        		    r += ( si 
	        			? a[ 0 ] + (new String(y)) + a[ 0 ] + s + format.key 
	        			: '' ) 
	        			+ s + json( c[ y ], _m ) 
	        			+ ( i == qnt-1 
	        			    ? '' 
	        			    : ',' 
	        			);
	        		}
	        		else {
	        			if( c[ y ] == null ) value = 'null';
	        			else {
	        				switch( typeof c[ y ] ){
	        					case 'number': value = c[ y ]; break;
	        					case 'boolean': value = c[ y ]; break;
	        					case null: value = 'null'; break;
	        					case 'string': value = a[ 1 ] + 
	        						(
	        							format.toUnicode 
	        							? JSON.util.strToUnicode( JSON.util.escap( c[ y ] ) )
	        							: JSON.util.escap( c[ y ] )
	        						) + a[ 1 ]; 
	        						value = value.replace(/\n/, '\\n');
	        					break;
	        					default: value = a[ 1 ] + (
	        							format.toUnicode 
	        							? JSON.util.strToUnicode( JSON.util.escap( c[ y ] ) )
	        							: JSON.util.escap( c[ y ] )
	        						) + a[ 1 ]; break;
	        				}
	        			}
	        			r += ( si ? a[ 0 ] + y + a[ 0 ] + s + format.key : '' ) + s + value + ( i == qnt-1 ? '' : ',' );
	        		}
	        		
	        		i++;
	        	}
	        	return b[0] + r + n + t + b[1];
	        };
		
		return typeof object == 'object' && object != null ? json( object, m, quebra ): object;
	};
	
	JSON.encode = function( object ) {
		return JSON.compile( object, false, JSON.util.jsonFormat );
	};
	
	JSON.phpArrayEncode = function( object ) {
		return JSON.compile( object, false, JSON.util.phpArrayFormat );
	};
	
	JSON.decode = function( string_json ) {
		if( typeof string_json != 'string' || !(/^[\{\[].*[\}\]]$/gi).test( string_json.replace( /^\s+|\s+$/gi,'' ) ) ) return null;
		eval( 'return ' + string_json + ';');
	};
	
	JSON.print = function( object, format ) {
		return JSON.compile( object, true, format ? format : JSON.util.jsonFormat );
	};
})();