function dump (obj, dep)
{
	var r   = '';
	var dep = (typeof(dep) == 'number') ? ++dep : 0;
	var ind = '';
 
	for (var i = 0; i < dep; i++) { ind += '\t'; }
	for (var i in obj) {
		var is_obj = (typeof(obj[i]) == 'object');
 
		r += ind + '[' + i + '] : ';
		r += !is_obj ? obj[i] : '';
		r += '\n';
		r += is_obj ? arguments.callee(obj[i], dep) : '';
	}
 
	return r;
}

String.prototype.getFuncBody = function()
{ 
	var str=this.toString(); 
	str=str.replace(/[^{]+{/,"");
	str=str.substring(0,str.length-1);   
	str = str.replace(/\n/gi,"");
	//if(!str.match(/\(.*\)/gi))str += ")";
	return str; 
}

jQuery.fn.extend({
	setDisabled: function(_disabled){
		return this.each(function(i){
			this.disabled = _disabled;
			
			if (!_disabled) 
				$(this).removeAttr("disabled");
			
			//link with onclick
			if (this.onclick && _disabled) {
				//alert(this.onclick.toString().getFuncBody());
				this.onclick = new Function("return false;" + this.onclick.toString().getFuncBody());
			}
			//link without onclick
			else 
				if (_disabled) {
					this.onclick = function(){
						return false;
					}
				//alert(this.onclick.toString().getFuncBody());
				}
				//remove return false with link without onclick
				else 
					if (!_disabled && this.onclick.toString().indexOf("function(){return false;}") != -1) {
						//alert("Este no tenía onclick");
						this.onclick = null;
					}
					//remove return false link with onclick
					else 
						if (!_disabled && this.onclick.toString().indexOf("return false;") != -1) {
							//alert(this.onclick.toString().getFuncBody());
							strClick = this.onclick.toString().getFuncBody().replace("return false;", "");
							this.onclick = new Function(strClick);
						}
		});
	}
});

function update_badge(_badge_tag, _new_value)
{
	SPEED = 500;
	
	if (_new_value == undefined || _new_value == 0 || _new_value == "")
	{
		$("[tag=" + _badge_tag + "]").fadeOut(SPEED, function(i){
			$(this).html("0");
		});
	}
	else
	{	
		if ($("[tag=" + _badge_tag + "]").html() != _new_value)
		{
			if ($("[tag=" + _badge_tag + "]").html() == 0)
			{
				$("[tag=" + _badge_tag + "]").fadeIn().html(_new_value).animate({
						opacity: 1
					}, SPEED);
			}
			else {
				$("[tag=" + _badge_tag + "]").show().animate({
					opacity:0
				}, SPEED, "linear", function(i){
					$(this).html(_new_value).animate({
						opacity: 1
					}, SPEED);
				});
			}
		}
	}
}


function animatePoof(_element) 
{
	var bgTop = 0; // initial background-position for the poof sprit is '0 0'
	var frames = 5; // number of frames in the sprite animation
	var frameSize = 32; // size of poof <div> in pixels (32 x 32 px in this example)
	var frameRate = 80; // set length of time each frame in the animation will display (in milliseconds)
	var xOffset = 24;
	var yOffset = 24;
	
	var offset = $(_element).offset();

	$(_element).after('<div id="' + $(_element).attr('id') + '_poof" class="poof"></div>').css({
			left: offset.left - xOffset + 'px',
			top: offset.top - yOffset + 'px'
	}).show();

	//alert($(_element).attr('id'));

	// loop through amination frames
	// and display each frame by resetting the background-position of the poof <div>
	for(var i=1;i<frames;i++) {
		$('#' + $(_element).attr('id') + '_poof').animate({
			backgroundPosition: '0 ' + (bgTop - frameSize) + 'px'
		}, frameRate);
		bgTop -= frameSize; // update bgPosition to reflect the new background-position of our poof <div>
	}
	
	// wait until the animation completes and then hide the poof <div>
	setTimeout("$('#" + $(_element).attr('id') + "_poof').remove()", frames * frameRate);
}


function OKN_Server(_is_sdk_server, _url, _format, _language)
{	
	if (_is_sdk_server == undefined)
		_is_sdk_server = true;
		
	if (_url == undefined) {
		if (_is_sdk_server)
			_url = "sdk/1.0/server.php";
		else
			_url = "index.php";
	}
		
	if (_format == undefined)
		_format = "json";
	
	if (_language == undefined)
		_language = "es";
	
	this.OKN_SDK_SERVER = _is_sdk_server == true;
	this.OKN_SERVER_URL = _url;
	this.OKN_SERVER_FORMAT = _format;
	this.OKN_SERVER_LANGUAGE = _language;

	this.tinySpinner = '<img src="themes/okn/images/spinner.gif" border="0" width="12" height="12" align="absmiddle" />';
	this.tinyCenteredSpinner = '<div style="margin-top:-6px;top:50%;width:12px;height:12px;position:relative;left:50%; margin-left:-6px;"><br/><br/><p>' + this.tinySpinner + '</p></div>';
	this.spinner = '<img src="themes/okn/images/spinner.gif" border="0" width="22" height="22" align="absmiddle" />';
	this.centeredSpinner = '<div style="margin-top:-11px;top:50%;width:22px;height:22px;position:relative;left:50%; margin-left:-11px;"><br/><br/><p>' + this.spinner + '</p></div>';

	
/*	Available options
 * -------------------
 *	request_language
 *	request_format
 *	autohandle_errors
 *	autoeval_script_result
 *	locking_object
 *	removing_object
 *	show_spinner_in
 *	spinner_type
 *	sending_form
 *	replacing_content_with_result
 *	replacing_content_with_url - TODO
 *	replacing_object_with_result
 *	replacing_object_with_url - TODO
 *	navigating_back
 *	reloading_page
 *	redirecting_to_url
 */
	
	
	// POST request
	this.call = function (_function_name, _options, _callback_function)
	{	
		var old_spinner_content = {};
		
		// Prevent empty options
		if (_options == undefined)
			var _options = new Object();

		// Bloquear uno o varios objetos (en función del selector)
		if (_options.locking_object) {
			$(_options.locking_object).setDisabled(true);
		}
				
		// Spinner Type
		if (_options.spinner_type == undefined)
			_options.spinner_type = this.spinner;
		
		// Mostrar Spinner
		if (_options.show_spinner_in) {
			$(_options.show_spinner_in).each(function(i) {
				old_spinner_content[i] = $(this).html();
				$(this).html(_options.spinner_type);
			});
		}
		
		// Asegurarnos que se pasa un enetro y, en caso contrario, poner un valor por defecto
		if (_options.navigating_back && isNaN(_options.navigating_back)) {
			_options.navigating_back = 1;
		}
		
		if (_options.autohandle_errors == undefined)
			_options.autohandle_errors = true;
			
		var request_language = this.OKN_SERVER_LANGUAGE;
		if (_options.request_language)
			request_language = _options.request_language;
			
		var request_format = this.OKN_SERVER_FORMAT;
		if (_options.request_format)
			request_format = _options.request_format;
		
		if (request_format == "html" || request_format == "text" || request_format == "script")
			_options.autohandle_errors = false;
		
		if (!this.OKN_SDK_SERVER)
			_options.autohandle_errors = false;
			
		if (request_format != "script")
			_options.autoeval_script_result = false;
		else
			if (_options.autoeval_script_result == undefined)
				_options.autoeval_script_result = false;

		// Standard parameters
		var post_params = new Object();
		
		if (this.OKN_SDK_SERVER)
		{
			post_params.okn_function = _function_name;
			post_params.okn_format = request_format;
			post_params.okn_language = request_language;
		}
		
		var request_url = this.OKN_SERVER_URL;
		
		// User GET parameters
		if (_options.get_params != undefined && _options.get_params)
		{
			if (this.OKN_SERVER_URL.indexOf("?") >= 0) 
			{
				request_url = this.OKN_SERVER_URL + "&" + jQuery.param(_options.get_params);
			}
			else
			{
				request_url = this.OKN_SERVER_URL + "?" + jQuery.param(_options.get_params);
			} 
		}
			
		// User POST parameters
		if (_options.post_params != undefined && _options.post_params)
		{
			for (key in _options.post_params) 
				post_params[key] = _options.post_params[key];
		}
		
		// Send a form
		if (_options.sending_form)
		{
			inputs = $(_options.sending_form + ' :input:not([okn_ignore_field=1])');
			
			if ($(_options.sending_form).attr("okn_validate_form") == "1" && !validate_form(inputs))
			{
				// Ocultar Spinners
				if (_options.show_spinner_in) {
					$(_options.show_spinner_in).each(function(i) {
						$(this).html(old_spinner_content[i]);
					});
				}
				
				// Enable locked objects
				if (_options.locking_object) {
					$(_options.locking_object).setDisabled(false);
				}
				
				return -1;
			}
	
			inputs.each(
				function (i) {
					//alert($(this).attr("name"));
					if ($(this).attr("type") == "radio" || $(this).attr("type") == "checkbox")
					{
						if ($(this).attr("checked") == true)
						{
							//alert($(this).attr("name"));	
							post_params[$(this).attr("name")] = $(this).val();							
						}
					}
					else
					{
						post_params[$(this).attr("name")] = $(this).val();
					}
				}
			);
		}
		
		// Connect with the server (POST request)
		$.post(request_url, post_params, internal_callback, request_format);
				
		function internal_callback(_data, _textStatus)
		{
			// Ocultar Spinners
			if (_options.show_spinner_in) {
				$(_options.show_spinner_in).each(function(i) {
					$(this).html(old_spinner_content[i]);
				});
			}
			
			// Uncontrolled errors
			if (_textStatus != "success" || _data == undefined)
			{
				alert("Communications error: " + _textStatus);
			}
			// Controlled errors
			else if (_options.autohandle_errors && _data.errors > 0) 
			{
				var msg = _data.errors + " SDK Internal Errors:";
				
				for (i = 1; i <= _data.errors; i++)
				{
					msg = msg + "\n[" + i + "] #" + _data.result[i - 1].code + ": " + _data.result[i - 1].message;
				}
				
				alert(msg);
			}
			// Response OK!!
			else 
			{
				// Ocultar Spinners
				if (_options.show_spinner_in) {
					$(_options.show_spinner_in).each(function(i) {
						$(this).html(old_spinner_content[i]);
					});
				}
				
				// Replace innerHTML of the container
				if (_options.replacing_content_with_result) {
					$(_options.replacing_content_with_result).html(_data);
				}
				
				// Replace object with the result
				if (_options.replacing_object_with_result) {
					$(_options.replacing_object_with_result).replaceWith(_data);
				}
				
				// *********************************
				// User (optional) callback function
				// *********************************
				if (_callback_function != undefined && _callback_function)
				{
					if (!_callback_function(_data))
					{
						// Enable posible locked objects
						if (_options.locking_object)
						{
							$(_options.locking_object).setDisabled(false);
						}
						
						return -2;
					}
				}
				
				// Eliminar uno o varios objetos (en función del selector)
				if (_options.removing_object) {
					$(_options.removing_object).each(function () {
						$(this).hide("fast", function (){
							animatePoof(this);
							$(this).remove();
						});
					});
				}
				
				if (_options.autoeval_script_result && request_format == "script")
				{
					eval(_data);
				}
				
				// Navegar por el histórico hacia atrás (1 o más posiciones)
				if (_options.navigating_back) {
					history.back(_options.navigating_back);
					return true;
				}
				
				// Recargar la página actual
				if (_options.reloading_page) {
					location.reload();
					return true;
				}
				
				// Redireccionar a otra página
				if (_options.redirecting_to_url) {
					location.href = _options.redirecting_to_url;
					return true;
				}
			}
			
			// Enable locked objects
			if (_options.locking_object) {
				$(_options.locking_object).setDisabled(false);
			}
			
			return true;
		}
		
		return true;
	}
};