// cometbird_dragtogo.js

var CometbirdDragtogo =
{
	_loaded			: false,
	_moving			: false,
	_startAlready	: false,
	_dropEvent		: null,
	_startEvent		: null,
	
	_currentAddTabParent	: null,
	_innerNode				: true,
	_isCancelDrag			: false,
	
	init : function()
	{	
		if ( CometbirdDragtogo._loaded )
			return;
		
		CometbirdDragtogo._loaded = true;
		var contentArea = getBrowser().mPanelContainer;
		if (contentArea)
		{
			try 
			{
				eval( "nsDragAndDrop.dragOver =" + nsDragAndDrop.dragOver.toString().replace('aEvent.stopPropagation();','if ( !CometbirdDragtogo._moving ) { $& }') );
			}catch(e) {}
			
			eval( "nsDragAndDrop.checkCanDrop =" + nsDragAndDrop.checkCanDrop.toString().replace('if ("canDrop" in aDragDropObserver)','if (CometbirdDragtogo._startAlready) this.mDragSession.canDrop = true; $&') );
		
			contentArea.addEventListener( "draggesture", CometbirdDragtogo.onstartdrag, false );
			contentArea.addEventListener( "dragover", CometbirdDragtogo.ondragover, false );
			contentArea.addEventListener( "dragdrop", CometbirdDragtogo.ondragdrop, false );
			contentArea.addEventListener( "drop", CometbirdDragtogo.ondragdrop, false );
		}
	},
	
	onstartdrag : function( event )
	{
		CometbirdDragtogo._startAlready = true;
		CometbirdDragtogo._startEvent = event;
	},
	
	ondragover : function( event )
	{
		CometbirdDragtogo._moving = true;
		nsDragAndDrop.dragOver( event, CometbirdDragtogoObserver);
		CometbirdDragtogo._moving = false;
	},
		
	ondragdrop : function( event )
	{
		nsDragAndDrop.drop( event, CometbirdDragtogoObserver);
	},
  
	onMousedown : function( event )
	{
		if ( event.button == 0 )//left mouse down
		{	
			CometbirdDragtogo._isCancelDrag = false;
		}
	},
	
	onMouseup : function( event )
	{
		if ( event.button == 2 )// right mouse up
		{
			CometbirdDragtogo._isCancelDrag = true;
		}
	},
	
	doResult : function( dragText )
	{
		// trim space
		dragText = dragText.replace(/^\s+/g,"").replace(/\s+$/g,""); 
		if ( dragText.length == 0 )
			return;	

		// drag from outer
		if ( !CometbirdDragtogo._innerNode )
		{
			//CometBirdFile.writeLog("drag from outer: "+dragText);
			loadURI(dragText, null, null, true);
			return;
		}
		
		// below from inner
		// email
		if ( /^(mailto):/i.test(dragText) || /^\w+[\-\.\w]*@(\w+(\-+\w+)*\.)+\w{2,7}$/.test(dragText) )
		{
			if ( !/^(mailto):/i.test(dragText) )
				dragText = "mailto:" + dragText;
				
			//CometBirdFile.writeLog("mailto: "+dragText);
			loadURI(dragText, null, null, true);
			return;
		}
		
		// javascript:
		if ( /^(javascript):/i.test(dragText) )
		{
			//CometBirdFile.writeLog("javascript: "+dragText);
			loadURI(dragText, null, null, true);
			return;
		}
		
		// check url
		var browser = getTopWin().getBrowser();
		if ( this.checkIsUrl( dragText ) )
		{	
			//CometBirdFile.writeLog("loadOneTab: "+dragText);
			browser.loadOneTab( dragText, null, null, null, true, true );
			CometbirdDragtogo.updateTabToGroup();
			return;
		}
		
		// about protocal
		if ( /^(about):/i.test(dragText) )
		{
			//CometBirdFile.writeLog("about: "+dragText);
			browser.loadOneTab( dragText, null, null, null, true, true );
			CometbirdDragtogo.updateTabToGroup();
		}
	},
	
	// open new url in 400ms
	// if click right mouse button in 400ms, it will cancel the drag operation
	dealDragText : function( dragText )
	{
		setTimeout( 
			function()
			{ 
				if ( !CometbirdDragtogo._isCancelDrag )
				{
					//CometBirdFile.writeLog("deal drag text" );
					CometbirdDragtogo.doResult( dragText ); 
					return;
				}

				//CometBirdFile.writeLog("cancel drag for right mouse button" );
			}, 
		400 );
	},
	
	checkIsUrl : function( url )
	{
		//CometBirdFile.writeLog( "checkIsUrl: " + url );
	
		var Expression = /:\/\//;
		if ( Expression.test(url) == true )
		{
			Expression = /^(http[s]?|ftp)/;
			if ( Expression.test(url) == false )
			{
				//CometBirdFile.writeLog( "checkIsUrl invalid:" + url );
				return false;
			}
		}
		
		// url test
		var DomainName = /(\w+(\-+\w+)*\.)+\w{2,7}/;
		var HasSpace = /\S\s+\S/;
		var KnowNameOrSlash = /^(www|bbs|forum|blog)|\//;
		var KnowTopDomain1 = /\.(com|net|org|gov|edu|info|mobi|mil|asia)$/;
		var KnowTopDomain2 = /\.(de|uk|eu|nl|it|cn|be|us|br|jp|ch|fr|at|se|es|cz|pt|ca|ru|hk|tw|pl)$/;
		var IsIpAddress = /^([1-2]?\d?\d\.){3}[1-2]?\d?\d/;
		var is_url = !HasSpace.test(url) && DomainName.test(url) &&
					   ( KnowNameOrSlash.test(url) || KnowTopDomain1.test(url) || KnowTopDomain2.test(url) || IsIpAddress.test(url) );
		return is_url;
	},
	
	cleanDrag : function()
	{
		if ( CometbirdDragtogo._dropEvent == null )
			return;
			
		CometbirdDragtogo._startAlready = false;
		CometbirdDragtogo._dropEvent.preventDefault();
		CometbirdDragtogo._dropEvent.stopPropagation();
		CometbirdDragtogo._dropEvent = null;
		CometbirdDragtogo._startEvent = null;
	}, 
	
	checkIsEnableDrag : function( type )
	{
		// check if enable drag and drop
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
        var prefs = prefService.getBranch("");
		
		if ( type == "link" )
		{
			if ( prefs.getBoolPref("browser.enhancement.dragdrop_link.enable") )
				return true;
			else
				return false;
		}
		
		if ( type == "text" )
		{
			if ( prefs.getBoolPref("browser.enhancement.dragdrop_text.enable") )
				return true;
			else
				return false;
		}
		
		return false;
	},
	
	updateTabToGroup : function()
	{
	try{
		if ( !CometbirdTabGroup.checkTabGroupEnable() )
			return;

		if ( CometbirdDragtogo._currentAddTabParent == null )
			return;
			
		// set parent info
		var pid = CometbirdDragtogo._currentAddTabParent.getAttribute( "cometbird_tab_id" );
		var gid = CometbirdDragtogo._currentAddTabParent.getAttribute( "cometbird_tab_gid" );
		var color = CometbirdDragtogo._currentAddTabParent.getAttribute( "cometbird_tab_color" );
		//CometBirdFile.writeLog ("drag: pid: " + pid);
		
		var curTab = gBrowser.mTabs[gBrowser.mTabContainer.itemCount-1];
		curTab.setAttribute( "cometbird_tab_pid", pid );
		curTab.setAttribute( "cometbird_tab_gid", gid );
		curTab.setAttribute( "cometbird_tab_color", color );
		CometbirdTabGroup.setColor(curTab, color);
		//CometBirdFile.writeLog ("drag: id: " + curTab.getAttribute( "cometbird_tab_id" ) );

		// inTo group
		CometbirdDragtogo.inToGroup( curTab );
		CometbirdDragtogo._currentAddTabParent = null;
	}catch(e){CometBirdFile.writeLog (e);}
	},
	
	inToGroup : function( newTab )
	{
	try{
		var newTabGid = newTab.getAttribute( "cometbird_tab_pid" );// gid
		var tab_count = gBrowser.mTabContainer.itemCount;
		
		for ( var i=tab_count-2; i>=0; i-- )
		{
			var tab = gBrowser.mTabs[i];
			if ( newTabGid == tab.getAttribute( "cometbird_tab_id" ) )// gid
			{
				CometbirdTabGroup.autoTabMove = true;
				gBrowser.moveTabTo( newTab, i+1 );// move before
				CometbirdTabGroup.autoTabMove = false;
				break;
			}
		}
		
		// set color
		setTimeout( "CometbirdTabGroup.updateTabsColor();", 10 );
	}catch(e){ CometBirdFile.writeLog("inToGroup"+e); }
	}
};

var CometbirdDragtogoObserver = 
{
	_data	: "",
	
	onDragOver : function(event, flavour, dragSession) 
	{
		dragSession.canDrop = true;
		if ( !CometbirdDragtogo._startAlready )
		{
			CometbirdDragtogo._startEvent = event;// save the event for selected text
			CometbirdDragtogo._startAlready = true;
		}
		
		CometbirdDragtogoObserver._data = "";
		
		//save selected data
		var focusedWindow = document.commandDispatcher.focusedWindow;
		if ( !focusedWindow )
			return;

		// check the selecting node is drag node
		if ( !CometbirdDragtogo._startEvent.target || CometbirdDragtogo._startEvent.target == null ) 
			return;
			
		if ( CometbirdDragtogo._startEvent.target.localName != null &&
     		( CometbirdDragtogo._startEvent.target.localName.toUpperCase() == "TEXTAREA"
			|| (CometbirdDragtogo._startEvent.target.localName.toUpperCase() == "INPUT" && CometbirdDragtogo._startEvent.target.type == "text") ) )
			CometbirdDragtogoObserver._data = CometbirdDragtogo._startEvent.target.value.substring( CometbirdDragtogo._startEvent.target.selectionStart, CometbirdDragtogo._startEvent.target.selectionEnd );
		else
			CometbirdDragtogoObserver._data = focusedWindow.getSelection().toString();
	},

	onDrop : function(event, xferData, dragSession) 
	{
		if ( !CometbirdDragtogo._startAlready ) 
			return;
		
		// init drop event
		CometbirdDragtogo._dropEvent = event;
		
		// save current tab info
		CometbirdDragtogo._currentAddTabParent = gBrowser.selectedTab;
		
		// Drag and Drop from content outer
		// get node of drag
		var drag_node = dragSession.sourceNode;
		CometbirdDragtogo._innerNode = true;
		if ( !drag_node )
		{
			var url = "";
			var strText = "";
			try {
				var ferData = xferData.data.split("\n");
				url = ferData[0];
				strText = ferData[1];
			} catch(e) 
			{
				url = "";
				strText = "";
			}

			if ( url == "" ) 
			{
				CometbirdDragtogo.cleanDrag();
				return;
			}
			
			if ( CometbirdDragtogo.checkIsUrl(url) || (/^file:\/\/\/[\S]+$/.test(url)) ) 
			{
				// local file/directory
				if ( /^file:\/\/\//.test(url) ) 
				{
					if ( /([^\/]+\.(xpi|jar))$/.test(url) ) 
					{
						eval("InstallTrigger.install({ '" + RegExp.$1 + "' : url })");
						CometbirdDragtogo.cleanDrag();
						return;
					}
				}

				if ( strText != "" && strText != undefined && CometbirdDragtogo.checkIsEnableDrag("link") ) // link and text
				{
					//CometBirdFile.writeLog("url: "+url);
					loadURI(url, null, null, true);
					CometbirdDragtogo.cleanDrag();
					return;
				}
				
				// other url
				if ( CometbirdDragtogo.checkIsEnableDrag("link") )
				{
					CometbirdDragtogo._innerNode = false;
					CometbirdDragtogo.dealDragText( url );
				}
			}
			
			CometbirdDragtogo.cleanDrag();
			return;
		}
		
		var orignal_drag_data = xferData.data.replace(/^\s+/g,"").replace(/\s+$/g,"");
		//CometBirdFile.writeLog("drag data: " + orignal_drag_data);
		
		// xferData.data: url of link or selected text
		var ferData = orignal_drag_data.split("\n");
		//CometBirdFile.writeLog("ferData.length: " + ferData.length);
		if ( ferData.length > 2 )
		{
			CometbirdDragtogo.cleanDrag();
			return;
		}
		
		var url = "";
		var	str = "";
		if ( typeof ferData[1] == "undefined" )// select
		{
			str = ferData[0];
		}
		else
		{
			url = ferData[0];
			str = ferData[1];
		}

		// selected text
		var selected_text = CometbirdDragtogoObserver._data.replace(/^\s+/g,"").replace(/\s+$/g,""); 
		//CometBirdFile.writeLog("selected_text: " + selected_text + " - " + selected_text.length);
		
		str = str.replace(/^\s+/g,"").replace(/\s+$/g,""); // trim space
		//CometBirdFile.writeLog("str: " + str + " - " + str.length);
		if ( selected_text.length > 0 && selected_text == str )
		{
			if ( CometbirdDragtogo.checkIsEnableDrag("text") )
				CometbirdDragtogo.dealDragText( selected_text );
			CometbirdDragtogo.cleanDrag();
			return;
		}

		// xferData.data: url of link or selected text
		if ( CometbirdDragtogo.checkIsEnableDrag("link") )
			CometbirdDragtogo.dealDragText( url );
		CometbirdDragtogo.cleanDrag();
	},

	getSupportedFlavours : function() 
	{
		var flavourSet = new FlavourSet();
		flavourSet.appendFlavour("text/x-moz-url");
		flavourSet.appendFlavour("text/unicode");
		return flavourSet;
	}
};

window.addEventListener( "load", CometbirdDragtogo.init, false );
window.addEventListener( "mousedown", CometbirdDragtogo.onMousedown, false );
window.addEventListener( "mouseup", CometbirdDragtogo.onMouseup, false );