var Ajax = function(_targetOrComplete, _url, _requestMethod){
	this.before = function() { return true; };
	this.error = function () { alert("Ocorreu um erro ao executar a ação solicitada."); };
	this.complete = this.content;
	this.target = $("corpo");
	this.feedBack = false;
	this.requestMimeType = "text/html; charset=utf-8";
	this.method = "get";
	this.params = "";
	this.baseUrl = URL + "js/ajax/";
	this.historyControl = null;
	this.ifrName = "iframeHistory";
	var xmlHttp = null;
	/*@cc_on @*/
	/*@if (@_jscript_version >= 5)
	try {
		xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (e2) {
			xmlHttp = false;
		}
	}
	@end @*/
	if (!xmlHttp && typeof XMLHttpRequest != 'undefined') { xmlHttp = new XMLHttpRequest();	}
	if(!xmlHttp) alert("Esta página utiliza um controle ActiveX.\nPor favor, habilite os controles ActiveX em seu browser e tente novamente.");
	else this.xmlHttp = xmlHttp;

	if(_targetOrComplete!=null) {
		if(typeof _targetOrComplete == 'function') this.setComplete(_targetOrComplete);
		else this.setTarget(_targetOrComplete);
	}
	if(_requestMethod!=null) this.setRequestMethod(_requestMethod);
	if(_url!=null) this.callServer(_url);
}
/* sets */
Ajax.prototype.setRequestMethod = function(requestMethod) {// false = text | true = xml
	if(requestMethod=='xml') requestMethod = true;
	this.requestMethod = requestMethod;
	if(requestMethod){
		if (this.xmlHttp.overrideMimeType) this.xmlHttp.overrideMimeType('text/xml; charset=utf-8');
		this.setRequestMimeType('text/xml; charset=utf-8');
	}
};
Ajax.prototype.setRequestMimeType = function(mimeType) { this.requestMimeType = mimeType; };
Ajax.prototype.setMethod = function(method){ this.method = method.toLowerCase(); };
Ajax.prototype.setFeedBack = function(element){ this.feedBack = $(element); };

Ajax.prototype.setTarget = function(target) {
	target = (typeof target=='string') ? $(target) : target ;
	this.target = target;
};

Ajax.prototype.setBefore = function(before){ this.before = before; };
Ajax.prototype.setError = function(error){
	if((typeof error) == "function") this.error = error;
	else {
		this.error = function(){ alert(error); };
	}
};
Ajax.prototype.setComplete = function(complete){
	if((typeof complete) == "function")	this.complete = complete;
	else this.complete = function(){ alert(complete); };
};
/* feedBack */
Ajax.prototype.activateHistoryControl = function(){ this.historyControl = true; }
Ajax.prototype.destroyHistoryControl = function(){ this.historyControl = false; }

Ajax.prototype.makeFeedBack = function(label, id){
	var id = isset(id) ? id : "activity";
	var label = isset(label) ? label : "Processando";
	if(!$(id)){
		var div = document.createElement("div");
		div.setAttribute("id", id);
		div.innerHTML = this.fixIeWindow(id) + label;
		document.body.appendChild(div);
	}
	this.feedBack = $(id);
};
Ajax.prototype.fixIeWindow = function(id){
	var idFrame = 'TTiEiFrM' + id;
	var tt_n = navigator.userAgent.toLowerCase();
	var tt_nv = navigator.appVersion;
	var tt_ie = (tt_n.indexOf("msie") != -1 && document.all)?true:false;
	var tt_ie6 = tt_ie && parseFloat(tt_nv.substring(tt_nv.indexOf("MSIE")+5)) >= 5.5 ? true : false;
	if(tt_ie || tt_ie6) return '<iframe id="' + idFrame + '" src="javascript:false" scrolling="no" frameborder="0" style="filter:Alpha(opacity=0);position:absolute;top:0px;left:0px;display:block;width:300px;height:300px;margin:-2px;z-index:-100" width="100%" height="100%"></iframe>';
	return "";
}
/* methods */
Ajax.prototype.hideFeedBack = function(){
	if(!this.feedBack) return true;
	this.feedBack.style.visibility = "hidden";
	this.feedBack.style.display = "none";
}
Ajax.prototype.showFeedBack = function(){
	if(!this.feedBack) return true;
	this.feedBack.style.visibility = "visible";
	this.feedBack.style.display = "block";
}
Ajax.prototype.noCache = function(){
	this.xmlHttp.setRequestHeader("Cache-Control", "no-store, no-cache, must-revalidate");
	this.xmlHttp.setRequestHeader("Cache-Control", "post-check=0, pre-check=0");
	this.xmlHttp.setRequestHeader("Pragma", "no-cache");
}
Ajax.prototype.reviewParams = function(params){
	if(!isset(params)) return false;
	if(this.method=="post") {
		this.params = params.substring(1);
		return;
	}

	this.params = encodeURIComponent(params);
	this.params = this.params.replace(/%3F/gi,"&"); // &
	this.params = this.params.replace(/%26/gi,"&"); // ?
	this.params = this.params.replace(/%3D/gi,"="); // =

	this.params = "?" + this.params.substring(1);
	return this.params;
}

/* calling the server */
Ajax.prototype.callServer = function(url, params) {
	if(!this.before()) return false;
	this.showFeedBack();
	this.reviewParams(params);

	this.url = url;

	if(this.historyControl!=null && this.historyControl!=false){
		this.historyControl = false;
		this.callIframe();
		window.backButton = this;
		return;
	}

	this.url = (this.method=="post")? url : url + this.params;
	this.xmlHttp.open(this.method, this.url, true);

	var g = this;
	this.xmlHttp.onreadystatechange = function(){
		if (g.xmlHttp.readyState == 4) {
			if (g.xmlHttp.status ==200) {
				var r = (g.requestMethod)? g.xmlHttp.responseXML : g.fixCall(g.xmlHttp.responseText);
				g.complete(r);
				g.hideFeedBack();
				if(g.historyControl == false) g.activateHistoryControl();
				return true;
			}else{
				g.error();
				g.hideFeedBack();
				if(g.historyControl == false) g.activateHistoryControl();
				return false;
			}
		}
	}
	if(this.method=="post") {
		this.xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
		this.noCache();
		this.xmlHttp.send(this.params);
	} else {
		this.xmlHttp.setRequestHeader("Content-Type", this.requestMimeType);
		this.noCache();
		this.xmlHttp.send(null);
	}
};
Ajax.prototype.callIframe = function(){
	if($(this.ifrName) == null){
		var i = document.createElement("iframe");
		i.setAttribute("id", this.ifrName);
		i.setAttribute("name", this.ifrName);
		document.body.appendChild(i);
	}
	var p = (!empty(this.params)) ? this.params + "&" : "?" ;
	var l = location.pathname;
	if(this.url.indexOf("http://"))	this.url = "http://" + location.host + (l.substring(0,l.lastIndexOf("/"))) + "/" + this.url;
	window[this.ifrName].location.href = this.baseUrl + "blank.htm" + p + "actionUrl=" + this.url;
};

Ajax.prototype.sendForm = function(targetForm, before){
	var _form = this.getFormObject(targetForm);

	if((typeof _form) == "undefined") return false;
	var url = _form.getAttribute("action");

	var method = (_form.getAttribute("method")) ? _form.getAttribute("method") : "post";
	this.setMethod(method);

	if(_form.getAttribute("enctype")) this.setRequestMimeType(_form.getAttribute("enctype"));

	var params = "", value = "", t = '';

	for(var i=0;i<_form.length;i++) {
		t = _form[i].tagName.toLowerCase();
		if(t=="checkbox" || t=="select" || t=="input" || t=="button" || t=="textarea") {
			if(_form[i].type=="checkbox") {
				if(_form[i].checked) params += "&" + _form[i].name + "=1";
			} else {
				params += "&" + _form[i].name + "=";
				value = encodeURIComponent(_form[i].value);
				params += value;
			}
		}
	}

	var formId = _form.attributes["id"].value;
	if(isset(before)) this.setBefore(before);
	else if(isset(window[formId + "addJsValidation"])) this.setBefore(window[formId + "addJsValidation"]);

	this.callServer(url, params);
};

Ajax.prototype.getFormObject = function(targetForm) {
	var _form = (typeof targetForm) == "string" ? $(targetForm) : targetForm;
	if(_form.tagName.toLowerCase() == 'form') return _form;
	while(_form.tagName.toLowerCase() != 'form') _form = _form.parentNode;
	return _form;
};

Ajax.prototype.parseForms = function(_target) {
	var ifr, _id, i, j;

	if(_target==null) _target = this.target;
	var _forms = _target.getElementsByTagName('form');
	if(!_forms.length) return;

	for( i=0; i<_forms.length; i++) {
		_inps = _forms[i].getElementsByTagName('input');

		for( j=0; j<_inps.length; j++) {
			if(_inps[j].getAttribute('type')=='file') {
				_id = _inps[j].getAttribute('id');
				_inps[j].setAttribute("id", _id + 'File');

				//_inps[j].addEventListener('blur', this.uploadFileAfterDelay, true);

				_inpH = cE('input', _forms[i], _id);
				_inpH.value = ($(_id + '_ANT')) ? $(_id + '_ANT').value : '';
				_inpH.style.visibility = "hidden";
				_inpH.style.display = "none";

				ifr = cE('iframe', _forms[i], 'iframe_'+_id);
				ifr.style.display = 'none';

				_forms[i].gotUploadField = true;
			}
		}

		//_forms[i].addEventListener('submit',
	}
};

Ajax.prototype.uploadFileAfterDelay = function() {
	console.info(arguments[0]);
};

Ajax.prototype.uploadFile = function() {
};

Ajax.prototype.content = function(r) {
	this.target.innerHTML = r[0];
	this.target.style.display = 'block';
	createScriptSrc(r[2]);
	createScriptBlock(r[1]);
	this.parseForms();
	return true;
}
Ajax.populateCombo = Ajax.prototype.populateCombo = function(target, data) {
	var v = null;

	while (target.firstChild) target.removeChild(target.firstChild);
	for(var i=0; i<data.length; i++) {
		v = data[i].attributes;
		target.options[i] = new Option(v[1].value, v[0].value);

		if(v.length > 2)
			target.options[i].setAttribute('selected', 'selected');
	}
	target.focus();
}

/* fix call (no eval) */
Ajax.fixCall = Ajax.prototype.fixCall = function(r){
	var ini = 0;
	var add = "";
	var code = "";
	var scriptEnd = 0;
	var _src = Array();
	while (ini!=-1){
		ini = r.indexOf('<script', ini);
		if (ini >=0){
			var scriptIni = r.indexOf('>', ini) + 1;
			scriptEnd = r.indexOf('</script>', scriptIni);
			add = r.substring(scriptIni,scriptEnd);
			if(add.length==0) _src.push(scriptSrc(r.substring(ini, scriptIni)));
			else code += add;
			ini = scriptIni;
		}
	}
	var ret = Array(r, code, _src);
	ret['response'] = r;
	ret['code'] = code;
	ret['sources'] = _src;
	return ret;
}

var scriptSrc = function(src){
	var srcIni = src.indexOf('src="', src)+5;
	var srcEnd = src.indexOf('"', srcIni);
	return src.substring(srcIni, srcEnd);
}

var createScriptBlock = function(text){
	var script = document.createElement("script");
	script.text = text;
	document.body.appendChild(script);
}
var createScriptSrc = function(_src) {
	for(var i=0;i<_src.length;i++) {
		var script = document.createElement("script");
		script.setAttribute("src", _src[i]);
		script.setAttribute("type", "text/javascript");
		script.setAttribute("charset", "utf-8");
		document.body.appendChild(script);
	}
}