function get_object(parent, path)
{
	var next_index = path.shift();
	if (path.length)
		return get_object(parent[next_index], path);
	else
		return parent[next_index];
}

(function ()
{
	var pre, max_depth, history = [], c_target, start_time;
	
	start_time = new Date;
	
	window['dbg_toggle'] = function (obj)
	{
		var _history = obj.getAttribute('history');
		obj.onclick = '';
		obj.style.cursor = '';
		__history = _history.split('|');
		max_depth = 0;
		history = _history.split('|');
		
		start_time = new Date;
		obj.innerHTML = dump(get_object(c_target, __history), 0);
	}
	
	var _c = function (value)
	{
		switch (typeof value)
		{
			case 'number':
				return '<span style="color: #FF6666">'+value+'</span>';
			case 'string':
				return '<span style="color: #99CCFF">"'+value+'"</span>';
			case 'boolean':
				return '<span style="color: #99FF99">'+value+'</span>';
		}
	}
	
	var dump = function (obj, depth)
	{
		try {
		var result = '', _history = history.join('|');
		
		var type = typeof obj;
		if (type=='object' && obj instanceof Array) type = 'array';
		
		switch (type)
		{
			case 'object':
			{
				result += '{<div class="d_space">'
				try 
				{
					for (i in obj)
					{
						try 
						{
							if (typeof(obj[i]) == 'object') 
							{
								history.push(i);
								var next_result = depth >= max_depth ? '<div class="d_float" style="cursor:pointer" history="'+history.join('|')+'" onclick="dbg_toggle(this)">{...}</div>' : '<div class="d_float">'+dump(obj[i], depth+1)+'</div>';
								result += '<div><div class="d_float">'+_c(i)+':&nbsp;</div>'+next_result+'</div>';
								history.pop();
							}
							else
							{
								result += '<div>'+_c(i)+':&nbsp;'+dump(obj[i], depth+1)+'</div>';
							}
						} catch (e){}
					}
				}catch(e){}
				result += '</div>}';
				
				break;
			}
			case 'number':
			case 'string':
			case 'boolean':
			{
				result += _c(obj);
				break;
			}
			case 'array':
			{
				result += '[<div class="d_space">';
				var flag = '';
				for (var i = 0; i < obj.length; i++)
				{
					result += flag;
					if (typeof obj[i] == 'object')
					{
						history.push(i);
						var next_result = depth >= max_depth ? '<div class="d_float" style="cursor:pointer" history="'+history.join('|')+'" onclick="dbg_toggle(this)">{...}</div>' : '<div class="d_float">'+dump(obj[i], depth+1)+'</div>';
						result += '<div>'+next_result+'</div>';
						flag = '';
						history.pop();
					}
					else
					{
						result += dump(obj[i], depth+1);
						flag = ', ';
					}
				}
				result += '</div>]';
				break;
			}
			case 'function':
			{
				result += '<span style="color: #BBBBBB">function () {}</span>';
				break;
			}
			/*
			default:
			{
				result += '<span style="color: #BBBBBB"> ? </span>';
				break;
			}
			*/
		}
		}catch(e){}
		return result;
	}
	var dumped=false;
	window.dump = function (obj, depth)
	{
		if(dumped) return;
		
		max_depth = typeof(depth) == 'undefined' ? 0 : depth;
		if (!pre)
		{
			pre = document.createElement('PRE');
			pre.style.backgroundColor = '#404040';
			pre.style.position = 'fixed';
			pre.style.top = '0px';
			pre.style.left = '0px';
			pre.style.height = '400px';
			pre.style.margin = '0px';
			pre.style.overflow = 'auto';
			pre.style.width = '100%';
			pre.style.fontSize = '11px';
			document.body.appendChild(pre);
		}
		
		c_target = obj;
		start_time = new Date;
		pre.style.display = 'block';
		pre.innerHTML = '<div style="color: #FFFF99">'+dump(obj, 0)+'</div>';
		dumped=true;
	}
	
	document.onkeydown = function (ev)
	{
		ev = ev ? ev : event;
		
		if ((ev.keyCode == 192 || ev.keyCode == 96 || ev.keyCode == 1025 ) && ev.shiftKey && pre)
		{
			pre.style.display = pre.style.display == 'none' ? 'block' : 'none';
		}
	}

})();