
const MAX_TITLE_LEN = 50;
const MENU_TITLE_SUFFIX = "...";

var bc_media_capture_instance = null;
var bc_pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
	
function bc_media_capture_onLoad(event)
{
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	try{
		bc_media_capture_instance  = Components.classes["@bitcomet.com/BitCometMediaCapture;1"].createInstance( Components.interfaces.IBitCometMediaCapture );	
		if(!bc_media_capture_instance)
		{
			window.alert( "Failed BitCometExtension, No Class." );
		}	
		else
		{
			bc_media_capture_instance.MediaCaptureStart();		
		
			var container = gBrowser.tabContainer;
			container.addEventListener("TabClose", bc_media_capture_OnTabClose, false);  // for version firefox 2+ only		
		
			// initial setting
			var capture_type = bc_media_capture_option.GetCaptureType();
			bc_media_capture_instance.MediaCaptureSetting(capture_type.length, capture_type);
		}
	}
	catch(e)
	{
	}
}   

function bc_media_capture_onUnload(event)
{
	if(bc_media_capture_instance)
	{
		var container = gBrowser.tabContainer;
		container.removeEventListener("TabClose", bc_media_capture_OnTabClose, false);
		
		// clear all history
		var browser_num = gBrowser.browsers.length;
		for (var i = 0;i < browser_num;i++)
		{
			var browser = gBrowser.getBrowserAtIndex(i);
			if (browser != null && null != browser.webProgress)
			{
				var supports = bc_media_capture_menu.__getBrowserId(browser);
				bc_media_capture_instance.MediaListClear(browser.currentURI.spec, supports);				
			}
		}
		
		bc_media_capture_instance.MediaCaptureStop();
	}
}

window.addEventListener("load", bc_media_capture_onLoad, false);
window.addEventListener("unload", bc_media_capture_onUnload, false);

var bc_media_capture_option = {
	ToggleCaptureType:function(type)
	{
		var capture_type = this.GetCaptureType();
		
		var index = 0;
		while (index < capture_type.length)
		{
			if (capture_type[index] == type)
				break;			
			index++;
		}
		
		if (index < capture_type.length)
		{
			capture_type.splice(index, 1);
		}
		else
		{
			capture_type.push(type);
		}
		
		this.__SetCaptureType(capture_type);
	},
	
	GetCaptureType:function()
	{
		var capture_type_str = bc_pref.getCharPref("BitComet.media_capture.capture_type");
		return capture_type_str.split(',');
	},
	
	HasCaptureType:function(type)
	{
		var capture_type_str = bc_pref.getCharPref("BitComet.media_capture.capture_type");
		return capture_type_str.indexOf(type) != -1;
	},
	
	__SetCaptureType:function(capture_type)
	{
		var capture_type_str = "";
		for (var i = 0;i < capture_type.length;i++)
		{
			if (0 != capture_type_str.length)
				capture_type_str  += ',';
			capture_type_str += capture_type[i];
		}

		bc_pref.setCharPref("BitComet.media_capture.capture_type", capture_type_str);
	}
}

var bc_media_capture_menu = {
	
	//onShowMainPopup:function(event)
	//{
	//	var pop_menu = document.getElementById("bc_media_capture_menu").firstChild;	
	//	this.__clearMenu(pop_menu, 0);
	//	this.__createMenu(pop_menu);
	//},
	
	onShowContextPopup:function(event)
	{
		if (!event.target)
			return;
			
		var pop_menu = event.target;
		this.createMediaMenu(pop_menu);
		this.__clearMenu(pop_menu, 4);
		this.__createMenu(pop_menu);
	},
	
	createMediaMenu: function(menuPopupMedia)
	{
		var bubble = document.getElementById("bc_ext-strings");
		if (!bubble)
			return;

		// type video menuitem
		var menuitemVideo = document.createElement("menuitem");
		menuitemVideo.setAttribute("id", "bc_media_capture_video");
		menuitemVideo.setAttribute("type", "checkbox");
		menuitemVideo.setAttribute("checked", bc_media_capture_option.HasCaptureType("video"));
		menuitemVideo.setAttribute("label", bubble.getString("bc_media_capture_video.text"));
		menuitemVideo.setAttribute("accesskey", bubble.getString("bc_media_capture_video.accesskey"));
		menuitemVideo.setAttribute("oncommand", "bc_media_capture_OnCaptureType(event, 'video')");
		menuPopupMedia.appendChild(menuitemVideo);
		
		// type audio menuitem
		var menuitemAudio = document.createElement("menuitem");
		menuitemAudio.setAttribute("id", "bc_media_capture_audio");
		menuitemAudio.setAttribute("type", "checkbox");
		menuitemAudio.setAttribute("checked", bc_media_capture_option.HasCaptureType("audio"));
		menuitemAudio.setAttribute("label", bubble.getString("bc_media_capture_audio.text"));
		menuitemAudio.setAttribute("accesskey", bubble.getString("bc_media_capture_audio.accesskey"));
		menuitemAudio.setAttribute("oncommand", "bc_media_capture_OnCaptureType(event, 'audio')");
		menuPopupMedia.appendChild(menuitemAudio);
		
		// type flash menuitem
		var menuitemFlash = document.createElement("menuitem");
		menuitemFlash.setAttribute("id", "bc_media_capture_flash");
		menuitemFlash.setAttribute("type", "checkbox");
		menuitemFlash.setAttribute("checked", bc_media_capture_option.HasCaptureType("flash"));
		menuitemFlash.setAttribute("label", bubble.getString("bc_media_capture_flash.text"));
		menuitemFlash.setAttribute("accesskey", bubble.getString("bc_media_capture_flash.accesskey"));
		menuitemFlash.setAttribute("oncommand", "bc_media_capture_OnCaptureType(event, 'flash')");
		menuPopupMedia.appendChild(menuitemFlash);

		var menuitemSeparator = document.createElement("menuseparator");
		menuPopupMedia.appendChild(menuitemSeparator);
	},

	createCleanMenu: function(menuPopupMedia, new_link_array)
	{
		var bubble = document.getElementById("bc_ext-strings");
		if (!bubble)
			return;

		var menuitemSeparator = document.createElement("menuseparator");
		menuPopupMedia.appendChild(menuitemSeparator);

		// clear all menuitem
		var menu_item = document.createElement("menuitem");
		menu_item.setAttribute("id", "bc_media_capture_clean");
		menu_item.setAttribute("label", bubble.getString("bc_media_capture_clear.text"));
		menu_item.setAttribute("oncommand", "bc_media_capture_OnClear(event)");

		if (new_link_array.length == 0)
		{
			menu_item.setAttribute("disabled", true);
		}
		
		menuPopupMedia.appendChild(menu_item);
	},
	
	onRemoveByBrowser:function(browser)
	{
		try
		{
			var supports = this.__getBrowserId(browser);
			bc_media_capture_instance.MediaListClear(browser.currentURI.spec, supports);
		}
		catch(e)
		{
		}
	},

	onCommand:function(event) 
	{
		var target = event.originalTarget;
		
		var bc_ext_instance = Components.classes["@bitcomet.com/BitCometExtension;1"].createInstance(Components.interfaces.IBitCometExtension);
		if (null != bc_ext_instance)
		{
			var	value =	{value:	0};
			if (!bc_ext_instance.GetInfo("version", value))
			{
				bc_ext_instance = null;
			}
		}
		
		var in_cache = this.__isMediaInCache(target.bc_media_url);		
		if (null != bc_ext_instance && !in_cache)
		{
			var url_array = new Array();
			url_array.push(target.bc_media_bclink);
			url_array.push(target.bc_media_title);
			bc_ext_instance.Download(url_array.length, url_array, "", "", "");
		}	
		else
		{
			try
			{
				this.__Download(target.bc_media_url, target.bc_media_title, in_cache);
				//saveURL(target.bc_media_url, "", null, true, false, null);
			}
			catch(ex)
			{
				// do nothing				
			}
		}
	},
	
	 OnCaptureType:function(event, type)
	 {
		bc_media_capture_option.ToggleCaptureType(type);
		var capture_type = bc_media_capture_option.GetCaptureType();
		try
		{
			bc_media_capture_instance.MediaCaptureSetting(capture_type.length, capture_type);
		}
		catch(e)
		{
		}
	 },
	 
	 OnClear:function(event, type)
	 {
		var supports = this.__getBrowserId(gBrowser.selectedBrowser);
		bc_media_capture_instance.MediaListClear(gBrowser.selectedBrowser.currentURI.spec, supports);	
		this.onShowContextPopup( event );
	 },

	__createMenuItem:function(media_info, idx)
	{
		var label = media_info.label;
		if (label.length > MAX_TITLE_LEN)
			label = label.substr(0, MAX_TITLE_LEN - MENU_TITLE_SUFFIX.length) + MENU_TITLE_SUFFIX;
		
		var menu_item = document.createElement("menuitem");
		menu_item.bc_commandFunc	= bc_media_capture_menu_oncommand;
		menu_item.bc_media_url		= media_info.url;
		menu_item.bc_media_title	= media_info.title;
		menu_item.bc_media_bclink   = media_info.url_bc_link;
		menu_item.setAttribute("statustext", media_info.url);	
		menu_item.setAttribute("tooltiptext", media_info.title);
		menu_item.setAttribute("label", idx + ' ' + label);
		menu_item.setAttribute("accesskey", idx);				
		menu_item.setAttribute("oncommand", "this.bc_commandFunc(event);");		
		return menu_item;
	},

	__get_video_url:function(allText)
	{
		var mmReg = /(?:http:\/\/[\w.]+\/)(?!:\/\/)[^<^>^"^'^\s]+\.(?:asf|wmv)(?!\w)/ig;
		var file_url_array = new Array;
		var temp_url = allText.match(mmReg);
		if (temp_url) 
		{
				for (var i=0; i<temp_url.length; i++)
				{
					for (var j=0; j<temp_url.length; j++)
					{
						if (temp_url[i] == temp_url[j] && i != j)
								temp_url.pop();
					}
				}
				
				file_url_array = temp_url;
		}
		
		return file_url_array;
	},
	
	__get_video_file:function(file_url, pop_menu)
	{
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("GET", file_url, true);
		xmlhttp.send(null);
		xmlhttp.onreadystatechange = function()
		{
			if (xmlhttp.readyState == 2)
			{
					var sSize = "";
					
					// get file size
					var file_size = xmlhttp.getResponseHeader("Content-Length");
					if (file_size != "")
					{
							var nSize = parseInt(file_size, 10);
							var kb = nSize / 1024;
							if (kb < 1024)
							{
								sSize = kb.toString();
								var n = sSize.indexOf(".");
								if (n != sSize.length)
								{
									if (n == 1)
											sSize = sSize.substring(0, 4);
									else if (n == 2)
											sSize = sSize.substring(0, 4);
									else if (n == 3)
											sSize = sSize.substring(0, 3);
								}

								sSize += "KB";
							}
							else
							{
								var size = kb / 1024;
								sSize = size.toString();
								var n = sSize.indexOf(".");
								if (n != sSize.length)
								{
									if (n == 1)
											sSize = sSize.substring(0, 4);
									else if (n == 2)
											sSize = sSize.substring(0, 4);
									else if (n == 3)
											sSize = sSize.substring(0, 3);
								}

								sSize += "MB";
							}
					}
					
					if (sSize != "")
					{
							sSize = "[" + sSize + "] "
					}
					
					var title = file_url.substring(file_url.lastIndexOf("/")+1, file_url.length);
					var ext = title.substring(title.lastIndexOf(".")+1, title.length);
					var ext = ext.toUpperCase();
					ext = "[" + ext + "] - " + sSize;
					var label = ext + title;
				
					var media_info = {};
					media_info.url					= file_url;
					media_info.title				= title;
					media_info.label				= label;
					media_info.url_bc_link 	= file_url;
					
					var no_capture_media_file_menuitem = document.getElementById("id_no_media_file");
					if (no_capture_media_file_menuitem)
						pop_menu.removeChild(no_capture_media_file_menuitem);

					var menu_item = bc_media_capture_menu.__createMenuItem(media_info, pop_menu.childNodes.length - 3);
					pop_menu.appendChild(menu_item);

					xmlhttp.abort();
			}
		};
	},
	
	__get_media_info:function(pop_menu)
	{
			// get url from parse the innerHtml 
	    var allText = window.content.document.documentElement.innerHTML;
			var file_url_array = bc_media_capture_menu.__get_video_url(allText);

			// get url from iframe
			var iframe = window.content.document.getElementsByTagName("iframe");
			for (var n=0; n<iframe.length; n++)
			{
					//content.document.
					var obj = iframe[n].contentDocument.getElementsByTagName("object");
					for (var i=0; i<obj.length; i++)
					{
							var param = obj[i].getElementsByTagName("param");
							for (var j=0; j<param.length; j++)
							{
									var sUrl = param[j].getAttribute("value");
									var protocol = sUrl.substring(0, 7);
									if (protocol != "http://")
										continue;
									
									var ext = sUrl.substr(sUrl.length - 4);
									if (ext == ".asf" || ext == ".wmv")
									{
										// the value is wmv or asf link
										file_url_array.push(sUrl);
									}
									else
									{
											// parse the url of content, find the wmv or asf link
											var xmlhttp = new XMLHttpRequest();
											xmlhttp.open("GET", sUrl, false);		// the content may not be huge, so we use Synchronous type
											xmlhttp.send(null);
											if (xmlhttp.readyState == 4)
											{
												 	if( xmlhttp.status == 200 )
													{
															var array_url = bc_media_capture_menu.__get_video_url(xmlhttp.responseText);
															for (var k=0; k<array_url.length; k++)
															{
																file_url_array.push(array_url[k]);
															}
													}
											}
									}
							}
					}
			}
	
			if (file_url_array.length != 0)
			{
				for (var i=0; i<file_url_array.length; i++)
				{
					bc_media_capture_menu.__get_video_file(file_url_array[i], pop_menu);
				}
			}
	},

	__createMenu:function(pop_menu)
	{
		var supports = this.__getBrowserId(gBrowser.selectedBrowser);
		var new_link_array = null;
		try
		{
			var new_link_array = bc_media_capture_instance.MediaListGet(gBrowser.selectedBrowser.currentURI.spec, supports);

		}
		catch(e)
		{
			new_link_array = new Array;
		}
		if (new_link_array.length == 0)
		{
			var bubble = document.getElementById("bc_ext-strings");
			if (!bubble)
				return;

			var menu_item = document.createElement("menuitem");
			menu_item.setAttribute("id", "id_no_media_file");
			menu_item.setAttribute("label", bubble.getString("bc_no_media_capture.text"));
			menu_item.setAttribute("disabled", true);
			pop_menu.appendChild(menu_item);
		}
		else
		{
			for (var i = 0;i < new_link_array.length;i++)
			{
				var media_info = new_link_array.queryElementAt(i, Components.interfaces.IBitCometMediaInfo);			
				var menu_item = bc_media_capture_menu.__createMenuItem(media_info, i + 1);
				pop_menu.appendChild(menu_item);			
			}
		}

		if ( bc_media_capture_option.HasCaptureType("video") )
		{
				bc_media_capture_menu.__get_media_info(pop_menu);
		}
		
		this.createCleanMenu(pop_menu, new_link_array);
	},
	
	__clearMenu:function(pop_menu, left_cnt)	
	{
		var link_item_num = pop_menu.childNodes.length - left_cnt;
		while (link_item_num > 0)
		{
			pop_menu.removeChild(pop_menu.lastChild);
			link_item_num--;
		}		
	},
	
	__getBrowserId:function(browser)
	{
		return browser.webProgress.DOMWindow.QueryInterface(Components.interfaces.nsISupports);
	},
	
	__Download:function(url_str, title_str, from_cache)
	{
	 const Cc = Components.classes;
	 const Ci = Components.interfaces;
	
	 try
	 {
		 var filepicker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
		 filepicker.init(gBrowser.selectedBrowser.webProgress.DOMWindow, "Save...", Ci.nsIFilePicker.modeSave);
		 filepicker.appendFilters(Ci.nsIFilePicker.filterAll);
		 filepicker.defaultString = title_str;
		 var ret = filepicker.show();
		 if (ret == Ci.nsIFilePicker.returnOK || ret == Ci.nsIFilePicker.returnReplace)		 
		 {
			var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowser;1"].createInstance(Ci.nsIWebBrowserPersist);
			var dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager);
			var ios_svc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
			var source_uri = ios_svc.newURI(url_str, null, null);
			var target_uri = ios_svc.newFileURI(filepicker.file);

			var isVersion2 = true;
			// get the version of Firefox
			var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo);
			var versionChecker = Components.classes["@mozilla.org/xpcom/version-comparator;1"].getService(Components.interfaces.nsIVersionComparator);
			if(versionChecker.compare(appInfo.version, "3.0") >= 0) {
				isVersion2 = false;
			}

			var start_time = Date.now();
			// firefox 2.0
			if (isVersion2)
			{
				var download = dm.addDownload(0, source_uri, target_uri, "", "", null, start_time, null, persist);
			}
			else // firefox 3.0
			{
				var download = dm.addDownload(0, source_uri, target_uri, "", null, start_time, null, persist);
			}
			persist.progressListener = download;
			var extra_http_headers = "";
			
			persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
			if (!from_cache)
			    persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_BYPASS_CACHE;
				
			// Leave it to WebBrowserPersist to discover the encoding type (or lack thereof):
			persist.persistFlags |= Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;								 
			
			persist.saveURI(source_uri, null, null, null, extra_http_headers, target_uri);
			
			// to pop up firefox download dialog
			var command_download = document.getElementById("Tools:Downloads");
			if (null != command_download)
			{
				command_download.doCommand();
			}
		 }
	 }
	 catch (ex)
	 {
		 dump_error("__Download()", ex);
	 }
	},
	
	__isMediaInCache:function(url_str)
	{
		var ret = false;
		const Cc = Components.classes;
		const Ci = Components.interfaces;
		var cache_svc = Cc["@mozilla.org/network/cache-service;1"].getService(Ci.nsICacheService);
		var cache_session = cache_svc.createSession("HTTP", Ci.nsICache.STORE_ANYWHERE, Ci.nsICache.STREAM_BASED);
		if (null != cache_session)
		{
			try 
			{
				var cache_entry_desc = cache_session.openCacheEntry(url_str, Ci.nsICacheService.ACCESS_READ, Ci.nsICache.NON_BLOCKING);
				ret = (null != cache_entry_desc);
			}
			catch (ex)
			{
			}			
		}		
		return ret;
	}
}; //bc_media_capture_menu

//function bc_media_capture_menu_popup(event)
//{
//	bc_media_capture_menu.onShowMainPopup(event);
//}

function bc_media_capture_menu_oncommand(event)
{	
	bc_media_capture_menu.onCommand(event);
}

function bc_media_capture_OnTabClose(event)
{
	bc_media_capture_menu.onRemoveByBrowser(event.target.linkedBrowser);
}

function bc_media_capture_contextmenu_show(event)
{
	bc_media_capture_menu.onShowContextPopup(event);
}

function bc_media_capture_OnCaptureType(event, type)
{
	bc_media_capture_menu.OnCaptureType(event, type);
}

function bc_media_capture_OnClear(event)
{
	bc_media_capture_menu.OnClear(event);
}

//// just for debug
function dump_error(func, ex)
{
	dump(func + "----");
	dump(ex);
	dump("\r\n");
}