// MattC 19-Mar-09. Globals for the translation

function $(id) { return document.getElementById(id); }

var translationsArray = new Array();
var translationsPos;

/* getElementsByClass from http://www.dustindiaz.com/getelementsbyclass/
	# Supply a class name as a string.
	# (optional) Supply a node. This can be obtained by getElementById, or simply by just throwing in "document" (it will be document if don't supply a node)). It's mainly useful if you know your parent and you don't want to loop through the entire D.O.M.
	# (optional) Limit your results by adding a tagName. Very useful when you're toggling checkboxes and etcetera. You could just supply "input". */

function getElementsByClass(searchClass, node, tag) {
	var classElements = new Array();
	if ( node == null )
		node = document;
	if ( tag == null )
		tag = '*';
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}

// MattC 22-Apr-09. Clear a list

function pfClearList(theSel) {
	while (theSel.length > 0) {
		theSel.options[0] = null;
	}
}

// MattC 22-Apr-09. Add an option to a list

function addOption(theSel, theText, theValue) {
	var newOpt = new Option(theText, theValue);
	var selLength = theSel.length;
	theSel.options[selLength] = newOpt;
}

function pfShowReset(theSel, resetString) {
	pfClearList(theSel);
	addOption(theSel, 'Google Translate', 'NO_LOCALE');
	addOption(theSel, resetString, 'RESET');
}

// MattC 27-Mar-09. Try to work out the best place to split a string (escaped)

function pfIntelliBreak(text, cursor, tolerance) {

	// Is cursor within a HTML tag? Scan back for '<', then forward for '>'
	var htmlOpen = text.lastIndexOf('%3C', cursor);
	var htmlClose = text.indexOf('%3E', cursor);
	
	// Open character found at start, not within tolerance so force a break if we can
	if (htmlOpen == 0 && ((cursor - htmlOpen) > tolerance)) {
		var esc = text.lastIndexOf('%', cursor);
		if (esc > -1 && ((cursor - esc) <= tolerance)) {
			return esc;
		} else {
			return cursor;
		}
	}
	
	// Open character found and within tolerance
	if (htmlOpen > -1 && ((cursor - htmlOpen) <= tolerance)) {
		// Close character found and within tolerance
		if (htmlClose > -1 && ((htmlClose - cursor) <= tolerance)) {
			// We are probably within a HTML tag.. don't split if it's within tolerance
			return htmlOpen;
		}
	}
	
	// Probably not in a HTML tag, so lets find a word boundary
	var space = text.lastIndexOf('%20', cursor);
	if (space > -1 && ((cursor - space) <= tolerance)) {
		return space;
	}

	// Don't split up on an escaped character
	var esc = text.lastIndexOf('%', cursor);
	if (esc > -1 && ((cursor - esc) <= tolerance)) {
		return esc;
	}
	
	// Can't find a nice place to split, so force a break
	return cursor;
}

// MattC 27-Mar-09. Break up a string into chunks & try to break
// lines on word boundaries and without breaking HTML

function pfChunks(text, limit, tolerance) {

	var chunks = new Array();
	var cursorStart = 0;
	var cursorEnd;
	var id = '';
	
	//var debugIterator = 0;

	text = escape(text);
	
	if (text.length <= limit) {
		chunks[chunks.length] = unescape(text);
	} else {
		cursorEnd = limit;
		while (cursorEnd < text.length) {

			//if (debugIterator == 10) return chunks;
			//debugIterator += 1;
		
			cursorEnd = pfIntelliBreak(text, cursorEnd, tolerance);
			id = 'test<id=' + chunks.length + '/>';
			chunks[chunks.length] = id + unescape(text.substring(cursorStart, cursorEnd)) + '\n';
			//console.log(chunks[chunks.length-1]);
			
			cursorStart = cursorEnd;
			
			if ((cursorStart + limit) >= text.length) {
				// No more big chunks left
				cursorEnd = text.length;
				id = 'test<id=' + chunks.length + '/>';
				chunks[chunks.length] = id + unescape(text.substring(cursorStart, cursorEnd));
			} else {
				cursorEnd = cursorStart + limit;
			}
		}
	}
	
	return chunks;
}

// MattC 19-Mar-09. Perform the translations held in the array. 
// Once one translation has completed, request the next one.

function pfPerformTranslation(){

	try {
		var gtl = google.language.translate;
	} catch(e) {
		alert('The Google Translation engine hasn\'t loaded yet.');
		return false;
	}

	if(translationsArray[translationsPos]){
		// Source language ommited so that google can decide
		//console.log('Translate ' + translationsPos + 'x' + translationsArray[translationsPos].id + translationsArray[translationsPos].sourceText.substr(0, 10));
		
		//translationsPos++;
		//pfPerformTranslation();
		
		gtl(translationsArray[translationsPos].sourceText, '', translationsArray[translationsPos].destLang, function(result) {
			if (!result.error) {
				var posStart = result.translation.indexOf('<id=');
				//if (result.translation.substr(0,4)=='<id=') { // Google fault 246
				if (posStart > -1 && posStart < 50) {
					// Process multiple chunks
					var posEnd = result.translation.indexOf('/>');
					var chunkNum = result.translation.substring(posStart+4, posEnd);
					var sRegex = new RegExp('<DIV id=.?pf-' + chunkNum + '-chunk.?>' + '</DIV>', 'i');
					//alert(chunkNum + '..' + $pf(translationsArray[translationsPos].id).innerHTML + result.translation.substr(posEnd+2, 10));
					//alert(sRegex);
					//alert($pf(translationsArray[translationsPos].id).innerHTML);
					$(translationsArray[translationsPos].id).innerHTML = $(translationsArray[translationsPos].id).innerHTML.replace(sRegex, result.translation.substr(posEnd+2));
				} else {
					// Single chunk
					$(translationsArray[translationsPos].id).innerHTML = result.translation;
				}
				translationsPos++;
				pfPerformTranslation();
			} else {
				$(translationsArray[translationsPos].id).innerHTML = '<div id="pf-translation-error">' + result.error.message + '</div> ' + $(translationsArray[translationsPos].id).innerHTML;
				translationsPos++;
				pfPerformTranslation();
			}
		});
	}
}

// MattC 19-Mar-09. Populate the array that will be recursed over
// to perform the translation.

function pfTranslatePage(destLang) {

	if (destLang=='RESET') {
		window.location.reload(true);
		return;
	}
	
	sourceLang = '';
	
	// Get all list items which use the certain classes
	var lists = getElementsByClass('(content|sidebar)');
	for (var i = 0; i < lists.length; i++) {
		lists[i].id = 'trans-' + i;
		var chunks = pfChunks(lists[i].innerHTML, 1750, 250);
		var chunky = '';
		//console.log(' Chunk length = ' + chunks.length);
		for (var j = 0; j < chunks.length; j++) {
			translationsArray[translationsArray.length] = { sourceLang: sourceLang, destLang: destLang, sourceText: chunks[j], destText: '', id: lists[i].id };
			chunky = chunky + '<DIV id="pf-' + j + '-chunk"></DIV>';
		}
		if (chunks.length > 1) {
			lists[i].innerHTML = chunky;
			//alert(chunky);
			//alert(lists[i].innerHTML);
		}
	}
	
	translationsPos=0;
	pfPerformTranslation();
}