/**
 * Componente de sincronização com webservice
 * Ele é responsável pela sincronização direta com o servidor
 * e retorna no parâmetro retorno a array com todas as linhas da consulta.
 */
function ServicoConsulta(ip, banco, consulta, aceitaVazio, retorno) {
	var error = null;
	var xmlhttp;

	var retornoXml;
	var array = [];


	try {
		if (verificarInternet()) {

			if (ip.indexOf(':') == -1) {
				ip = ip + ":8080";
			}

			if (window.XMLHttpRequest) {
				xmlhttp = new XMLHttpRequest({
					mozSystem: true
				});
			} else {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}

			var dois = 0;

			xmlhttp.onerror = function(e) {
				throw e;
			};



			xmlhttp.onreadystatechange = function() {
				console.log("State: " + xmlhttp.readyState);
				console.log("status: " + xmlhttp.status);
				console.log("status: " + xmlhttp.getAllResponseHeaders());
				if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
					console.log("DOWN");

					console.log(xmlhttp.responseText);
					//correcao bug window phone
					var parser = new DOMParser();
					var doc = parser.parseFromString(xmlhttp.responseText, 'text/xml');
					var retornoXML = doc.getElementsByTagName("SqlConsultaReturn");

					var i = 0;

					//verifica se existe linhas e colunas do banco
					//diferencia se é uma excpetion ou se tudo ta normal
					if (retornoXML[0].childNodes.length != 0) {
						if (retornoXML[0].childNodes[0].nodeValue.indexOf('#l#') != -1 && retornoXML[0].childNodes[0].nodeValue.indexOf('#c#') != -1) {
							for (i in retornoXML[0].childNodes) {
								if (retornoXML[0].childNodes[i].nodeValue != undefined) {
									array = unirArrays(array, retornoXML[0].childNodes[i].nodeValue.split("#l#"));
								}
							};
						} else {
							//verifica se é retorno vazio ou erro
							error = errorGenericoBanco(retornoXML[0].childNodes[0].nodeValue);
						}
					} else {
						if (aceitaVazio === true) {} else {
							error = errorVazio(retornarBanco(consulta));
						}
					}
				}

				if (xmlhttp.readyState == 4 && xmlhttp.status == 404) {
					error = erro404();
				}

				if (xmlhttp.readyState == 4 && xmlhttp.status == 500) {
					error = erro500();
				}

				if (xmlhttp.readyState == 4 && xmlhttp.status == 503) {
					error = erro503();
				}

				if (xmlhttp.readyState == 2 && xmlhttp.status == 0) {}
			};

			function verificarErro() {

			}

			var urlMM = getURLFormatada(ip);
			var consultaa = montarXmlConsulta(banco, consulta);

			console.log("URL de conexão: " + urlMM);

			xmlhttp.open("POST", urlMM, false);

			xmlhttp.setRequestHeader("Content-Type", "text/xml");
			xmlhttp.setRequestHeader("SOAPAction", "\"\"");
			console.log('consulta: ' + consulta);
			xmlhttp.send(consultaa);
		} else {
			error = erroSemInternet();
		}

	} catch (e) {
		throw e;
	} 


	function getURLFormatada(ipMontar) {

		return "http://" + ipMontar + "/axis/SmartMobile.jws";

	}

	function montarXmlConsulta(banco, xml) {

		var retorno = new StringBuilder();

		retorno.append("<soapenv:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:def=\"http://DefaultNamespace\">   <soapenv:Header/>   <soapenv:Body>      <def:SqlConsulta soapenv:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">         <banco xsi:type=\"xsd:string\" xs:type=\"type:string\" xmlns:xs=\"http://www.w3.org/2000/XMLSchema-instance\">");
		retorno.append(banco);
		retorno.append("</banco>         <xml xsi:type=\"xsd:string\" xs:type=\"type:string\" xmlns:xs=\"http://www.w3.org/2000/XMLSchema-instance\">");
		retorno.append(xml);
		retorno.append("</xml>      </def:SqlConsulta>   </soapenv:Body></soapenv:Envelope>");

		return retorno.toString();
	}

	try {
		if (error == null) {
			array = jQuery.grep(array, function(n) {
				return (n);
			});
			console.log("Total de dados: " + array.length);
			retorno(array);
		} else {
			throw error;
		}
	} catch (e) {
		throw e;
	} finally{
		if(error != null){
			throw error;
		}
	}
}

function montarSqlSelect(valores, from, where) {

	var rtn = new StringBuilder();

	rtn.append("SELECT ");

	for (var i = 0; i < valores.length; i++) {

		rtn.append(valores[i]);

		if ((i + 1) != valores.length) {
			rtn.append(", ");
		}
	}

	rtn.append(" FROM ");
	rtn.append(from);

	if (where != undefined && where != '') {
		rtn.append(" WHERE ");
		rtn.append(where);
	}

	return rtn.toString();

}

function unirArrays(x, y) {
	var obj = {};
	for (var i = x.length - 1; i >= 0; --i)
		obj[x[i]] = x[i];
	for (var i = y.length - 1; i >= 0; --i)
		obj[y[i]] = y[i];
	var res = [];
	for (var k in obj) {
		if (obj.hasOwnProperty(k))
			res.push(obj[k]);
	}
	console.log(res);
	return res;
}

function retornarBanco(msg) {
	msg = msg.toUpperCase();
	var retorno = msg.split('FROM');
	retorno = retorno[1];

	if (retorno.indexOf('WHERE') != -1) {
		retorno = retorno.split('WHERE');
		retorno = retorno[0];
	}

	if (retorno.indexOf('ORDER BY') != -1) {
		retorno = retorno.split('ORDER BY');
		retorno = retorno[0];
	}

	if (retorno.indexOf('GROUP BY') != -1) {
		retorno = retorno.split('ORDER BY');
		retorno = retorno[0];
	}

	return retorno;

}

//--------------------------------------------------------------
//----------------------- ERROS --------------------------------
//--------------------------------------------------------------

/**
 *ERRO 500 - 503 (Service Unavailable)
 * Erro que dispara caso não encontra o link correto;
 */
var erroSemInternet = function() {
	var error = new Error('Conexão: Não foi possível conectar ao Servidor.\n1)Verifique sua Conexão\n2)Sincronize Novamente');
	error.name = 'Sem Conexão';
	return error;
};
/**
 *ERRO 500 - 503 (Service Unavailable)
 * Erro que dispara caso não encontra o link correto;
 */
var erro503 = function() {
	var error = new Error('Servidor Indisponível');
	error.name = 'ERRO 503';
	return error;
};
/**
 *ERRO 500 - Erro condição inesperada que o impediu de cumprir o pedido
 * Erro que dispara caso não encontra o link correto;
 */
var erro500 = function() {
	var error = new Error('Condição inesperada que o impediu de cumprir o pedido');
	error.name = 'ERRO 500';
	return error;
};

/**
 *ERRO 404 - Página não encontrada
 * Erro que dispara caso não encontra o link correto;
 */
var erro404 = function() {
	var error = new Error('Página não encontrada, verifique se o link ou a porta estão corretas');
	error.name = 'ERRO 404';
	return error;
};

/**
 *ERRO 404/BANCO - BANCO NÃO ENCONTRADO
 * Erro que dispara caso não encontra o link correto;
 */
var erro404Banco = function(msg) {
	var error = new Error(msg);
	error.name = 'ERRO 404/BANCO';
	return error;
};

var errorGenericoBanco = function(msg) {
	var error = new Error(msg);
	error.name = 'Erro interno WEBSERVICE';
	return error;
};

var errorVazio = function(msg) {
	var error = new Error('Retorno vazio, não é aceito - ' + msg);
	error.name = 'Retorno:';
	return error;
};

function verificarInternet() {
	if (/*navigator.connection.type != Connection.UNKNOWN &&*/ navigator.connection.type != Connection.NONE) {
		return true;
	} else {
		return false;
	}
}