// cometbird_translate.js
var xrequest = null;
var isAbort = false;

var cometbirdTranslate =
{
    _wherex                	: 0,
    _wherey                	: 0,
	_move_time				: 0,
	_display_time			: 0,
	
	_timer                	: null,
	_display_timer			: null,
	_delay_timer			: null,
	
	_range					: null,
	_rangeParent			: null,
	_rangeStart				: null,
	_rangeEnd				: null,
	
	_translate_word			: "",
	_selection_word			: "",
	_is_selected_translate	: false,
	_selection_word_need_translate : false,
	_result_array			: [],
	
	_selection_minX			: 0,
	_selection_maxX			: 0,
	_selection_minY			: 0,
	_selection_maxY			: 0,
	
	_selection_endX			: 0,
	_selection_endY			: 0,
	
	_selection_show			: false,
	_selection_seg			: false,
	_selection_left2right	: true,
	
	_has_popup				: false,
	
	_num					: 1,
	_show_timer				: null,
	
    init : function()
    {
		// init home lang
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
		prefs.setCharPref( "browser.enhancement.google.translate.home_lang", prefs.getCharPref("general.useragent.locale") );
    },
	
	statusbarToggle : function( event )
	{
		if ( event.button != 0 )// not left button
			return;
			
		if ( event.target.id != "cometbird_statusbarpanel" && event.target.id != "translate_select_image" && event.target.id != "translate_select_error_image" )
			return;
		
		// open error url
		if ( document.getElementById("translate_select_error_image").getAttribute("hidden") == "false" )
		{
			var error_url = "http://www.google.com/sorry/";
			CometBirdUtility.openURL( error_url );
			
			window.clearInterval(cometbirdTranslate._show_timer);
			cometbirdTranslate._show_timer = null;
			document.getElementById("translate_select_error_image").setAttribute("hidden", "true");
			return;
		}
		
		this.toggle( event );
	},
   
    toggle : function( event )
    {
        if ( event.target.id != "cometbird-translate-button" && event.target.id != "cometbird-translate-toggle" 
			&& event.target.id != "cometbird_statusbarpanel" && event.target.id != "translate_select_image" 
			&& event.target.id != "cometbird-translate-statusbar-toggle" )
            return;
       
        var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
        var is_enable_tranlate = prefs.getBoolPref("browser.enhancement.google.translate.enable");
       
        is_enable_tranlate = ( !is_enable_tranlate );
        prefs.setBoolPref("browser.enhancement.google.translate.enable", is_enable_tranlate );
		
		// notify to update ui	
		var bserverService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
		bserverService.notifyObservers( null, CometBirdTranslateSettingDefine.changed_event, null );
    },
	
	showErrorPic : function()
	{
		if ( cometbirdTranslate._num == 1 )// show second
		{
			document.getElementById("translate_select_error_image").setAttribute("src", "chrome://cometbird/skin/translator_error_replace.png");
			cometbirdTranslate._num++;
			return;
		}
		
		// show first 
		document.getElementById("translate_select_error_image").setAttribute("src", "chrome://cometbird/skin/translator_error.png");
		cometbirdTranslate._num = 1;
	},
	
    translate : function( translate_text )
    {
    try{	
		// cancel current http
		if ( xrequest != null )
		{
			isAbort = true;
			xrequest = null;
		}
		
		// new http object
        xrequest = new XMLHttpRequest();
		isAbort = false;
        xrequest.onreadystatechange = function()
        {       
			//CometBirdFile.writeLog("state: " + xrequest.readyState);
			if ( xrequest.readyState > 1 && isAbort )// has send
			{
				xrequest.abort();
				return;
			}
			
            if ( xrequest.readyState == 4 || xrequest.readyState == "complete" )
            {
				// clear old data
				while ( cometbirdTranslate._result_array.length > 0 )
					cometbirdTranslate._result_array.pop();
			
				try
				{
					var json_obj = eval('(' + xrequest.responseText + ')'); 
				}
				catch(e)
				{
					// error
					if ( xrequest.responseText.substr(0,16) == '<html DIR="LTR">' ) // begin with: <html DIR="LTR"><head>...
					{
						if( cometbirdTranslate._show_timer != null )
							return;
							
						document.getElementById("translate_select_error_image").setAttribute("hidden", "false");
						cometbirdTranslate._num = 1;
						document.getElementById("translate_select_error_image").setAttribute("src", "chrome://cometbird/skin/translator_error.png");
						cometbirdTranslate._show_timer = window.setInterval( "cometbirdTranslate.showErrorPic()",500 );
						return;
					}
				}
			
				/*
				// new json-string format
				{
				"sentences":
					[{"trans":"值","orig":"value","translit":"zhí"}],
					
				"dict":
					[
						{"pos":"noun","terms":["定值","音值","值","价","价格","价钱","价值"]},
						{"pos":"verb","terms":["鉴赏","臧否","宝贵","重视","珍视","尊重","看重","珍重","尚","推崇","翊"]}
					],
					
				"src":"en"
				}
				
				// multi-sentences
				{
				"sentences":
					[
						{"trans":"存储在缓存中所确定的价值的关键。","orig":"Stores a value identified by a key in cache.","translit":"cún chú zài huǎn cún zhōng suǒ què dìng de jià zhí de guān jiàn。"},
						{"trans":"此方法应实施的子类来存储特定的缓存中存储的数据。","orig":"This method should be implemented by child classes to store the data in specific cache storage.","translit":"cǐ fāng fǎ yīng shí shī de zi lèi lái cún chú tè dìng de huǎn cún zhōng cún chú de shù jù。"},
						{"trans":"的独特性和依赖性均以集（）了。","orig":"The uniqueness and dependency are handled in set() already.","translit":"de dú tè xìng hé yī lài xìng jūn yǐ jí（） le。"},
						{"trans":"因此，只有实现数据存储的需要。","orig":"So only the implementation of data storage is needed.","translit":"yīn cǐ， zhǐ yǒu shí xiàn shù jù cún chú de xū yào。"}
					],
				"src":"en"
				}
				*/
				
				/* new json-string format 2010-07-27
				zh_cn to en_us
				[[["Please enter text","请输入文字",""]],,"zh-CN"]
				
				en_us to zh_cn
				[[["何时","When","Hé shí"]],[["名词",["日子"]],["副词",["何时","几时","曷","洎"]],["连词",["于","等"]],["叹词",["几时"]]],"en"]
				
				// multi-sentences
				[
					[
						["很抱歉，但函数beginform是不是在网上手册。","Sorry, but the function beginform is not in the online manual.","Hěn bàoqiàn, dàn hánshù beginform shì bùshì zài wǎngshàng shǒucè."],
						["也许你拼写错误，或者它是一个相对较新的功能，却没有到在线文档它。","Perhaps you misspelled it, or it is a relatively new function that hasn't made it into the online documentation yet.","Yěxǔ nǐ pīnxiě cuòwù, huòzhě tā shì yīgè xiāngduì jiào xīn de gōngnéng, què méiyǒu dào zàixiàn wéndàng tā."],
						["以下是20个职能似乎在拼写beginform（真的好大胆的比赛中最接近）。","The following are the 20 functions which seem to be closest in spelling to beginform (really good matches are in bold).","Yǐxià shì 20 gè zhínéng sìhū zài pīnxiě beginform(zhēn de hào dàdǎn de bǐsài zhōng zuì jiējìn)."],
						["也许你要找的其中之一：","Perhaps you were looking for one of these:","Yěxǔ nǐ yào zhǎo de qízhōng zhī yī:"]
					]
					,
					,
					"en"
				]
				*/
				
				// json_obj[1] is undefined: only one meaning
				if ( json_obj[1] == undefined )
				{
					cometbirdTranslate_selection_seg = true;
					
					var str_translate_result = "";
					for ( var i=0; i<json_obj[0].length; i++)
					{	
						//CometBirdFile.writeLog( json_obj[0][i][0] );
						str_translate_result += json_obj[0][i][0];
					}
					
					// display result
					cometbirdTranslate._result_array.push( str_translate_result );
					cometbirdTranslate.displayResult( translate_text );
					return;
				}
					
				// json_obj[1] is array: more than one meaning
				cometbirdTranslate_selection_seg = false;
				for ( var i=0; i<json_obj[1].length; i++ )
				{	
					//CometBirdFile.writeLog( json_obj[1][i][1] );
					cometbirdTranslate._result_array.push( json_obj[1][i][1] );// each POS
				}
				
				// display result
                cometbirdTranslate.displayResult( translate_text );
				return;
            }
        };
       
        var url = "";
		
		// get lang
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
		var tranlate_home_lang = prefs.getCharPref("browser.enhancement.google.translate.home_lang");
        var tranlate_from_lang = prefs.getCharPref("browser.enhancement.google.translate.from_lang");
		var tranlate_to_lang = prefs.getCharPref("browser.enhancement.google.translate.to_lang");		
		
		/*
		if ( tranlate_home_lang == "zh-CN" )
			url = "http://translate.google.cn/translate_a/t";  
		else
			url = "http://translate.google.com/translate_a/t";  
		*/
		url = "http://translate.google.com/translate_a/t";  
		// detect lang
		if ( tranlate_to_lang == "auto" )
			tranlate_to_lang = tranlate_home_lang;
        var parameters = "client=t&text="+encodeURIComponent(translate_text)+"&hl="+tranlate_home_lang+"&sl="+tranlate_from_lang+"&tl="+tranlate_to_lang;
		
		url = url + "?" + parameters;
		//CometBirdFile.writeLog( "url "+ url );
        xrequest.open( "GET", url, true );
        xrequest.send(null);
    }catch(e){CometBirdUtility.showErrorMsg("http exp: " + e);}
    },
	
	hideResultPanel : function()
	{
		// stop timer
		window.clearTimeout( cometbirdTranslate._display_timer );
		
		var panel = document.getElementById("translate-panel");
		if ( panel != null )
			panel.hidePopup();
			
		// clear old data
		while ( cometbirdTranslate._result_array.length > 0 )
			cometbirdTranslate._result_array.pop();
	},
	
	displayResult : function( translate_text )
	{
	try{
		if( cometbirdTranslate._show_timer != null )// close it if translate success
		{
			window.clearInterval(cometbirdTranslate._show_timer);
			cometbirdTranslate._show_timer = null;
			document.getElementById("translate_select_error_image").setAttribute("hidden", "true");
		}
		
		// show panel
		var panel = document.getElementById("translate-panel");
		if ( panel == null )
			return;
		
		if ( panel.state == "open" )
			return;
			
		if ( translate_text.length == 0 || cometbirdTranslate._result_array.length == 0 )	
		{
			return;
		}
		
		if ( cometbirdTranslate._has_popup )// open the popup
		{
			return;
		}
		
		if ( cometbirdTranslate._translate_word != translate_text && cometbirdTranslate._selection_word != translate_text )
		{
			return;
		}
		
		// check active window
		var active_win = cometbirdTranslate.getActiveWindow();
		if ( active_win == null )// firefox not active now
			return;

		if ( active_win.document.documentURI != "chrome://browser/content/browser.xul" )// not main browser window
			return;
			
		// clear last data
		var translate_result_box = document.getElementById("translate-result-box");
		var result_vbox = document.getElementById("result-vbox");
		if ( result_vbox != null )
			translate_result_box.removeChild( result_vbox );
		
		// sentence
		if ( cometbirdTranslate_selection_seg )
		{
			if ( translate_text.length > 50 )
			{
				var part_translate_text = translate_text.substr(0,20) + "..." + translate_text.substr(translate_text.length-20,20) + ": \n";
				document.getElementById("translate_result_label").value = part_translate_text;
			}
			else
			{
				document.getElementById("translate_result_label").value = translate_text + " \n";
			}
				
			document.getElementById("translate_result_label").value += cometbirdTranslate._result_array[0];
						
			panel.openPopupAtScreen( cometbirdTranslate._wherex, cometbirdTranslate._wherey, false );
			cometbirdTranslate._display_timer = window.setTimeout( "cometbirdTranslate.monitorHidePanel()", 6000 );
			return;
		}
		
		// dicts
		document.getElementById("translate_result_label").value = translate_text + ": " + cometbirdTranslate._result_array[0];
		// only one pos
		if ( cometbirdTranslate._result_array.length == 1 )
		{
			if ( CometBirdUtility.compareTowWord( translate_text, cometbirdTranslate._result_array[0] ) )// equal
			{
				return;
			}
			panel.openPopupAtScreen( cometbirdTranslate._wherex, cometbirdTranslate._wherey, false );
			cometbirdTranslate._display_timer = window.setTimeout( "cometbirdTranslate.monitorHidePanel()", 6000 );
		}
		
		// seconde part result
		var vbox = document.createElement("vbox");
		vbox.setAttribute( "id", "result-vbox" );
		for ( var i=1; i<cometbirdTranslate._result_array.length; i++ )
		{
			// add spacer
			var spacer = document.createElement("spacer");
			spacer.setAttribute( "height", "3" );
			vbox.appendChild( spacer );
			
			// add description
			var description = document.createElement("description");
			description.setAttribute( "style", "max-width:50em;" );
			description.setAttribute( "flex", "1" );
			
			var text_node = document.createTextNode( cometbirdTranslate._result_array[i] );
			description.appendChild( text_node );
			
			vbox.appendChild( description );
		}
		translate_result_box.appendChild( vbox );
		
		panel.openPopupAtScreen( cometbirdTranslate._wherex, cometbirdTranslate._wherey, false );
		cometbirdTranslate._display_timer = window.setTimeout( "cometbirdTranslate.monitorHidePanel()", 6000 );
		
	}catch(e){CometBirdUtility.showErrorMsg(e);}
	},
	
    getValidWord : function( range, rangeParent, rangeStart, rangeEnd )
    {
		// not document element
		if ( range == null || rangeParent == "[object Text]" || rangeParent == null )
			return "";
		
		// now find beginning and end of word
		var single_re = /\s/; // a single white space character, including space, tab, form feed, line feed
		//var symbol_re = /[\uFF00-\uFFFF]|[\u2E80-\u33FF]/i; // 所有全角符号
		//var symbol_sim_re = /[\u0021-\u002f]|[\u003a-\u003f]|[\u005b-\u0060]|[\u007b-\u007e]/i; // 所有半角符号
        var symbol_re = /[，|。|\？|！|；|：|“|”]/; // 全角 , . ? ! ; : “ ”
		var symbol_sim_re = /[,|.|\?|!|;|:|"]/; // 半角 , . ? ! ; : "
		while( typeof ( range.toString()[0] ) == "undefined" && rangeStart >= 0 
			|| (!single_re.test(range.toString()[0]) && !symbol_re.test(range.toString()[0]) && !symbol_sim_re.test(range.toString()[0]) && rangeStart >= 0) )
        {
            rangeStart--;
            if( rangeStart >= 0 )
            {
				try
				{
					range.setStart( rangeParent, rangeStart );
				}
				catch(e)
				{
					break;
				}
			}
        }
       
        // move forward one char again
        rangeStart++;
		try
		{
			range.setStart( rangeParent, rangeStart );
		}
		catch(e){}
       
        while( typeof ( range.toString().substr(-1,1) ) == "undefined" 
			|| (!single_re.test( range.toString().substr(-1,1) ) && !symbol_re.test( range.toString().substr(-1,1) ) && !symbol_sim_re.test( range.toString().substr(-1,1) ) ) )
        {
            rangeEnd++;
            try
            {
                range.setEnd( rangeParent, rangeEnd );
            }
            catch(e)
            {
                break;
            }
        }

        // move back one char again
        rangeEnd--;
        if ( rangeEnd < 0 )
            return "";
        
		try
		{
			range.setEnd( rangeParent, rangeEnd );
		}catch(e){}
		
        return range.toString();
    },
   
	checkInSelected : function( event )
	{
	try{
		if ( event.target == null )
			return false;
				
		var focusedWindow = document.commandDispatcher.focusedWindow;
		if ( !focusedWindow )
			return false;
		var selected_text = focusedWindow.getSelection().toString();

		if ( selected_text.length > 0 )
		{
			var start_offset = focusedWindow.getSelection().anchorOffset;
			var end_offset = focusedWindow.getSelection().focusOffset;
			var now_offset = event.rangeOffset;
			
			var sel_first_node = focusedWindow.getSelection().anchorNode;
			var sel_last_node = focusedWindow.getSelection().focusNode;
						
			var child_nodes = event.target.childNodes;
			for ( var i=0; i<child_nodes.length; i++ )
			{
				if ( child_nodes[i] == null || child_nodes[i].nodeName != "#text" )
				{
					continue;
				}
				
				if ( event.rangeParent.isSameNode(child_nodes[i]) )// current node
				{
					// check if in the selection
					if ( focusedWindow.getSelection().containsNode( child_nodes[i], true ) )// in selection
					{
						if ( sel_first_node.isSameNode( sel_last_node ) )// only one node
						{
							if ( end_offset - start_offset == 1 )// trible click and select all
							{
								return true;
							}
							
							if ( now_offset >= start_offset && now_offset <= end_offset 
								|| now_offset <= start_offset && now_offset >= end_offset  )
							{
								return true;
							}
							else
							{
								return false;
							}
						}
						
						// in the middle of selection
						if ( !child_nodes[i].isSameNode(sel_first_node) && !child_nodes[i].isSameNode(sel_last_node) )
						{
							return true;
						}
						
						// first left2right
						if ( child_nodes[i].isSameNode(sel_first_node) && cometbirdTranslate._selection_left2right && now_offset >= start_offset ) 
						{
							return true;
						}
						
						// the last left2right
						if ( child_nodes[i].isSameNode(sel_last_node) && cometbirdTranslate._selection_left2right && now_offset <= end_offset )
						{
							return true;
						}
						
						// first right2left
						if ( child_nodes[i].isSameNode(sel_first_node) && !cometbirdTranslate._selection_left2right && now_offset <= start_offset ) 
						{
							return true;
						}
						
						// the last right2left
						if ( child_nodes[i].isSameNode(sel_last_node) && !cometbirdTranslate._selection_left2right && now_offset >= end_offset )
						{
							return true;
						}
					}
					return false;
				}
			}
		}
		return false;
	}catch(e){CometBirdUtility.showErrorMsg(e);}
	},
	
    // translate when mouse move
    onmousemove : function( event )
    {
    try{	
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
        if ( !prefs.getBoolPref("browser.enhancement.google.translate.enable") )// close translate
            return;
		
		// hide panel
		cometbirdTranslate.hideResultPanel();
		window.clearTimeout( cometbirdTranslate._delay_timer );
		cometbirdTranslate._delay_timer = null;
		
		// clear last time info
		cometbirdTranslate._range = null;
        cometbirdTranslate._rangeStart = null;
        cometbirdTranslate._rangeEnd = null;
		cometbirdTranslate._rangeParent = null;
		cometbirdTranslate._translate_word = "N/A";
		
		cometbirdTranslate._selection_word_need_translate = false;
		
		if ( !cometbirdTranslate.filterElement(event) )// not need to translate
			return;

		// save position
		cometbirdTranslate._wherex = event.screenX + 15;
		cometbirdTranslate._wherey = event.screenY + 15;
		
		// update time
		cometbirdTranslate.saveNowTime();
		
		// to check the mouse is in selection
		cometbirdTranslate._selection_show = false;
		if ( cometbirdTranslate.checkInSelected( event ) )// in the selection range
		{
			// need translate
			cometbirdTranslate._selection_show = true;
			return;
		}

		/////////////////////////////////////////////
		// begin to get text when mouse moving
		// save range info
	    cometbirdTranslate._range = document.createRange();
        cometbirdTranslate._rangeStart = event.rangeOffset;
        cometbirdTranslate._rangeEnd = event.rangeOffset;
		cometbirdTranslate._rangeParent = event.rangeParent;
		
        cometbirdTranslate._range.setStart( cometbirdTranslate._rangeParent, cometbirdTranslate._rangeStart );
        cometbirdTranslate._range.setEnd( cometbirdTranslate._rangeParent, cometbirdTranslate._rangeEnd );
    }catch(e){CometBirdUtility.showErrorMsg(e);}
    },
	
	saveNowTime : function()
	{
		// save now time
		var now = new Date();
		var seconds = now.getSeconds();
		seconds += now.getMinutes() * 60;
		
		// using milli-seconds
		var milliSeconds = now.getMilliseconds();
		milliSeconds += seconds * 1000;
		cometbirdTranslate._move_time = milliSeconds;
	},
	
	filterElement : function( event )
	{
		// link text
		if ( event.target.nodeName == "A" || event.target.nodeName == "a" )
		{
			// if has title attribute, ignore it
			var attr = event.target.attributes;
			for ( var i=0; i<attr.length; i++ )
			{
				if ( attr[i].nodeName == "title" )
					return false;
			}
		}
			
		// input box
		if ( event.target.nodeName == "INPUT" || event.target.nodeName == "input" )
			return false;
			
		// not text node
	    if ( event.rangeParent == null || event.rangeParent.nodeType != Node.TEXT_NODE )
            return false;
			
		// other 
		return true;
	},
	
	monitorHidePanel : function()
	{
		var panel = document.getElementById("translate-panel");
		if ( panel != null )
			panel.hidePopup();
	},
	
	getActiveWindow : function() 
	{
		var activeWindow = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService(Components.interfaces.nsIWindowWatcher).activeWindow;
		return activeWindow;
		//if (activeWindow == null) 
		//	return null; // No windows are open
			
		//var isReallyActive = ( activeWindow.document.documentElement.getAttribute("active") == "true" );
		//return isReallyActive ? activeWindow : null;
	},
	
    monitorTranslate : function()
    {
    try{
	    var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
        if ( !prefs.getBoolPref("browser.enhancement.google.translate.enable") )// close translate
            return;
		
		// now is translate selected text			
		if ( cometbirdTranslate._is_selected_translate )
			return;
			
		// show panel
		var panel = document.getElementById("translate-panel");
		if ( panel != null && panel.state == "open" )
			return;
		
		// get now time
		var now = new Date();
		var seconds = now.getSeconds();
		seconds += now.getMinutes() * 60;
		
		var milliSeconds = now.getMilliseconds();
		milliSeconds += seconds * 1000;
				
		// to get word and translate
		if ( milliSeconds >= cometbirdTranslate._move_time + 1000 )
		{
			// translate the selection text
			if ( cometbirdTranslate._selection_show || cometbirdTranslate._selection_word_need_translate )
			{
				cometbirdTranslate._selection_show = false;
				cometbirdTranslate._selection_word_need_translate = false;
				
				if ( cometbirdTranslate._selection_word == "N/A" || cometbirdTranslate._selection_word.length == 0 )
					return;
					
				cometbirdTranslate.translate( cometbirdTranslate._selection_word );
				
				// cancel get word
				cometbirdTranslate._range = null;
				return;
			}
			
			
			if ( cometbirdTranslate._range == null )
				return;
				
			// get word
			var translate_word = cometbirdTranslate.getValidWord( cometbirdTranslate._range, cometbirdTranslate._rangeParent, cometbirdTranslate._rangeStart, cometbirdTranslate._rangeEnd );
			if ( translate_word.length == 0 )
				return;
				
			// begin to translate
			cometbirdTranslate._translate_word = translate_word;
			cometbirdTranslate.translate( translate_word );
			cometbirdTranslate._range = null;
		}
    }catch(e){CometBirdUtility.showErrorMsg(e);}   
    },
	
	setConfigTranslator : function( event )
	{
	    if ( event.target.id != "cometbird-translate-config" )
            return;
			
		var windowsMediator = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
		var setting_win = windowsMediator.getMostRecentWindow( "CometBirdTranslateSettingDialog" );
		if ( setting_win == null || setting_win.closed )
		{
			setting_win = window.openDialog( "chrome://cometbird/content/cometbird_translate_setting.xul", "Cometbird Translate Config...", "chrome=yes,titlebar=yes,toolbar=yes,dependent=no,centerscreen" ,true );
		}		
		else
		{
			setting_win.focus();
		}
	},
	
	translatetoPage : function( event )
	{
	try{
		if ( event.target.id != "cometbird-translate-topage" )
            return;
		
		// get lang
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
		var tranlate_home_lang = prefs.getCharPref("browser.enhancement.google.translate.home_lang");
        var tranlate_from_lang = prefs.getCharPref("browser.enhancement.google.translate.from_lang");
		
		var tranlate_to_lang = prefs.getCharPref("browser.enhancement.google.translate.to_lang");
		if ( tranlate_to_lang == "auto" )
			tranlate_to_lang = tranlate_home_lang;
			
		document.commandDispatcher.focusedWindow.location = "http://translate.google.com/translate_p?hl="+tranlate_home_lang+"&sl="+tranlate_from_lang+"&tl="+tranlate_to_lang+"&u="+escape(document.commandDispatcher.focusedWindow.location.toString());
	}catch(e){CometBirdUtility.showErrorMsg(e);}
	},
	
	selectedText : function( event )
	{
	try{
		// init
		cometbirdTranslate._selection_word = "N/A";
		cometbirdTranslate._is_selected_translate = false;
		cometbirdTranslate._range = null;
		cometbirdTranslate.saveNowTime();
		
		if ( event.button != 0 )
			return;
			
	    var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
        if ( !prefs.getBoolPref("browser.enhancement.google.translate.enable") 
			|| !prefs.getBoolPref("browser.enhancement.google.translate_selected.enable") )// close translate
        {
			return;
		}

		if ( !cometbirdTranslate.filterElement(event) )// not need to translate
			return;
		
		var targetnode = event.target;
		if ( event.button != 0 || targetnode == null )
		{
			return;
		}
		
		cometbirdTranslate._selection_endX = event.pageX;
		cometbirdTranslate._selection_endY = event.pageY;
		if ( cometbirdTranslate._selection_minX == cometbirdTranslate._selection_endX && cometbirdTranslate._selection_minY == cometbirdTranslate._selection_endY )// select nothing
		{
			return;
		}
		
		// select direction
		if ( cometbirdTranslate._selection_minX < cometbirdTranslate._selection_endX )
			cometbirdTranslate._selection_left2right = true;
		else
			cometbirdTranslate._selection_left2right = false;
			
		// get selected text
		var focusedWindow = document.commandDispatcher.focusedWindow;
		if ( !focusedWindow )
			return;
		var selection_text = "";
		selection_text = CometBirdUtility.trim( focusedWindow.getSelection().toString() );
		if ( selection_text.length == 0 )
		{
			return;
		}
			
		// set position
		cometbirdTranslate._wherex = event.screenX + 15;
        cometbirdTranslate._wherey = event.screenY + 15;
		
		// begin to translate
		cometbirdTranslate._selection_word = selection_text;
		cometbirdTranslate._selection_word_need_translate = true;
	}catch(e){CometBirdUtility.showErrorMsg(e);}
	},
	
	beginSelectedText : function( event )
	{
		if ( event.button != 0 )
			return;
		
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
        if ( !prefs.getBoolPref("browser.enhancement.google.translate.enable") 
			|| !prefs.getBoolPref("browser.enhancement.google.translate_selected.enable") )// close translate
            return;

		cometbirdTranslate._selection_minX = event.pageX;
		cometbirdTranslate._selection_maxX = event.pageX;
		cometbirdTranslate._selection_minY = event.pageY;
		cometbirdTranslate._selection_maxY = event.pageY;
		
		cometbirdTranslate._selection_word = "N/A";
		cometbirdTranslate._is_selected_translate = true;
		cometbirdTranslate._selection_word_need_translate = false;
		
		// hide panel
		cometbirdTranslate.hideResultPanel();
		window.clearTimeout( cometbirdTranslate._delay_timer );
		cometbirdTranslate._delay_timer = null;
	},
	
	onclick : function( event )
	{
	try{
		// init
		cometbirdTranslate._selection_word = "N/A";
		cometbirdTranslate._selection_word_need_translate = false;
		cometbirdTranslate._range = null;
		cometbirdTranslate.saveNowTime();
		
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
        if ( !prefs.getBoolPref("browser.enhancement.google.translate.enable") 
			|| !prefs.getBoolPref("browser.enhancement.google.translate_selected.enable") )// close translate
            return;
			
		if ( event.button != 0 )
			return;
			
		if ( !cometbirdTranslate.filterElement(event) )// not need to translate
			return;
				
		// hide panel
		cometbirdTranslate.hideResultPanel();
		window.clearTimeout( cometbirdTranslate._delay_timer );
		cometbirdTranslate._delay_timer = null;
		
		// get text by selection
		var select_text = "";
		var focusedWindow = document.commandDispatcher.focusedWindow;
		if ( !focusedWindow )
			return;
		var current_selection = focusedWindow.getSelection();
		select_text = current_selection.toString();
		if ( select_text.length == 0 )
		{
			cometbirdTranslate._selection_word = "N/A";
			return;
		}
		
		// begin to translate	
		cometbirdTranslate._wherex = event.screenX + 15;
		cometbirdTranslate._wherey = event.screenY + 15;

		cometbirdTranslate._selection_word = select_text;
		cometbirdTranslate._selection_word_need_translate = true;
	}catch(e){CometBirdUtility.showErrorMsg(e);}
	},
	
	onpopupshowing : function( event )
	{
		if ( event.target.nodeName == "tooltip" )// each element has tooltip, and it popupshow when it is not empty 
			return;

		if ( event.target.id == "translate-panel" )
			return;
			
		// set popup
		cometbirdTranslate._has_popup = true;
		
		//hide translate result
		cometbirdTranslate.hideResultPanel();
	},
	
	onpopupshown : function( event )
	{
		if ( event.target.id == "translate-panel" )
			return;
			
		//set popup
		cometbirdTranslate._has_popup = true;
	},
	
	onpopuphiddening : function( event )
	{
		if ( event.target.id == "translate-panel" )
			return;
			
		cometbirdTranslate._has_popup = false;
	},
	
	onpopuphidden : function( event )
	{
		if ( event.target.id == "translate-panel" )
			return;
			
		cometbirdTranslate._has_popup = false;
	},
	
	onDOMMouseScroll : function( event )
	{
		// update time
		cometbirdTranslate.saveNowTime();
	}
};

window.addEventListener( "mousemove", cometbirdTranslate.onmousemove, false );// get word and save info
window.addEventListener( "mouseup", cometbirdTranslate.selectedText, false );
window.addEventListener( "mousedown", cometbirdTranslate.beginSelectedText, false );
window.addEventListener( "click", cometbirdTranslate.onclick, false );
window.addEventListener( "load", cometbirdTranslate.init, false );
window.addEventListener( "DOMMouseScroll", cometbirdTranslate.onDOMMouseScroll, false );

window.addEventListener( "popupshowing", cometbirdTranslate.onpopupshowing, false );
window.addEventListener( "popupshown", cometbirdTranslate.onpopupshown, false );
window.addEventListener( "popuphiding", cometbirdTranslate.onpopuphiddening, false );
window.addEventListener( "popuphidden", cometbirdTranslate.onpopuphidden, false );