MSIE = document.all;
NS4 = document.pageX;
CHROME = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
MOZ = navigator.product == 'Gecko'; // También detecta Chrome
MOZ2 = navigator.product == 'Gecko' && !CHROME;

if(MSIE) MSIE_VERSION = parseFloat(navigator.appVersion.split("MSIE")[1]);

function ktkCompatFixStyle(styleObj) {
	// Agregar setAttribute para Mozilla
	if(!styleObj.setAttribute) {
	   styleObj.setAttribute = function(prop, val) {
	      this[prop] = val;
	   }
	}
}

function ktkCompatSetStyle(obj, attr, val) {
	if(obj.style.setAttribute) {
		obj.style.setAttribute(attr, val);
	} else {
		obj.style[attr] = val;
	}
}

function ktkCompatGetEvent(evt) {
	return (evt ? evt : window.event);
}

function ktkGetKeyCode(evt) {
	evt = ktkCompatGetEvent(evt);
	var code = evt.keyCode;
	/*
	if(!code) {
		code = evt.which;
	}
	*/
	return code;
}

function ktkPressedKeyCode(evt) {
	if(MOZ) {
		return evt.which;
	} else {
		return event.keyCode;
	}
}

function ktkCompatSetX(obj, val) {
	if(MSIE) {
		obj.x = val;
	} else {
		obj.style.left = val;
	}
}

function ktkCompatSetY(obj, val) {
	if(MSIE) {
		obj.y = val;
	} else {
		obj.style.top = val;
	}
}

function ktkCompatGetWidth(obj) {
	return obj.clientWidth;
}

function ktkCompatGetHeight(obj) {
	return obj.clientHeight;
}

function ktkCompatGetWindowVisibleWidth(win) {
	var doc = win.document;
	if(MSIE) {
		return doc.body.offsetWidth;
	} else {
		return doc.body.clientWidth;
	}
}

function ktkCompatGetWindowVisibleHeight(win) {
	var doc = win.document;
	if(MSIE) {
		// Estamos dentro del editor en el frame inferior
		var tmp = win.document.documentElement.clientHeight;
		if(tmp) return tmp;

		return doc.body.offsetHeight;
	} else {
		return doc.body.clientHeight;
	}
}

function ktkCompatGetContentHeight(bodyObj) {
	return bodyObj.scrollHeight;
}

function ktkCompatGetXY(elem) {
	if (NS4 || MOZ) {
		return elem.pageX;
	} else {
		xPos = elem.offsetLeft - elem.document.body.scrollLeft;
		yPos = elem.offsetTop - elem.document.body.scrollTop;
		var tempEl = elem.offsetParent;
  		while (tempEl != null) {
  			xPos += tempEl.offsetLeft;
			yPos += tempEl.offsetTop
	  		tempEl = tempEl.offsetParent;
  		}
		return {"x": xPos, "y": yPos};
	}
}

function ktkCompatGetScrollLeft(container) {
	var objBody = container.document.body;
	var objDocElem = container.document.documentElement;

	// Ambos funcionan en ambos browsers (según el DocType seguramente)
	return Math.max(objBody.scrollLeft, objDocElem.scrollLeft);
}

function ktkCompatGetScrollTop(container) {
	var doc = container.document;
	var objBody = doc.body;
	var objDocElem = doc.documentElement;

	// Ambos funcionan en ambos browsers (según el DocType seguramente)
	return Math.max(objBody.scrollTop, objDocElem.scrollTop);
}

function ktkCompatGetX(elem) {
	if (NS4) {
		return elem.pageX;
	} else {
		xPos = elem.offsetLeft - elem.document.body.scrollLeft;
		var tempEl = elem.offsetParent;
  		while (tempEl != null) {
  			xPos += tempEl.offsetLeft;
	  		tempEl = tempEl.offsetParent;
  		}
		return xPos;
	}
}

// Si se dontIncludeScroll = true => se obtiene posición relativa al documento, sin considerar su scrollbar. Necesario para ktkScrollTo.
function ktkCompatGetY(elem, dontIncludeScroll) {
	if (NS4) {
		return elem.pageY;
	} else {
		// ktkDebugLog("ktkCompatGetY: --- " + elem.tagName + " = " + elem.offsetTop + " ---");
		yPos = elem.offsetTop;
		if(!dontIncludeScroll) {
			yPos -= elem.document.body.scrollTop;
		}
		var tempEl = elem.offsetParent;
		while (tempEl != null) {
			// ktkDebugLog("ktkCompatGetY: " + tempEl.tagName + " = +" + tempEl.offsetTop);
			yPos += tempEl.offsetTop
	  		tempEl = tempEl.offsetParent;
  		}
		return yPos;
	}
}

function ktkScrollTo(container, x2, y2) {
	var x1 = ktkCompatGetScrollLeft(container);
	var y1 = ktkCompatGetScrollTop(container);
	
	// alert("y1 = " + y1 + ", y2 = " + y2);
	
	steps = 50;
	var dx = (x2 - x1) / steps;
	var dy = (y2 - y1 - 200) / steps;
	for(var i = 0; i < steps; i++) {
		x = dx * i + x1;
		y = dy * i + y1;
		container.scrollTo(x, y);
	}
}

function ktkHasHScrollBar(obj) {
	return obj.clientWidth + 15 < obj.offsetWidth;
	// CHANGED: Produce DeadLock
	// return obj.clientWidth + 15 < obj.scrollWidth;
}

function ktkHasVScrollBar(obj) {
	return obj.clientHeight + 15 < obj.scrollHeight;
}

function ktkDispatchEvents(obj, eventId, e) {
	e = ktkCompatGetEvent(e);
	for(var i = 0; i < obj.ktkEventHandlers[eventId].length; i++) {
		if(e) e.ktkTarget = obj;

		/*
		if(obj.id.indexOf("form_2_Tipo[") != -1) {
			ktkDebug(obj.id + " - " + eventId + ": " + obj.ktkEventHandlers[eventId][i] + "");
		}
		*/

		obj.ktkEventHandlers[eventId][i].apply(obj, [e]);
	}
}

function ktkAddEvent(obj, eventId, func, before) {
	if(MSIE) eventId = "on" + eventId;

	/*
	if(obj.id.indexOf("Tipo") != -1) {
		ktkDebug("ktkAddEvent: " + obj.id + ", func = " + func);
	}
	*/
	
	ktkInitEventHandler(obj, eventId);
	
	if(before) {
		ktkArrayInsert(obj.ktkEventHandlers[eventId], 0, func);
	} else {
		obj.ktkEventHandlers[eventId].push(func);
	}
}

function ktkInitEventHandler(obj, eventId) {
	if(!obj.ktkEventHandlers) obj.ktkEventHandlers = {};
	if(!obj.ktkEventHandlers[eventId]) {
		obj.ktkEventHandlers[eventId] = [];

		if(
		   	obj[eventId]
			// No encolar evento nativo de Mozilla (crea problemas con el focus)
			// TODO: Detectar de otra forma
			&& !(MOZ && obj[eventId].name == eventId)
		) {
			// Archivar evento original
			obj.ktkEventHandlers[eventId].push(obj[eventId]);
		}

		var func = new Function("ktkDispatchEvents(this, '" + eventId + "', arguments[0])");
		
		if(MSIE) {
			obj[eventId] = func;

		} else {
			obj.addEventListener(eventId, func, false);

			if(window.MOZ && eventId == "blur") {
				// Asegurar que se haga onChange antes de onBlur
				obj._ktkOnBlur = obj.onblur;
				obj.onblur = new Function("ktkMOZDelayBlur('" + obj.id + "', arguments[0])");
			}
		}
	}
}

function ktkGetChildNodeById(obj, id) {
	var childNodes = obj.childNodes, t;
	for(var i = 0; i < childNodes.length; i++) {
		t = childNodes[i];
		if(t.id == id) return t;
	}
	return null;
}

function ktkGetTarget(e) {
	e = ktkCompatGetEvent(e);
	if(!e) return null;
	if(e.ktkTarget) return e.ktkTarget;
	if(MSIE) {
		return e.srcElement;
	} else {
		return e.target;
	}
}

function ktkMOZDelayBlur(objId, e) {
	// setInterval(new Function("try {ktkObj('" + objId + "')._ktkOnBlur()} catch (e) {}"), 100);
	window.MOZDelayBlurEvent = e; // TODO: Soportar múltiples MOZDelayBlur mediante "e" almacenados independientemente
	setTimeout(new Function("var f = ktkObj('" + objId + "')._ktkOnBlur; if(f) f(MOZDelayBlurEvent)"), 100);
}

function ktkFadeIn(obj) {
	ktkFadeInOut(obj, 'visible');
}

function ktkFadeOut(obj) {
	ktkFadeInOut(obj, 'hidden');
}

function ktkFadeInOut(obj, dest) {
	if(MSIE) {
		obj.style.filter = "blendTrans(duration=0.5)";
		obj.filters.blendTrans.apply();
		ktkCompatSetStyle(obj, 'visibility', dest);
		obj.filters.blendTrans.play();

	} else {
		ktkCompatSetStyle(obj, 'visibility', dest);
	}
}

