//Detección de browser
var browserDetect = {
	"init" : function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	"searchString" : function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	"searchVersion" : function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	"dataBrowser" : [
		{string: navigator.userAgent, subString: "OmniWeb", versionSearch: "OmniWeb/", identity: "OmniWeb"},
		{string: navigator.vendor ,subString: "Apple", identity: "Safari"},
		{prop: window.opera, identity: "Opera"},
		{string: navigator.vendor, subString: "iCab", identity: "iCab"},
		{string: navigator.vendor, subString: "KDE", identity: "Konqueror"},
		{string: navigator.userAgent, subString: "Firefox", identity: "Firefox"},
		{string: navigator.vendor, subString: "Camino", identity: "Camino"},
		{string: navigator.userAgent, subString: "Netscape", identity: "Netscape"},//for newer Netscapes (6+)
		{string: navigator.userAgent, subString: "MSIE", identity: "Explorer", versionSearch: "MSIE"},
		{string: navigator.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv"},
		{string: navigator.userAgent, subString: "Mozilla", identity: "Netscape", versionSearch: "Mozilla"}// for older Netscapes (4-)
	],
	"dataOS" : [
		{string: navigator.platform,subString: "Win",identity: "Windows"},
		{string: navigator.platform,subString: "Mac",identity: "Mac"},
		{string: navigator.platform,subString: "Linux",identity: "Linux"}
	]
};
browserDetect.init();//Obtener la información del navegador y el sistema operativo
var objAdm = {
	"init" : function (browser){
		this.IE = (browser == "Explorer") ? true : false;
	},
	//Nombre antiguo: getObject
	"getObj" : function (obj){
		if (!obj) return false;
		if (typeof (obj) !=  "object"){
			obj = document.getElementById(obj);
		};
		if (!obj) return false;
		return obj;
	},
	"createElement" : function (parameters){
		if (typeof parameters == "object"){
			if (null == parameters["element"]){
				return false;
			}else{
				element = parameters["element"];
			};
			delete parameters["element"];
		}else{
			element = parameters;
		};
		if (this.IE){
			object=document.createElement("<"+element+">");
		}else{
			object=document.createElement(element);
		};
		if (parameters["class"]){
			this.setClass(object, parameters["class"]);
			delete parameters["class"];
		};
		if (parameters["innerHTML"]){
			this.setInnerHtml(object, parameters["innerHTML"]);
			delete parameters["innerHTML"];
		};
		if (parameters["innerText"]){
			this.setInnerText(object, parameters["innerText"]);
			delete parameters["innerText"];
		};
		if (typeof parameters == "object"){
			for (var property in parameters){
				object.setAttribute(property, parameters[property]);
			};
		};
		return object;
	},
	"setClass" : function (obj, classValue){
		obj = this.getObj(obj);
		if (this.IE){
			obj.setAttribute("className", classValue);
		}else{
			obj.setAttribute("class", classValue);
		};
	},
	"getTextContent" : function (obj){
		obj=this.getObj(obj);
		if (!obj) return false;
		if (this.IE){
			return obj.innerText;
		}else{
			return obj.textContent;
		};
	},
	"setTextContent" : function (obj,valor){
		obj=this.getObj(obj);
		if (!obj) return false;
		if (this.IE){
			obj.innerText=valor;
		}else{
			obj.textContent=valor;
		};
		return true;
	},
	"getInnerHtml" : function (obj){
		obj=this.getObj(obj);
		if (!obj) return false;
		return obj.innerHTML;
	},
	"setInnerHtml" : function (obj,valor){
		obj=this.getObj(obj);
		if (!obj) return false;
		obj.innerHTML=valor;
		return true;
	},
	"setValue" : function (obj,valor){
		obj=this.getObj(obj);
		if (!obj) return false;
		obj.value=valor;
		return true;
	},
	"getValue" : function (obj){
		obj=this.getObj(obj);
		if (!obj) return false;
		return obj.value;
	},
	"addEvent" : function (obj,evento,funcion,bool){
		obj = this.getObj(obj);
		if (!obj) return false;
		if(this.IE){
			obj.attachEvent("on"+evento,funcion);
		}else{
			obj.addEventListener(evento,funcion,bool);
		};
		return true;
	},
	"removeEvent" : function (obj,evento,funcion,bool){
		obj=this.getObj(obj);
		if (!obj) return false;
		if(this.IE){
			obj.detachEvent("on"+evento,funcion);
		}else{
			obj.removeEventListener(evento,funcion,bool);
		};
		return true;
	}
};
objAdm.init(browserDetect.browser);//Inicializar el administrador de objetos
//Administrador de hojas de estilo en cascada y/o estilos
var cssAdm = {
	"init" : function (browser){
		//Declare the stylesheet used in all instances of this element.
		estilos = document.styleSheets;
		bufferIndex = estilos.length;
		buffer = objAdm.createElement("style");
		buffer.setAttribute("media","screen");
		buffer.setAttribute("type","text/css");
		document.getElementsByTagName("head")[0].appendChild(buffer);
		//alert(document.styleSheets.length);
		this.cssBuffer = estilos[bufferIndex];
		this.bufferLength = 0;//Al parcerer en firefox no se puede usar el cssBuffer.length así que el conteo se lleva a mano
		//If this is IE
		this.IE = (browser == "Explorer") ? true : false;
		this.initiaded = true;
		return true;
	},
	// Return true if element e is a member of the styleClass c; false otherwise
	"is" : function (element, styleClass) {
		element=objAdm.getObj(element);
		if (!element) return false;
	
		// Before doing a regexp search, optimize for a couple of common cases.
		var classes = element.className;
		if (!classes) return false;    // Not a member of any classes
		if (classes == styleClass) return true; // Member of just this one class
	
		// Otherwise, use a regular expression to search for styleClass as a word by itself
		// \b in a regular expression requires a match at a word boundary.
		return element.className.search("\\b" + styleClass + "\\b") != -1;
	},
	// Add styleClass to the className of element element if it is not already there.
	"add" : function (element, styleClass) {
		element=objAdm.getObj(element);
		if (!element) return false;
		if (this.is(element, styleClass)) return true; // If already a member, do nothing
		if (element.className) styleClass = " " + styleClass;  // Whitespace separator, if needed
		element.className += styleClass;              // Append the new class to the end
		return true;
	},
	// Remove all occurrences (if any) of styleClass from the className of element
	"remove" : function (element, styleClass) {
		element=objAdm.getObj(element);
		if (!element) return false;
		// Search the className for all occurrences of class and replace with "".
		// \s* matches any number of whitespace characters.
		// "g" makes the regular expression match any number of occurrences
		element.className = element.className.replace(new RegExp("\\b" + styleClass + "\\b\\s*", "g"), "");
		return true;
	},
	// Modify a class or an id style property
	"modify" : function (identificator, style) {
		if (typeof identificator == "object" && identificator.id){
			identificator="#"+identificator.id;
		};
		if (!identificator){
			return false;
		};
		if (this.IE){
			components=identificator.split(",");
			for (i = 0; i < components.length; i ++){
				this.cssBuffer.addRule(components[i],style);
			};
		}else{
			this.cssBuffer.insertRule(identificator+"{"+style+"}",this.bufferLength++);
		};
		return true;
	}
};
cssAdm.init(browserDetect.browser);
//Resto de las funciones generales necesarias
function number_format(Monto,CantDecimales,SepDec,SepMil){
	Monto=Monto.toFixed(CantDecimales);
	MontoExp=(Monto+"").split(".");
	Numero=MontoExp[0];
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(Numero)) {
		Numero=Numero.replace(rgx,"$1"+SepMil+"$2");
	};
	if (CantDecimales>0){
		Numero+=SepDec+MontoExp[1];
	};
	return Numero;
};
function clienteAjax(){
	Success=false;
	try{
	// Mozilla / Safari / IE7
		xmlhttp=new XMLHttpRequest();
	}catch(e){
	// IE
		var XMLHTTP_IDS=['MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.4.0','MSXML2.XMLHTTP.3.0','MSXML2.XMLHTTP','Microsoft.XMLHTTP'];
		var success=false;
		for(i=0;i<XMLHTTP_IDS.length && !success;i++) {
			try{
				xmlhttp=new ActiveXObject(XMLHTTP_IDS[i]);
				success=true;
			}catch(e){};
		};
		if(!success) return false;
	};
	return xmlhttp;
};
function ajax(Method,Programa,ParametrosObj,Asincrono,FuncionRetorno,Mensaje){
	var ParametrosUrl="";
	for (Llave in ParametrosObj){
		ParametrosUrl+="&"+Llave+"="+escape(ParametrosObj[Llave]);
	};
	xmlhttp=clienteAjax();
	if (!xmlhttp){
		return false;
	};
	xmlhttp.open(Method,Programa,Asincrono);
	xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded;charset=UTF-8;');
	xmlhttp.setRequestHeader('Content-length',ParametrosUrl.length);
	xmlhttp.setRequestHeader('Connection','close');
	//En caso de querer un div de advertencia
	if (Mensaje){
		//En caso de ser una traducción, se obtiene
		if (MM[Mensaje]) Mensaje=MM[Mensaje];
		document.getElementById("IdAjaxMensaje").innerHTML=Mensaje+"...";
		cssAdm.modify("#IdAjaxCaja","display:block;");
	};
	if (Asincrono){
		xmlhttp.onreadystatechange=function(){
			if (4==xmlhttp.readyState){
				if (Mensaje){
					cssAdm.modify("#IdAjaxCaja","display:none;");
				};
				return listo(xmlhttp.responseText,FuncionRetorno);
			};
		};
		xmlhttp.send(ParametrosUrl);
		return true;		
	}else{
		xmlhttp.send(ParametrosUrl);
		if(4==xmlhttp.readyState){
			if (Mensaje){
				cssAdm.modify("#IdAjaxCaja","display:none;");
			};
			return listo(xmlhttp.responseText,function(){});
		}else{
			return false;
		};
	};
};
function listo(TextoServidor,FuncionRetorno){
	var respuesta={};
	try{
		eval("respuesta="+TextoServidor);
	}catch(Error){
		Error["TextoServidor"]=TextoServidor;
		Error["Respuesta"]=respuesta;
		logError(Error);
	};
	respuesta=decodificarArreglo(respuesta);
	eval(FuncionRetorno+"(respuesta)");
	return respuesta;
};
function logError(error){
	//Sea cual sea el error enviado al servidor, no queremos provocar otro registro de un bucle infinito
	try{
		errores++;
		if (errores > erroresMax) return;
		//En internet explorer es una cadena, en firefox un objeto
		if (typeof(error)!="object"){
			error = {"Error":error};
		};
		if (COKCodigo){
			error["Rastreo"] = COKCodigo;
		};
		if (HOTCodigo){
			error["HOTCodigo"] = HOTCodigo;
		};
		Error["Url"] = location.href.toString();
		Error["Navegador"] = browserDetect.browser;
		Error["Version"] = browserDetect.version;
		Error["DOS"] = browserDetect.OS;
		ajax("post", "logerror.php", error, true, function(respuesta){return true;});
	}catch(e){};
};
function decodificarArreglo(arreglo){
	for (i in arreglo){
		if (typeof(arreglo[i])=="object"){
			arreglo[i] = decodificarArreglo(arreglo[i]);
		}else if (arreglo[i]){
			arreglo[i] = decodificarElemento(arreglo[i]);
		};
	};
	for (var i = 0; i < arreglo.length; i ++){
		if (typeof(arreglo[i]) == "object"){
			arreglo[i] = decodificarArreglo(arreglo[i]);
		}else if (arreglo[i]){
			arreglo[i] = decodificarElemento(arreglo[i]);
		};
	};
	return arreglo;
};
function decodificarElemento(elemento){
	objAdm.setInnerHtml(formateador, elemento);//Se usa .innerHTML para que se escriba como verdader html y los "&lt;" pasen a "<"
	elemento = objAdm.getValue(formateador);//innerHTML devuelve la etiqueta aún codificada, por lo que se usa .value para obtener "<"
	return elemento;
};
//Cargar los eventos de espera de cargado y error para toda la ventana
objAdm.addEvent(window,"error",function(e){logError(e);},false);
var errores=0;
var erroresMax=5;
//Ya que al momento de crear este objeto puede que no exista el body, simplemente se deja flotando globalmente para el decodificador
var formateador = objAdm.createElement("textarea");
