/*
* DEBUGGER AVANZADO DE JAVASCRIPT
* --------------------------------------------------------------------------------------------------------------------
*
* Rubén Moraleda Ruano
* http://blog.xplorastudios.com
*
* Esta obra está bajo una licencia Reconocimiento-Compartir bajo la misma licencia 3.0 España de Creative Commons. 
* Para ver una copia de esta licencia, visite http://creativecommons.org/licenses/by-sa/3.0/es/ o envie una carta a 
* Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
*
*/

var jsdebugWatchers=new Array();
var jsdebugLogs=new Array();
var jsdebugLogLimit=10; // Numero máximo de entradas en el log
var jsdebugEnabled=true;
var jsdebugRefreshTime=1000;
var jsdebugVisible=false;

// Estilos
var jsdebugStyles='\
	<style type="text/css">\
		#jsdebug {z-index:9000;position:fixed;right:0;bottom:0;background-color:#ddd;color:#000;border:1px solid #000;padding:0px;font-size:8pt;line-height:12pt;}\
		#jsdebug a {color:#f00 !important;}\
		#jsdebug h4 {margin:0;padding:5px;font-size:10pt !important;font-weight:bold !important;}\
		#jsdebug.open {}\
		#jsdebug.open h4 {background-color:#000;color:#fff}\
		#jsdebug .jstoggle {}\
		#jsdebug .jsempty {}\
		#jsdebug .jswindow {padding:5px;}\
		#jsdebug .jsexprwin {}\
		#jsdebug .jslogwin {margin:5px 0 0 0;padding:5px 0 0 0;border-top:2px solid #000;}\
		#jsdebug h5 {font-size:8pt !important;font-weight:bold !important;padding:0 0 5px 0;margin:0 0 5px 0;border-bottom:1px dotted #000;}\
		#jsdebug .jsexpr {color:#060;}\
		#jsdebug .jsvalue {color:#00f;}\
		#jsdebug .jslog {color:#060;}\
		#jsdebug .jsdate {color:#555;}\
		#jsdebug .jscontent {margin:0 15px}\
		#jsdebug .jsadd {padding:5px 0 0 0;margin:5px 0 0 0;border-top:1px dotted #000;}\
		#jsdebug .jsaddresults {margin:5px 0 0 0;padding:4px;background-color:#eee;overflow:auto;}\
		#jsdebug .jsaddresult {color:#555;text-decoration:underline;}\
		#jsdebug .jsaddresult .jsaddresultcc {color:#800;font-weight:bold;}\
		#jsdebug .jserror {color:#f00;}\
	</style>\
';

function jsdebugWatch(expression) {
	jsdebugWatchers.push(expression);
}
function jsdebugDelWatch(i) {
	jsdebugWatchers.splice(i,1);
}
function jsdebugEmptyWatch() {
	jsdebugWatchers=[];
}
function jsdebugAddCustomWatch(event) {
	if ((window.event) ? event.which : event.keyCode==13) {
		// Añadimos si la tecla pulsada es enter
			jsdebugWatch($("#jsdebug input[@name=add]").attr("value"));
			$("#jsdebug input[@name=add]").attr("value","");
			$("#jsdebug input[@name=add]").blur();
	} else {
		jsdebugAddCustomWatchMuestraCoincidencias();
	}
}
function jsdebugAddCustomWatchReset() {
	$("#jsdebug input[@name=add]").attr("value","");
	jsdebugAddCustomWatchLimpiaCoincidencias()
}
function jsdebugAddCustomWatchMuestraCoincidencias() {
	// Sugerimos variables y objetos en base a la busqueda
	search=$("#jsdebug input[@name=add]").attr("value");
	suggested=new Array();
	if (search!="") {
		// Generamos array con coincidencias
			for (var s in this) {
				if (s.toLowerCase().indexOf(search.toLowerCase())>=0) suggested.push(s);
			}
		// Mostramos coincidencias
			if (suggested.length>0) {
				output="";
				suggested.sort()
				for (var i in suggested) {
					output+="<a href='' onclick='jsdebugWatch(\""+suggested[i]+"\");jsdebugAddCustomWatchReset();return false;' class='jsaddresult'>"+suggested[i].split(new RegExp(search,"i")).join("<span class='jsaddresultcc'>"+search+"</span>")+"</a> <small>("+typeof eval(suggested[i])+")</small><br/>";
				}
				$("#jsdebug .jsaddresults").html(output);
				// Si la altura es menor de 150px la usamos, de lo contrario, la ajustamos a 150 (ojo, .jsaddresults debe tener overflow:auto)
					$("#jsdebug .jsaddresults").css({height: "auto"}); // Reiniciamos altura
					altura=($("#jsdebug .jsaddresults").height()<150) ? $("#jsdebug .jsaddresults").height() : 150;
					$("#jsdebug .jsaddresults").css({
						height: altura
					});
				$("#jsdebug .jsaddresults").html(output).show();
			} else {
				jsdebugAddCustomWatchLimpiaCoincidencias();
			}
	} else {
		jsdebugAddCustomWatchLimpiaCoincidencias();
	}
}
function jsdebugAddCustomWatchLimpiaCoincidencias() {
	$("#jsdebug .jsaddresults").html("").hide();
}
function jsdebugLog(log) {
	// Añadimos la fecha
		var ahora = new Date();
		log="<span class='jsdate'>"+ahora.getHours()+":"+ahora.getMinutes()+":"+ahora.getSeconds()+" </span>"+log;
	// Si excede el numero de entradas del log eliminamos la mas antigua
		if (jsdebugLogs.length>=jsdebugLogLimit) jsdebugLogs.shift();
	jsdebugLogs.push(log);
}
function jsdebugDelLog(i) {
	jsdebugLogs.splice(i,1);
}
function jsdebugEmptyLog() {
	jsdebugLogs=[];
}
function jsdebugRefresh() {
	if (!jsdebugEnabled) return false;
	jsdebugRefreshWatchers();
	jsdebugRefreshLogs();
	setTimeout("jsdebugRefresh()",jsdebugRefreshTime);
}
function jsdebugRefreshWatchers() {
	output="";
	for(i=0;i<jsdebugWatchers.length;i++) {
		try {
			value=eval(jsdebugWatchers[i]);
		} catch(err) {
			value="<span class='jserror'>Error</span> ("+err.description+")";
		}
		output+="[<a href='' onclick='jsdebugDelWatch("+i+");return false;'>X</a>] <span class='jsexpr'>"+ jsdebugWatchers[i]+"</span> = <span class='jsvalue'>"+value+"</span><br/>";
	}
	if (jsdebugWatchers.length<1) {
		output+="Sin expresiones a evaluar";
	}
	$("#jsdebug .jsexprwin .jscontent").html(output);
}
function jsdebugRefreshLogs() {
	output="";
	for(i=(jsdebugLogs.length-1);i>=0;i--) {
		output+="[<a href='' onclick='jsdebugDelLog("+i+");return false;'>X</a>] <span class='jslog'>"+ jsdebugLogs[i]+"</span><br/>";
	}
	if (jsdebugLogs.length<1) {
		output+="Log vacio";
	}
	$("#jsdebug .jslogwin .jscontent").html(output);
}
function jsdebugInit() {
	if (!jsdebugEnabled) return false;
	// Añadimos el código para el debugging
		$("body").append("<div id='jsdebug'>\
			<h4>Debugger Javascript <small>[<a href='' onclick='jsdebugToggle();return false;' class='jstoggle'></a>]</small></h4>\
			<div class='jswindow'>\
				<div class='jsexprwin'>\
					<h5>Evaluador de expresiones <small>[<a href='' onclick='jsdebugEmptyWatch();return false;' class='jsempty'>Vaciar</a>]</small></h5>\
					<div class='jscontent'></div>\
					<div class='jsadd'>Expresión: <input type='text' name='add' size='30' onkeyup='jsdebugAddCustomWatch(event)'/><div class='jsaddresults' style='display:none'></div></div>\
				</div>\
				<div class='jslogwin'>\
					<h5>Log <small>(Últimas "+jsdebugLogLimit+" entradas) [<a href='' onclick='jsdebugEmptyLog();return false;' class='jsempty'>Vaciar</a>]</small></h5>\
					<div class='jscontent'></div>\
				</div>\
			</div>\
		</div>");
	// Añadimos los estilos
		$("head").append(jsdebugStyles);
	// Lo ocultamos o mostramos en función del valor que tenga por defecto
		jsdebugVisible ? jsdebugShow():jsdebugHide();
	// Iniciamos el auto-refrescado de variables
		setTimeout("jsdebugRefresh()",jsdebugRefreshTime);
}
function jsdebugClose() {
	$("#jsdebug").remove();
	jsdebugWatchers=false;
	jsdebugEnabled=false;
}
function jsdebugToggle() {
	jsdebugVisible ? jsdebugHide() : jsdebugShow();
}
function jsdebugShow() {
	$("#jsdebug .jswindow").show();
	$("#jsdebug .jstoggle").html("Cerrar");
	$("#jsdebug").addClass("open");
	jsdebugVisible=true;
}
function jsdebugHide() {
	$("#jsdebug .jswindow").hide();
	$("#jsdebug .jstoggle").html("Abrir");
	$("#jsdebug").removeClass("open");
	jsdebugVisible=false;
}
$(document).ready(function () {
	jsdebugInit();
});