//get ms translator token onload
$(document).ready(
function(e)
{
	window.external.GetMSTranslatorToken('','','');
}
);


/********skin********/
function UpdateSkinForPage(model, color, image)
{
    $("link#_NewSkinModel").attr("href", "").attr("href", "../../../skin/Model/" + model + "/BingDictDlg/TranslateResultOnline.css");
}

var rawResponseText='';
function translateTxt(from,to,text) 
{
	if (/*(from==''&&to=='en'&&text.IsChinese()) ||*/ (from=='zh-CHS'&&to=='en') || (from=='en'&&to=='zh-CHS'))
	{
		window.external.AddToLog('DoTranslate:BingApiTranslate;From:'+from+';To:'+to+';');
		translateTxt_ECCE(from,to,text);
	}
	else 
	{	
		window.external.AddToLog('DoTranslate:MSTranslatorApiTranslate;From:'+from+';To:'+to+';');
		translateTxt_All(from,to,text);
	}
}

//get the IE version
var ie = function()
{ 
    var undef, 
        v = 3,
        div = document.createElement('div'),
        all = div.getElementsByTagName('i');
    while ( 
        div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->', 
        all[0]
    );
    return v > 4 ? v : false;
} ();

function translateTxt_All(from, to , text)
{
    window.external.GetMSTranslatorToken(from, to, text);
}

function translateTxt_All_Callback(from,to,text,accessToken)
{
	var rawText = preprocessText1(text);
	var preprocessedText = preprocessText2(rawText);

	var xmlhttp;
	try
	{
		if (window.XMLHttpRequest)
		{
			//code for IE7+, Firefox, Chrome, Opera, Safari
			xmlhttp = new XMLHttpRequest();
		}
		else if (window.ActiveXObject)
		{
			//code for IE5, IE6
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	catch(e)
	{
		//FAIL: on creating xmlHttpRequest
		window.parent.TranslateTimeout();
		return;
	}

	var txt='';
	if (ie<=6)
	{
		txt=preprocessedText.substring(0,1800)
	}
	else 
	{
		txt=preprocessedText.substring(0,4800);
	}
	var url = 'http://api.microsofttranslator.com/v2/ajax.svc/TranslateArray2?oncomplete=_mstc6&onerror=_mste6&ctr=&ref=WidgetV2&rgp=12ea2632&loc=zh-chs&appId=&from=%22'+from+'%22&to=%22'+to+'%22&texts=[%22'+txt+'%22]';

	
	if (ie<=6)
	{
		xmlhttp.open("GET",url,true);
	}
	else
	{
		xmlhttp.open("POST",url,true); 
	}
	xmlhttp.setRequestHeader('Authorization',accessToken);
	xmlhttp.onreadystatechange = function()
	{
		if (xmlhttp.readyState == 4)
		{
			if (xmlhttp.status == 200)
			{
				rawResponseText = xmlhttp.responseText; //store the raw reponseText for futrue use.
				var resTxt = xmlhttp.responseText;

				//the result is not valid for parse
				if (resTxt.indexOf('{') == -1 || resTxt.lastIndexOf('}') == -1 
				|| resTxt.indexOf('[') == -1  || resTxt.indexOf(']') == -1 )
				{
					return;
				}

				var newTxt = resTxt.substring(resTxt.indexOf('['),resTxt.lastIndexOf(']')+1);
				var resultObj = eval('(' + newTxt + ')');
				processTranslateData(from,to,rawText,resultObj);
			}
			else
			{
				//FAIL: on getting server response
				window.parent.TranslateTimeout();
				return;
			}
		}
	}
	xmlhttp.send();
}

function preprocessText1(text)
{
	text = text.Trim().replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\s*\n+\s*/g, '","').replace(/\s+/g, ' ');
	return text;
}

function preprocessText2(text)
{
	text = encodeURIComponent(text).replace(/%20/g, '+').replace(/%2C/g, ',');
	return text;
}

//how to postprocess the data we get from the mstranslator
function processTranslateData(from,to,rawText,resultObj)
{
	if (typeof resultObj != 'object' || resultObj.length <=0)
	{
		return;
	}

	rawText=rawText.replace(/\\\"/g, '\"').replace(/\\\\/g, '\\');

	//get originalTexts and translatedTexts
	var originalTexts = rawText.split('","');
	var translatedTexts = new Object();
	var rawTranslatedTxt='';
	$(resultObj).each(function(k, paraObj) 
	{
		translatedTexts[k] = paraObj['TranslatedText'];
		rawTranslatedTxt += paraObj['TranslatedText'] + '\n';
	});
	if (rawTranslatedTxt.lastIndexOf('\n')>=0)
	{
		rawTranslatedTxt=rawTranslatedTxt.substring(0,rawTranslatedTxt.lastIndexOf('\n'));
	}
	
	//parse formated info
	var formatedOrigins = new Object();
	var formatedTranslates = new Object();
	$(resultObj).each(function(k, paraObj) 
	{
		//parse aligment
		if (paraObj["Alignment"])
		{
			formatedOrigins[k] = new Object();
			formatedTranslates[k] = new Object();
			var alignmentPairs = paraObj["Alignment"].split(' ');
			$(alignmentPairs).each(function(i, alignPair) 
			{
				var alignRanges = alignPair.split('-'); 
				var originBounds = alignRanges[0].split(':');
				var translatedBounds = alignRanges[1].split(':');
				
				var rand = Math.ceil((Math.random()*1000000)).toString();
				var beforeOrigin = '<div class=\"alignment origin classid'+rand+'\">';
				var beforeTranslated = '<div class=\"alignment translated classid'+rand+'\">';
				var after = '</div>';
				
				formatedOrigins[k][parseInt(originBounds[0])] = 
				{
					"lowerBound":parseInt(originBounds[0]),
					"upperBound":parseInt(originBounds[1]),
					"alignHtml":beforeOrigin + (originalTexts[k].substring(parseInt(originBounds[0]),parseInt(originBounds[1])+1)).ToHtmlEncode() + after
				};
				
				formatedTranslates[k][parseInt(translatedBounds[0])] = 
				{
					"lowerBound":parseInt(translatedBounds[0]),
					"upperBound":parseInt(translatedBounds[1]),
					"alignHtml": beforeTranslated + (translatedTexts[k].substring(parseInt(translatedBounds[0]), parseInt(translatedBounds[1]) + 1)).ToHtmlEncode() + after
				};
				
			});
			
		}
		
    });
	
	//get result string
	var resultString = '';
	$(resultObj).each(function(k, paraObj) 
	{
		var bound1=0,bound2=0;
		var oriLine='',transLine='';
		
		//if there's no aligment
		if (!formatedOrigins[k] || !formatedTranslates[k])
		{
			var rand = Math.ceil((Math.random()*1000000)).toString();
			var beforeOrigin = '<div class=\"unalignment origin classid'+rand+'\">';
			var beforeTranslated = '<div class=\"unalignment translated classid'+rand+'\">';
			var after = '</div>';
			
			oriLine += beforeOrigin + (originalTexts[k]).ToHtmlEncode() + after;
			transLine += beforeTranslated + (translatedTexts[k]).ToHtmlEncode() + after;
			resultString += '<div class="originLine">' + oriLine + '</div>' + '<div class="transaltedLine">' + transLine + '</div>';
			return true;//continue the 'each' loop
		}

		
		//there are alignments
		//1.there's unalignment before first alignment
		while (!formatedOrigins[k][bound1] && bound1 < originalTexts[k].length-1)
		{
			bound1++;
		}


		if (bound1!=0)
		{
		    oriLine += '<div class="unalignment origin">' + (originalTexts[k].substring(0, bound1)).ToHtmlEncode() + '</div>';
		} 

		//2.process first aligment and afterwards
		while (1) 
		{
			//add this alignment
			oriLine += formatedOrigins[k][bound1]['alignHtml'];
			
			//find next aligment
			var i=1;
			var oldBound=bound1;
			while (formatedOrigins[k][bound1]['upperBound']+i <= originalTexts[k].length-1)
			{
				if (formatedOrigins[k][formatedOrigins[k][bound1]['upperBound']+i])
				{
					bound1 = formatedOrigins[k][bound1]['upperBound']+i;//next alignment found
					break;
				}
				else
				{
					i++;
				}
			}
			
			//if there's unalignment between this alignment and next alignment,add the unalignment
			if (formatedOrigins[k][bound1] && bound1!= oldBound)
			{
				if (formatedOrigins[k][oldBound]['upperBound']!=bound1)
				{
				    oriLine += '<div class="unalignment origin">' + (originalTexts[k].substring(formatedOrigins[k][oldBound]['upperBound'] + 1, bound1)).ToHtmlEncode() + '</div>';
				}

				continue;
			}
			else 
			{
				oriLine += '<div class="unalignment origin">' + (originalTexts[k].substring(formatedOrigins[k][oldBound]['upperBound'] + 1, originalTexts[k].length)).ToHtmlEncode() + '</div>';

				break;
			}
		}

		//there are alignments
		//1.there's unalignment before first alignment
		while (!formatedTranslates[k][bound2] && bound2 < translatedTexts[k].length-1)
		{
			bound2++;
		}
		if (bound2!=0)
		{
		    transLine += '<div class="unalignment translated">' + (translatedTexts[k].substring(0, bound2)).ToHtmlEncode() + '</div>';
		}
		//2.process first aligment and afterwards
		while (1) 
		{		
			//add this alignment
			transLine += formatedTranslates[k][bound2]['alignHtml'];
			
			//find next aligment
			var i=1;
			var oldBound=bound2;
			while (formatedTranslates[k][bound2]['upperBound']+i <= translatedTexts[k].length-1)
			{
				if (formatedTranslates[k][formatedTranslates[k][bound2]['upperBound']+i])
				{
					bound2 = formatedTranslates[k][bound2]['upperBound']+i;
					
					break;
				}
				else
				{
					i++;
				}
			}

			//if there's unalignment between this alignment and next alignment,add the unalignment
			if (formatedTranslates[k][bound2] && bound2!= oldBound)
			{
				
				if (formatedTranslates[k][oldBound]['upperBound']!=bound2)
				{
				    transLine += '<div class="unalignment translated">' + (translatedTexts[k].substring(formatedTranslates[k][oldBound]['upperBound'] + 1, bound2)).ToHtmlEncode() + '</div>';
				}
				continue;
			}
			else
			{
				transLine += '<div class="unalignment translated">' + (translatedTexts[k].substring(formatedTranslates[k][oldBound]['upperBound'] + 1, translatedTexts[k].length)).ToHtmlEncode() + '</div>';
				break;
			}
		}
		resultString += '<div class="originLine">' + oriLine + '</div>' + '<div class="transaltedLine">' + transLine + '</div>';
	});

	$('#result').html(resultString);

	$('.alignment').bind(
	{	
		'mouseover':function()
		{
			var classNames=$(this).attr('class').Trim().replace(/\s+/,' ').split(' ');
			if (classNames)
			{
				$(classNames).each(function(index, className) {
					if (className.indexOf('classid')!=-1)
					{
						$('.'+className).addClass('hovered press_ba');
					}
				});
			}
		},
		'mouseout':function()
		{
			$('.alignment').removeClass('hovered press_ba');
		},
		'click':function()
		{
			window.external.SearchOnline($(this).html().ToHtmlDecode());
		}
		
	});
	
	if (from=='ar'||from=='fa'||from=='he')
	{
		$('.originLine').attr('dir','rtl');
	}
	if (to=='ar'||to=='fa'||to=='he')
	{
		$('.transaltedLine').attr('dir','rtl');
	}
	
	//notify the main window
	window.external.StoreTranslatedText(rawTranslatedTxt);
	window.external.OnlineLoadSuccess('TranslateResult');
}


//--------------------------------------------------------------------
//EC/CE translation: we will use bing translation api to do EC/CE translation

function translateTxt_ECCE(from,to,text)
{
	var rawText = text;
	var preprocessedText = encodeURIComponent(rawText);

	var xmlhttp;
	try
	{
		if (window.XMLHttpRequest)
		{
			//code for IE7+, Firefox, Chrome, Opera, Safari
			xmlhttp = new XMLHttpRequest();
		}
		else if (window.ActiveXObject)
		{
			//code for IE5, IE6
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	catch(e)
	{
		//FAIL: on creating xmlHttpRequest
		window.parent.TranslateTimeout();
		return;
	}

	var FromStr = from=='en' ? 'en-us' : 'zh-cn';
	var ToStr = from=='en' ? 'zh-cn' : 'en-us';
	var url = 'http://dict.bing.com.cn/api/http/v2/0003462a56234cee982be652b8ea1e5f/' + FromStr+'/' + ToStr + '/translation/?format=application/json&ts=' + (new Date()).getTime() + '&q=' + preprocessedText.substring(0,1800);

	xmlhttp.open("GET",url,true); 
	xmlhttp.onreadystatechange = function()
	{
		if (xmlhttp.readyState == 4)
		{
			if (xmlhttp.status == 200)
			{
				rawResponseText = xmlhttp.responseText; //store the raw reponseText for futrue use.
				var resTxt = xmlhttp.responseText;
				
				//the result is not valid for parse
				if (resTxt.indexOf('{') == -1 || resTxt.lastIndexOf('}') == -1)
				{
					return;
				}

				var newTxt = resTxt;
				var resultObj = eval('(' + newTxt + ')');
				processTranslateData_ECCE(from,to,rawText,resultObj);
			}
			else
			{
				//FAIL: on getting server response
				window.parent.TranslateTimeout();
				return;
			}
		}
	}
	xmlhttp.send();

}

function processTranslateData_ECCE(from,to,rawText,resultObj)
{
	if (typeof resultObj != 'object' || resultObj.length <=0)
	{
		return;
	}
	
	var WACount=0;//word aligments count
	if (resultObj["MT"]!=null && resultObj["MT"]["WA"]!=null)
	{
		WACount=resultObj["MT"]["WA"];
	}
	else
	{
		var resultString = '<div class="originLine"><div class="unalignment origin">' + rawText.ToHtmlEncode() + '</div></div>' + '<div class="transaltedLine"><div class="unalignment translated">' + rawText.ToHtmlEncode() + '</div></div>';
		$('#result').html(resultString);
		window.external.StoreTranslatedText(rawText);
		window.external.OnlineLoadSuccess('TranslateResult');
		return;
	}
	
	var source=resultObj["MT"]["S"];
	var target=resultObj["MT"]["T"];
	
	var tmp;
	tmp = source;
	var sourceWAItems = new Object();
	for (var i=1,start=0;i<=WACount;i++)
	{
		var WAItemStart=tmp.indexOf('{'+i+'#');
		var WAItemEnd=tmp.indexOf('$'+i+'}');
		
		var WAText=tmp.substring(WAItemStart,WAItemEnd);
		WAText=WAText.substring(WAText.indexOf('#')+1)
		
		var WAItem = new Object();;
		WAItem["WAItemStart"]=WAItemStart;
		WAItem["WAItemEnd"]=WAItemEnd;
		WAItem["AlignText"]=WAText;
		WAItem["AlignId"]=i;
		sourceWAItems[i]=WAItem;
	}
	//sort sourceWAItems in the order of raw string
	quickSortWAItems(sourceWAItems,1,WACount);
	
	tmp = target;
	var targetWAItems = new Object();
	for (var i=1,start=0;i<=WACount;i++)
	{
		var WAItemStart=tmp.indexOf('{'+i+'#');
		var WAItemEnd=tmp.indexOf('$'+i+'}');
		
		var WAText=tmp.substring(WAItemStart,WAItemEnd);
		WAText=WAText.substring(WAText.indexOf('#')+1)
		
		var WAItem = new Object();;
		WAItem["WAItemStart"]=WAItemStart;
		WAItem["WAItemEnd"]=WAItemEnd;
		WAItem["AlignText"]=WAText;
		WAItem["AlignId"]=i;
		targetWAItems[i]=WAItem;
	}
	//sort targetWAItems in the order of raw string
	quickSortWAItems(targetWAItems,1,WACount);
	
	//get resultString
	var oriLine='',transLine='',rawTranslatedTxt='',unalignBefore='',unalignAfter='';
	var unalignStart;
	
	//get original line
	for (var i=1,unalignStart=0;i<=WACount;i++)
	{
		unalignBefore = source.substring(unalignStart,sourceWAItems[i]["WAItemStart"]);
		
		if (unalignBefore.length>0)
		{
		    oriLine += '<div class="unalignment origin">' + (unalignBefore).ToHtmlEncode() + '</div>';
		}
		unalignStart=source.indexOf('}',sourceWAItems[i]["WAItemEnd"])+1;
		
		oriLine += '<div class="alignment origin classid' + sourceWAItems[i]["AlignId"] + '">' + (sourceWAItems[i]["AlignText"]).ToHtmlEncode() + '</div>';
	}
	unalignAfter = source.substring(unalignStart);
	if (unalignAfter.length>0)
	{
	    oriLine += '<div class="unalignment origin">' + (unalignAfter).ToHtmlEncode() + '</div>';
	}

	//get translated line
	for (var i=1,unalignStart=0;i<=WACount;i++)
	{
		unalignBefore = target.substring(unalignStart,targetWAItems[i]["WAItemStart"]);
		if (unalignBefore.length>0)
		{
		    transLine += '<div class="unalignment translated">' + (unalignBefore).ToHtmlEncode() + '</div>';
			rawTranslatedTxt+=unalignBefore;
		}
		unalignStart=target.indexOf('}',targetWAItems[i]["WAItemEnd"])+1;
		
		transLine += '<div class="alignment translated classid' + targetWAItems[i]["AlignId"] + '">' + (targetWAItems[i]["AlignText"]).ToHtmlEncode() + '</div>';
		rawTranslatedTxt+=targetWAItems[i]["AlignText"];
	}
	unalignAfter = target.substring(unalignStart);
	if (unalignAfter.length>0)
	{
	    transLine += '<div class="unalignment translated">' + (unalignAfter).ToHtmlEncode() + '</div>';
		rawTranslatedTxt+=unalignAfter;
	}
	
	//get result string
	var resultString = '<div class="originLine">' + oriLine + '</div>' + '<div class="transaltedLine">' + transLine + '</div>';
	
	$('#result').html(resultString);
	
	$('.alignment').bind(
	{	
		'mouseover':function()
		{
			var classNames=$(this).attr('class').Trim().replace(/\s+/,' ').split(' ');
			if (classNames)
			{
				$(classNames).each(function(index, className) {
					if (className.indexOf('classid')!=-1)
					{
						$('.'+className).addClass('hovered press_ba');
					}
				});
			}
		},
		'mouseout':function()
		{
			$('.alignment').removeClass('hovered press_ba');
		},
		'click':function()
		{
			window.external.SearchOnline($(this).html().ToHtmlDecode());
		}
		
	});
	
	if (from=='ar'||from=='fa'||from=='he')
	{
		$('.originLine').attr('dir','rtl');
	}
	if (to=='ar'||to=='fa'||to=='he')
	{
		$('.transaltedLine').attr('dir','rtl');
	}
	
	//notify the main window
	window.external.StoreTranslatedText(rawTranslatedTxt);
	window.external.OnlineLoadSuccess('TranslateResult');
}

function quickSortWAItems(s,l,r)
{
	if (l < r)
    {
        //swap(s[l], s[(l + r) / 2]);
        var i = l, j = r, x = s[l];
        while (i < j)
        {
            while (i < j && s[j]["WAItemStart"] >= x["WAItemStart"]) //find first number < x from right to left 
            	j--; 
            if (i < j)
            	s[i++] = s[j];
                    
            while (i < j && s[i]["WAItemStart"] < x["WAItemStart"]) //find first number > x from left to right 
            	i++; 
            if (i < j)
            	s[j--] = s[i];
        }
        s[i] = x;
        quickSortWAItems(s, l, i - 1); //recursive call 
        quickSortWAItems(s, i + 1, r);
    }
}

//---------------------------------------------------------------------
//lexiconTxt_ECCE
function lexiconTxt_ECCE(from,to,text)
{
	var rawText = text;
	var preprocessedText = encodeURIComponent(rawText);

	var xmlhttp;
	try
	{
		if (window.XMLHttpRequest)
		{
			//code for IE7+, Firefox, Chrome, Opera, Safari
			xmlhttp = new XMLHttpRequest();
		}
		else if (window.ActiveXObject)
		{
			//code for IE5, IE6
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	catch(e)
	{
		//FAIL: on creating xmlHttpRequest
		window.parent.TranslateTimeout();
		return;
	}

	var FromStr = from == 'en' ? 'en-us' : 'zh-cn';
	var ToStr = from == 'en' ? 'zh-cn' : 'en-us';
	var url = 'http://dict.bing.com.cn/api/http/v2/0003462a56234cee982be652b8ea1e5f/' + FromStr + '/' + ToStr + '/lexicon/?format=application/json&ts=' + (new Date()).getTime() + '&q=' + preprocessedText;

	xmlhttp.open("GET",url,true); 
	xmlhttp.onreadystatechange = function()
	{
		if (xmlhttp.readyState == 4)
		{
			if (xmlhttp.status == 200)
			{
				rawResponseText = xmlhttp.responseText; //store the raw reponseText for futrue use.
				var resTxt = xmlhttp.responseText;
				
				//the result is not valid for parse
				if (resTxt.indexOf('{') == -1 || resTxt.lastIndexOf('}') == -1)
				{
					return;
				}

				var newTxt = resTxt;
				var resultObj = eval('(' + newTxt + ')');
				processLexiconData_ECCE(from,to,rawText,resultObj);
			}
			else
			{
				//FAIL: on getting server response
				window.parent.TranslateTimeout();
				return;
			}
		}
	}
	xmlhttp.send();
}


function processLexiconData_ECCE(from,to,rawText,resultObj)
{
	if (typeof resultObj != 'object' || resultObj.length <=0)
	{
		return;
	}
	
	var CrossLangDef = resultObj["LEX"]["C_DEF"];
	for (var i=0;i<CrossLangDef.length;i++)
	{
		//TODO:
	}
	
	
	$('.alignment').bind(
	{	
		'mouseover':function()
		{
			var classNames=$(this).attr('class').Trim().replace(/\s+/,' ').split(' ');
			if (classNames)
			{
				$(classNames).each(function(index, className) {
					if (className.indexOf('classid')!=-1)
					{
						$('.'+className).addClass('hovered press_ba');
					}
				});
			}
		},
		'mouseout':function()
		{
			$('.alignment').removeClass('hovered press_ba');
		},
		'click':function()
		{
			window.external.SearchOnline($(this).html().ToHtmlDecode());
		}
		
	});
	
	
	//notify the main window
	window.external.StoreTranslatedText(rawTranslatedTxt);
	window.external.OnlineLoadSuccess('TranslateResult');
}






