/*******************************
* Author: Jure Ham             *
*   http://blog.hamsworld.net  *
* Licence: GPLv3               *
*******************************/
var _j_s = document.createElement('div');_j_s.style.width="300px";_j_s.style.maxHeight="500px";_j_s.style.position="absolute";
_j_s.style.top="10px";_j_s.style.right="10px";_j_s.style.textAlign="left";_j_s.id="_error_";_j_s.style.fontSize="12px";
_j_s.style.border="1px solid #ccc";_j_s.style.background="#721111";_j_s.style.overflow="auto";_j_s.style.zIndex=9999;
_j_s.style.padding="10px";_j_s.style.color="#fff";
_j_s.innerHTML = "jTrans by <a style='color:#fff; font-weight:bold;' href='http://blog.hamsworld.net'>HamsWorld</a><br><br>";
var _j_s_on = false;

//find all text nodes
var _j_elements = new Array();
_j_breakDown(document.getElementsByTagName("body")[0]);
function _j_breakDown(parent) {
	if 	(parent != undefined && 
			(parent.tagName == undefined || 
				(parent.tagName.toLowerCase() != "script" &&
					(parent.tagName.toLowerCase() != "input" || parent.type.toLowerCase() == "button" || parent.type.toLowerCase() == "submit")
				)
			)
		) {
		
		var hasChild = false;
		
		if (parent.childNodes != undefined && parent.childNodes.length > 0) {
			hasChild = true;
			for (var i = 0; i < parent.childNodes.length; i++) {
				_j_breakDown(parent.childNodes[i]);
			}
		}
		if (parent.attributes != null && parent.attributes.length > 0) {
			hasChild = true;
			for (var i = 0; i < parent.attributes.length; i++) {
				if (parent.attributes[i].nodeName.toLowerCase() == 'value') {
					_j_breakDown(parent.attributes[i]);
				}
			}
		} 
		if (parent.nodeType == Node.TEXT_NODE && !hasChild) {
			_j_elements[_j_elements.length] = parent;
		}
	}
}

//preapere nodes for google translator
_j_preapere();
function _j_preapere() {
	var send = "", points = "";
	for (var i = 0; i < _j_elements.length; i++) {
		var txt = _j_encodeTxt(_j_elements[i].nodeValue);
		if (txt.match(/([^\%]{2}|^)[a-zA-Z]/)) {
			var space = 0;
			if (txt.substring(txt.length - 3, txt.length) == "%20") {
				space += 1;
			} 
			if (txt.substring(0, 3) == "%20"){
				space += 2;
			} 
			var pointsTemp = i + "_" + space + ".";	
			var sendTemp = "&q=" + txt;
			
			if (send.length + points.length + sendTemp.length + pointsTemp.length > 1900) {
				_j_transfer(send, points);
				send = "";
				points = "";
			}
			
			points += pointsTemp;
			send += sendTemp;
			
		}

	}
	if (send.length > 0) {
		_j_transfer(send, points);
	}
}

//send to google
function _j_transfer(send, points, ln) {
	if (ln == undefined) ln = "";
	
	send += "&q=_";
	
	var url = 'http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&langpair=' + ln + '%7Cen&callback=read&context='+points + send;
	
	trans=document.createElement('SCRIPT');
	trans.type='text/javascript';
	trans.src= url;
	document.getElementsByTagName('head')[0].appendChild(trans);
}

//callback from translation
function read(cont, result, status, error) {
	var langs = new Array();
	var missed = new Array();
	
	var points = cont.split(".");
	
	if (status == 200 || status == 206) {			//ok or some errors
		for (var i = 0; i < result.length - 1; i++) {
			if (result[i]["responseStatus"] == 200) {
				
				//add language
				var lan = result[i]["responseData"]["detectedSourceLanguage"];			
				if (lan != undefined) {	
					if (langs[lan] == null) {
						langs[lan] = 1;
					} else {
						langs[lan]++;
					}
				}
				var p = points[i].split("_");
				var str = _j_convertEntities(result[i]["responseData"]["translatedText"]);
				if (str.length > 15 || lan == undefined) {		//string long enough or language is predefined
					if (p[1] == 1 || p[1] == 3) {		//space on the right or on both sides
						str += " ";
					}
					if (p[1] == 2 || p[1] == 3) {		//left or both
						str = " " + str;
					}
					_j_elements[p[0]].nodeValue = str;		//add translated string
				} else {
					missed[missed.length] = points[i];
				}
			} else {
				if (result[i]["responseStatus"] == 400) {	//lang detection	
					missed[missed.length] = points[i];
				} else {
					_j_msg("Error: " + result[i]["responseDetails"]);
				}
			}
		}
	} else {
		_j_msg("Big Error: " + status + " " + error);
	}
	if (missed.length > 0) {
		_j_missedLang(langs, missed);
	}
}

//do something with untranslated(couldn't detect language) nodes
function _j_missedLang(langs, missed) {
	var max = 0;
	var maxLang = "0";
	for (var lang in langs) {
		if (langs[lang] > max && lang.match(/^[a-z]{2}$/) && lang != "en") {
			max = langs[lang];
			maxLang = lang; 
		}
	}
	if (maxLang != "0") {
		var send = "";
		var points = "";
		for (var i = 0; i < missed.length; i++) {
			var p = missed[i].split("_");
			send += "&q=" + _j_encodeTxt(_j_elements[p[0]].nodeValue);
			points += missed[i] + ".";
		}
		_j_transfer(send, points, maxLang);
	}
}

//parse special chars
function _j_convertEntities( text ) {		//TODO something better
    var ret = text.replace( /\&\#(\d+);/g, function ( ent, cap ) {
		const num = parseInt( cap );
		return String.fromCharCode( num );
    });
	
    ret = ret.replace( /\&(\S+);/g, function ( ent, cap ) {
    	if (cap == "quot") cap = "\"";
    	else if (cap == "amp") cap = "&";
    	else if (cap == "lt") cap = "<";
    	else if (cap == "gt") cap = ">";
		else {
			//_j_msg("No char for: " + cap);
			cap = "?";		
		}
        return cap;
    });
    return ret;
}

function _j_encodeTxt(txt) {
	txt = txt.replace(/ +/g, " ");
	txt = txt.replace(/[\t\n\r]/g, "");
	txt = encodeURIComponent(txt);
	return txt;
}


function _j_msg(msg) {
	_j_s.innerHTML += msg + "<br>";
	if (!_j_s_on) {
		document.getElementsByTagName('body')[0].appendChild(_j_s);
		_j_s_on = true;
		setTimeout(function() {document.getElementsByTagName('body')[0].removeChild(_j_s);}, 5000);
	}
}


