/*
*Erstellt von Markus Emberger am 02.04.2010
*
*Erwartet Jsoncode, mit dem Rootelement 'JSON' (!!!case sensitive!!!)
*und gibt im Erfoglsfall ein Objekt/Array zurück
*oder false im Falle eines Fehlers
*/

var decodeJson = function(nzData) {

	try {
		//Prüfe of data richtig definiert wurde, und ob das Rootelement json ist!
		if(typeof nzData == "string") {
			var nIndex = nzData.search(/JSON/);
			if(nIndex != -1 && nIndex > 1 && nIndex < 8) {
			//JSON Code-Segment wird erwartet, beginne mit parsen
				return jsonParse(nzData);
			}//end if start with json
		}//end if string
	} catch(Error)
		{
		  //No need for errorhandling, just return false than...
		}
return false;
}//end of decodeJson

	/**
	* Parses a string of well-formed JSON text.
	*
	* If the input is not well-formed, then behavior is undefined, but it is
	* deterministic and is guaranteed not to modify any object other than its
	* return value.
	*
	* @param {string} json per RFC 4627
	* @param {function (this:Object, string, *):*} opt_reviver optional function
	*     that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1.
	*     If supplied, the function is called with a string key, and a value.
	*     The value is the property of 'this'.  The reviver should return
	*     the value to use in its place.  So if dates were serialized as
	*     {@code { "type": "Date", "time": 1234 }}, then a reviver might look like
	*     {@code
	*     function (key, value) {
	*       if (value && typeof value === 'object' && 'Date' === value.type) {
	*         return new Date(value.time);
	*       } else {
	*         return value;
	*       }
	*     }}.
	*     If the reviver returns {@code undefined} then the property named by key
	*     will be deleted from its container.
	*     {@code this} is bound to the object containing the specified property.
	* @return {Object|Array}
	*/
	var jsonParse = (function () {
	var number
	   = '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)';
	var oneChar = '(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]'
	   + '|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))';
	var string = '(?:\"' + oneChar + '*\")';
	
	// Will match a value in a well-formed JSON file.
	// If the input is not well-formed, may match strangely, but not in an unsafe
	// way.
	// Since this only matches value tokens, it does not match whitespace, colons,
	// or commas.
	var jsonToken = new RegExp(
	   '(?:false|true|null|[\\{\\}\\[\\]]'
	   + '|' + number
	   + '|' + string
	   + ')', 'g');
	
	// Matches escape sequences in a string literal
	var escapeSequence = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g');
	
	// Decodes escape sequences in object literals
	var escapes = {
	 '"': '"',
	 '/': '/',
	 '\\': '\\',
	 'b': '\b',
	 'f': '\f',
	 'n': '\n',
	 'r': '\r',
	 't': '\t'
	};
	function unescapeOne(_, ch, hex) {
	 return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16));
	}
	
	// A non-falsy value that coerces to the empty string when used as a key.
	var EMPTY_STRING = new String('');
	var SLASH = '\\';
	
	// Constructor to use based on an open token.
	var firstTokenCtors = { '{': Object, '[': Array };
	
	var hop = Object.hasOwnProperty;
	
	return function (json, opt_reviver) {
	 // Split into tokens
	 var toks = json.match(jsonToken);
	 // Construct the object to return
	 var result;
	 var tok = toks[0];
	 var topLevelPrimitive = false;
	 if ('{' === tok) {
	   result = {};
	 } else if ('[' === tok) {
	   result = [];
	 } else {
	   // The RFC only allows arrays or objects at the top level, but the JSON.parse
	   // defined by the EcmaScript 5 draft does allow strings, booleans, numbers, and null
	   // at the top level.
	   result = [];
	   topLevelPrimitive = true;
	 }
	
	 // If undefined, the key in an object key/value record to use for the next
	 // value parsed.
	 var key;
	 // Loop over remaining tokens maintaining a stack of uncompleted objects and
	 // arrays.
	 var stack = [result];
	 for (var i = 1 - topLevelPrimitive, n = toks.length; i < n; ++i) {
	   tok = toks[i];
	
	   var cont;
	   switch (tok.charCodeAt(0)) {
	     default:  // sign or digit
	       cont = stack[0];
	       cont[key || cont.length] = +(tok);
	       key = void 0;
	       break;
	     case 0x22:  // '"'
	       tok = tok.substring(1, tok.length - 1);
	       if (tok.indexOf(SLASH) !== -1) {
	         tok = tok.replace(escapeSequence, unescapeOne);
	       }
	       cont = stack[0];
	       if (!key) {
	         if (cont instanceof Array) {
	           key = cont.length;
	         } else {
	           key = tok || EMPTY_STRING;  // Use as key for next value seen.
	           break;
	         }
	       }
	       cont[key] = tok;
	       key = void 0;
	       break;
	     case 0x5b:  // '['
	       cont = stack[0];
	       stack.unshift(cont[key || cont.length] = []);
	       key = void 0;
	       break;
	     case 0x5d:  // ']'
	       stack.shift();
	       break;
	     case 0x66:  // 'f'
	       cont = stack[0];
	       cont[key || cont.length] = false;
	       key = void 0;
	       break;
	     case 0x6e:  // 'n'
	       cont = stack[0];
	       cont[key || cont.length] = null;
	       key = void 0;
	       break;
	     case 0x74:  // 't'
	       cont = stack[0];
	       cont[key || cont.length] = true;
	       key = void 0;
	       break;
	     case 0x7b:  // '{'
	       cont = stack[0];
	       stack.unshift(cont[key || cont.length] = {});
	       key = void 0;
	       break;
	     case 0x7d:  // '}'
	       stack.shift();
	       break;
	   }
	 }
	 // Fail if we've got an uncompleted object.
	 if (topLevelPrimitive) {
	   if (stack.length !== 1) { throw new Error(); }
	   result = result[0];
	 } else {
	   if (stack.length) { throw new Error(); }
	 }
	
	 if (opt_reviver) {
	   // Based on walk as implemented in http://www.json.org/json2.js
	   var walk = function (holder, key) {
	     var value = holder[key];
	     if (value && typeof value === 'object') {
	       var toDelete = null;
	       for (var k in value) {
	         if (hop.call(value, k) && value !== holder) {
	           // Recurse to properties first.  This has the effect of causing
	           // the reviver to be called on the object graph depth-first.
	
	           // Since 'this' is bound to the holder of the property, the
	           // reviver can access sibling properties of k including ones
	           // that have not yet been revived.
	
	           // The value returned by the reviver is used in place of the
	           // current value of property k.
	           // If it returns undefined then the property is deleted.
	           var v = walk(value, k);
	           if (v !== void 0) {
	             value[k] = v;
	           } else {
	             // Deleting properties inside the loop has vaguely defined
	             // semantics in ES3 and ES3.1.
	             if (!toDelete) { toDelete = []; }
	             toDelete.push(k);
	           }
	         }
	       }
	       if (toDelete) {
	         for (var i = toDelete.length; --i >= 0;) {
	           delete value[toDelete[i]];
	         }
	       }
	     }
	     return opt_reviver.call(holder, key, value);
	   };
	   result = walk({ '': result }, '');
	 }
	
	 return result;
	};
	})();
