var configUrl = "resource://livemargins/apps/search/search-config.html?"

var SearchPage = {
	queryCount: 0,
	successRequests: 0,
	
	init: function(){
		var searchString = "";
		try {
			var [, , searchInput] = window.location.href.match(/^(.*)\?(.*)$/);
			searchString = jQuery.trim(decodeURIComponent(searchInput));
		} catch (e) {
			searchString = "";
		}
		if (searchString && searchString.length > 0) {
			document.title = document.title + " - " + searchString;

			var self = this;
			window.setTimeout(function() {
				self.startSearch(searchString);
			}, 0);			
		} else {
			$('#loading').hide();
			this.startGuide();
		}
	},
	
	beforeSearch: function(searchString, searchId) {
		this.queryCount += 1;
		contentAPI.log("before search: " + searchId);
	},
	
	endSearch: function(searchString, status, searchId) {
		contentAPI.log("end search: " + searchId);
		this.queryCount -= 1;
		if (status && status === "success") {
			this.successRequests += 1;
		}
		if (this.queryCount <= 0) {
			$('#loading').hide();
			$('#ads-container').show();	
			$('#engines-container').show();	
			
			if (this.successRequests <= 5)	 {
				this.loadSearchEngineResults(searchString, 5);
				$('#engines-content > .info').show();
				this.showHotKeywords();
			} else {
				this.loadSearchEngineResults(searchString, 3);
			}
			this.showConfigButton(searchString);
		} 
	},
	
	startGuide: function() {
		var engineSection = new SearchSection('engines-container');
		engineSection.init();
		
		var guideContent = $('<div>').attr("id", "guide-content").html($('#guide-template').html());
		engineSection.addResultPage(
					'如何使用多重搜索?', 
					'engines-section', 
					'guide-content', 
					guideContent, 
					"chrome://livemargins/skin/images/search.png",
					'http://i.g-fox.cn/', 
					0);		
		
		this.showHotKeywords();
	},
	
	showConfigMessage: function(searchString){
	    var show = true;
		try {
			show = contentAPI.getBoolPref('config.message');
		} catch (e) {
			show = true;
		}
		if (show) {
		    var template = unescape($('#config-message-template').html());
			var msgContainer = $('<div>').attr('id', 'config-message');
			msgContainer.html(TrimPath.parseTemplate(template).process({ url: configUrl + encodeURIComponent(searchString) }));
			$('#content').append(msgContainer);
		}
	},
	
	showConfigButton: function(searchString) {
	   var button = $('<a>').attr('href', configUrl + encodeURIComponent(searchString)).text('搜索引擎配置').attr('id', 'config-button');
	   $('#content').append(button);
	},
	
	startSearch: function(searchString){
	    this.showConfigMessage(searchString);
		this.beforeSearch(searchString, "overall");
		
		var omitEngines = '';
	    try {
	        omitEngines = contentAPI.getCharPref('engines.omit');
	    } catch(e) {
	        omitEngines = '';
	    }
	    omitEngines = omitEngines.split(',');
	    
	    var omit_engines = {};
	    for (var i = 0; i < omitEngines.length; i += 1) {
	        omit_engines[omitEngines[i]] = true;
	    }
	    
		var wikiSection = new SearchSection("wiki-container");
		wikiSection.init();
		if (!('wikipedia' in omit_engines)) this.searchWikipedia(searchString, wikiSection, 1);
		if (!('dict' in omit_engines)) this.searchDict(searchString, wikiSection, 2);
		// we have an opening for google translate
		if (!('baidu-baike' in omit_engines)) this.searchBaiduBaike(searchString, wikiSection, 10);
		if (!('local' in omit_engines)) this.searchLocalInfor(searchString, wikiSection, 11);
		
		var pictureSection = new SearchSection('pictures-container');
		pictureSection.init();
		if (!('flickr' in omit_engines)) this.searchFlickr(searchString, pictureSection, 1);
		if (!('google-image' in omit_engines)) this.searchGoogleImage(searchString, pictureSection, 2);
		// this.searchTaobaoImgo(searchString, pictureSection, 3);
		
		var videoSection = new SearchSection('video-container');
		videoSection.init();
		if (!('youku' in omit_engines)) this.searchYouku(searchString, videoSection, 1);
		if (!('tudou' in omit_engines)) this.searchTudou(searchString, videoSection, 2);
		// this.searchGoogleVideo(searchString, videoSection, 3);
		
		// inject ads
		this.injectAds(searchString);
		
		var infoSection = new SearchSection('info-container');
		infoSection.init();
		if (!('google-news' in omit_engines)) this.searchGoogleNews(searchString, infoSection, 1);
		if (!('stock' in omit_engines)) this.searchStockQuote(searchString, infoSection, 2);
		if (!('verycd' in omit_engines)) this.searchVerycd(searchString, infoSection, 3);
		if (!('douban-book' in omit_engines)) this.searchDoubanBook(searchString, infoSection, 4);
		if (!('douban-movie' in omit_engines)) this.searchDoubanMovie(searchString, infoSection, 5);
		
		var lifestyleSection = new SearchSection('lifestyle-container');
		lifestyleSection.init();
		if (!('youdao-shopping' in omit_engines)) this.searchYoudaoGouwu(searchString, lifestyleSection, 2);
		if (!('betty' in omit_engines)) this.searchBettyKitchen(searchString, lifestyleSection, 3);
		if (!('buy360' in omit_engines)) this.searchBuy360(searchString, lifestyleSection, 4);

		var engineSection = new SearchSection('engines-container');
		engineSection.init();
		this.injectSearchEngines(searchString, engineSection);
		$('#engines-container').hide();
		
		this.trackPageview(searchString);
		
		this.endSearch(searchString, null, "overall");	
	},

	injectAds: function(searchString){
		this.beforeSearch(searchString, "ads");
		
		var self = this;
		contentAPI.ajax({
			url: "http://i.g-fox.cn/js/lmad.js",
			method: 'GET',
			dataType: "json",
			cache: false,
			success: function(data) {
				try {
					var index = Math.floor(Math.random() * data.length);
					if (index < 0 || index >= data.length) index = 0;
					var adObject = data[index];
					adObject.url = "http://i.g-fox.cn/hp?u=" + encodeURIComponent(adObject.url) + 
									"&c=lmad&t=" + 
									encodeURIComponent(adObject.title);
					
					var template = unescape($('#ads-template').html());
					var adsContainer = $('<div>').attr('id', 'ads-container');
					adsContainer.html(TrimPath.parseTemplate(template).process({ad: adObject})).hide();
					adsContainer.insertAfter($("#info-container"));
				} finally {
					self.endSearch(searchString, null, "ads");
				}
			},
			error: function(request, status) {
				contentAPI.log("ads service error: " + status);
				self.endSearch(searchString, null, "ads");
			},
		});
	},
	
	injectSearchEngines: function(searchString, section) {
		var result = contentAPI.getSearchEngines(searchString);
		if (!result) {
			return;
		}
		
		if (result.engines.length > 0) {
			var template = unescape($('#engines-template').html());
			var enginesContent = $('<div>').attr("id", "engines-content");
			enginesContent.html(TrimPath.parseTemplate(template).process(result));
			section.addResultPage(
						'使用搜索引擎', 
						'engines-section', 
						'engines-content', 
						enginesContent, 
						"chrome://livemargins/skin/images/search.png",
						result.currentEngine.link, 
						0);		
		}
	},
	
	loadSearchEngineResults: function(searchString, count){
		function showResults(data) {
			if (data === null) {
				$('#engines-detail-results').hide();
				return;
			}
			
			var template = unescape($('#engine-results-template').html());
			$('#engines-detail-results').html(TrimPath.parseTemplate(template).process({"results": data}));
			
			$('#engines-detail-results > div').each(function() {
				$(this).hover(
					function() { $(this).addClass("highlight"); },
					function() { $(this).removeClass('highlight'); }
				);
			});
		}
		
		contentAPI.ajax({
			url: "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=" + encodeURIComponent(searchString) + "&key=ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw&hl=zh-CN&rsz=large",
			method: 'GET',
			dataType: 'json',
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, 'Referer', 'http://g-fox.cn/');
			},
			success: function(data) {
				if (data.responseStatus === 200 && data.responseData.results.length > 0) {
					var results = [];
					for (var i = 0; i < data.responseData.results.length && i < count; i += 1) {
						results.push({
							title: data.responseData.results[i].titleNoFormatting,
							content: data.responseData.results[i].content.substring(0, 100) + " ... ",
							url: data.responseData.results[i].url,
							visibleUrl: data.responseData.results[i].visibleUrl
						});
						showResults(results);
					}
				} else {
					showResults(null);
				}
			},
			error: function(request, status) {
				showResults(null);
			},
		});
	},
	
	showHotKeywords: function(){
		var hotwords = contentAPI.searchService.getHotKeywords();
		if (hotwords && hotwords.length > 0) {
			var template = unescape($('#engine-hotwords-template').html());
			$('#hotkeywords > p').html(TrimPath.parseTemplate(template).process({ 'hotwords': hotwords }));
			$('#hotkeywords').show();
		}
	},
	
	openDetail: function(api, options) {
		SearchDetail.openDetail($('#content'), $('#detail-browser'), api, options);
	},
	
	trackPageview: function(searchString) {
		contentAPI.ajax({
			url: "http://i.g-fox.cn/s?s=s_ping&q=" + encodeURIComponent(searchString),
			method: 'GET',
			dataType: 'text',
			cache: false
		});
	},
	
	/** wiki section **/
	searchWikipedia: function(searchString, section, rank){
		var langCode = "zh";
		try {
			langCode = contentAPI.getCharPref('wikipedia.lang');
		} catch (e) {
			langCode = "zh";
		}
		
		var self = this;
		self.beforeSearch(searchString, "wikipedia");
		
		function fetchWikipediaArticle(block, aTitle) {
			contentAPI.ajax({
				url: 'http://' + langCode + '.wikipedia.org/w/api.php?action=parse&format=json&page=' + encodeURIComponent(aTitle),
				method: "GET",
				dataType: "json",
				timeout: 5000,
				success: function(parseData) {
					var wikiLink = "http://" + langCode + ".wikipedia.org/wiki/" + aTitle.replace(/ /g, "_");
					var parse = jQuery("<div>" + parseData.parse.text["*"]);
					var articleSummary = parse.find("p:first").text();
					articleSummary = articleSummary.replace(/\[.+?\]/g, "").substring(0, 80) + "...";
					var wikiDescription = $('<a></a>').
										attr('href', "javascript: void(0);").
										attr('class', 'a-description').
										text(articleSummary);
					block.append(wikiDescription);
				},
			});
		}
		
		contentAPI.ajax({
			url: 'http://' + langCode + '.wikipedia.org/w/api.php?action=query&format=json&list=search&srlimit=5&srwhat=text&srsearch=' + encodeURIComponent(searchString),
			method: 'GET',
			dataType: 'json',
			timeout: 5000,
			beforeSend: function(request){
			},
			success: function(data){
				try {
					var status = 'fail';
					if ("query" in data && "search" in data.query && data.query.search.length > 0) {
						var displayCount = 2;
						var wikiContent = $('<div>').attr('id', 'wikipedia-content');
						for (var i = 0; i < data.query.search.length && i < displayCount; i += 1) {
							var title = data.query.search[i].title;
							var wikiLink = "http://" + langCode + ".wikipedia.org/wiki/" + title.replace(/ /g, "_");
							var wikiDiv = $('<div>').attr('class', 'wikipedia-item');
							var wikiTitle = $('<a>').
											attr('href', "javascript: void(0);").
											attr('class', 'a-title').
											text(title);
							wikiDiv.append(wikiTitle);
							wikiDiv.click(function() {
								self.openDetail('Wikipedia', {
									langCode: langCode, 
									title: $("a.a-title", this).text()
								});
							});
							fetchWikipediaArticle(wikiDiv, title);
							wikiContent.append(wikiDiv);
						}
						section.addResultPage(
									'Wikipedia', 
									'wikipedia-section', 
									'wikipedia-content', 
									wikiContent, 
									"http://en.wikipedia.org/favicon.ico",
									"http://" + langCode + ".wikipedia.org/", 
									rank);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "wikipedia");
				}
			},
			error: function(data) {
				self.endSearch(searchString, null, "wikipedia");
			},
		});
	},
	
	searchHudong: function(searchString, section, rank){
		var self = this;
		self.beforeSearch(searchString, "hudong");
		
		contentAPI.ajax({
			url: "http://api.hudong.com/dict.do?title=" + encodeURIComponent(searchString) + "&from=top100&type=55",
			method: 'GET',
			dataType: "text",
			timeout: 5000,
			beforeSend: function(request) {
			},
			success: function(text){
				var status = 'fail';
				try {
					var xml = jQuery.parseXML(text);
					var responseFlag = $("response > flag", xml).text();					
					if (responseFlag === 'true') {
						var hudongContent = $('<div>').attr('id', 'hudong-content');
						var template = unescape($('#hudong-template').html());
						var result = {
							entry : {
								title: self.stripXss($("response > doctitle", xml).text()),
								description: self.stripXss($("response > summary", xml).text().replace(/<\/?[^>]*>/g, "").substring(0, 140) + "..."),
								image: $("response > firstimg", xml).text(),
								link: "http://www.hudong.com/wiki/" + encodeURIComponent(searchString)
							}
						};
						hudongContent.html(TrimPath.parseTemplate(template).process(result));
						section.addResultPage(
									'互动百科', 
									'hudong-section', 
									'hudong-content', 
									hudongContent, 
									'chrome://marginbox/skin/images/hudong.png',
									result.entry.link,
									rank);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "hudong");
				}
			},
			error: function(data) {
				self.endSearch(searchString, null, "hudong");
			}
		});
	},
	
	searchBaiduBaike: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "baidu_baike");
		
		// fuck Baidu for its encoding problem.
		var httpChannel = contentAPI.newChannel('http://baike.baidu.com/w?ct=17&lm=31&tn=baiduOlympics&pn=0&rn=10&ss=firefox&word=' + searchString, "GB2312", null);
		
		function completeCallback(data) {
			try {
				var status = 'fail';
				if (data) {
					// Here be dragons
					// don't know why Firefox 3.5.2 doesn't handle encoding=utf-8 xml well and responseXML = null
					var dataText = data.substring('<?xml version="1.0" encoding="GBK"?>'.length);
					dataText = dataText.replace(/\<\!\[CDATA\[/g, "");
					dataText = dataText.replace(/\]\]\>/g, "");
					
					var fakeDoc = $('<div>' + dataText);
					if (fakeDoc) {
						var wikiItem = $('res > wiki', fakeDoc);
						var baikeResult = {
							entry: {
								title: self.stripXss($('title', wikiItem).text().replace(/<\/?[^>]*>/g, "")),
								description: self.stripXss($('abstract', wikiItem).text().replace(/<\/?[^>]*>/g, "").substring(0, 140) + "..."),
								link: 'http://baike.baidu.com' + $('wikilink', wikiItem).text()
							}
						};
						if (baikeResult.entry.title && baikeResult.entry.title.length > 0) {
							var baikeContent = $('<div>').attr('id', 'baidubaike-content');
							var template = unescape($('#baidubaike-template').html());
							baikeContent.html(TrimPath.parseTemplate(template).process(baikeResult));
							section.addResultPage(
										'百度百科', 
										'baidu-section', 
										'baidubaike-content', 
										baikeContent, 
										'http://www.baidu.com/favicon.ico',
										baikeResult.entry.link,
										rank);
							status = 'success';
						}
					}
				}
			} finally {
				self.endSearch(searchString, status, "baidu_baike");
			}
		}
		
		var data = null;
		var listener = contentAPI.createChannelListener(function (aRequest, aContext) {
			data = '';
		}, function (aRequest, aContext, aStream, aSourceOffset, aLength) {
			data = contentAPI.readDataFromStream(aStream, aLength);
		}, function (aRequest, aContext, aStatus) {
			if (contentAPI.isSuccessCode(aStatus)) {
				// request was successfull
				completeCallback(data);
		    } else {
				// request failed
				completeCallback(null);
		    }
			httpChannel = null;
		});
		
		contentAPI.asyncOpenHttpChannel(httpChannel, listener);
	},
	
	searchDict: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "youdao_dict");
		
		contentAPI.ajax({
			url: 'http://dict.youdao.com/search?doctype=xml&q=' + encodeURIComponent(searchString),
			method: 'GET',
			dataType: 'text',
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(text){
				try {
					// Can not access nodeType of responseXML, so parse it manually.
					var xml = jQuery.parseXML(text);
					
					var status = 'fail';
					
					var dict = $('yodaodict', xml);
					var dictObject = {
						entry: {
							key: '',
							pron: '',
							def: '',
							webtrans: [],
							example: []
						},
						valid: false
					};
					var keyObject = $('return-phrase', dict).text();
					if (keyObject && keyObject.length > 0) {
						dictObject.entry.key = self.stripXss(keyObject);
						dictObject.entry.pron = self.stripXss($('phonetic-symbol', dict).text());
						dictObject.entry.def = self.stripXss($('custom-translation > translation > content', dict).text());
						dictObject.valid = true;
					} else {
						dictObject.entry.key = self.stripXss($('original-query', dict).text());
					}
					
					dict.find('yodao-web-dict > web-translation').each(function(index) {
						if (index < 2) {
							var webkey = self.stripXss($('key', $(this)).text());
							var def = [];
							$(this).find('trans').each(function() {
								def.push(self.stripXss($('value', $(this)).text()));
							});
							dictObject.entry.webtrans.push('<b>' + webkey + "</b>: " + def.join(", "));
							dictObject.valid = true;
						}
					});
					
					dict.find('example-sentences > sentence-pair').each(function(index) {
						if (index < 2) {
							dictObject.entry.example.push({
								orig: self.stripXss($('sentence', $(this)).text()),
								trans: self.stripXss($('sentence-translation', $(this)).text())
							});
						}
					});
	
					if (dictObject.valid) {
						var template = unescape($('#dict-template').html());
						var dictContent = $('<div>').attr('id', 'dict-content');
						dictContent.html(TrimPath.parseTemplate(template).process(dictObject));
						section.addResultPage(
									'有道词典', 
									'dict-section', 
									'dict-content', 
									dictContent, 
									'http://shared.youdao.com/images/favicon.ico',
									'http://dict.youdao.com/search?q=' + encodeURIComponent(searchString),
									rank);
						
						status = 'success';
					} else {
						// we let google translate for us
						self.searchGoogleTranslate(searchString, section, rank + 1);					
					}
				} finally {
					self.endSearch(searchString, status, "youdao_dict");
				}
			},
			error: function(request, status, errorThrown) {
				self.endSearch(searchString, null, "youdao_dict");
			}
		});
	},
	
	stripXML: function(s) {
		if (!s) {
			return s;
		}
		
		return s.replace(/</ig, '&lt;').replace(/>/ig, '&gt;');
	},
	
    stripXss: function(s) {
    	if (!s) {
    		return s;
    	}
    	
        return $('<p>').text(s).html();
    },

	searchGoogleTranslate: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "google_translate");
		
		var code2name = {
			'zh-CN': '中文(简体)',
			'zh-TW': '中文(繁体)',
			'en': '英语',
			'de': '德语',
			'fr': '法语',
			'ja': '日语',
			'ko': '朝鲜语',
			'ru': '俄语',
			'pt': '葡萄牙语',
			'es': '西班牙语',
			'it': '意大利语'
		};
		var fromLang = '';
		
		var fromLink = contentAPI.currentTabLink;
		var transPageLinkBase = "http://translate.google.com/translate?";
		if (fromLink) {
			transPageLinkBase += 'u=' + escape(fromLink) + "&";
		}
		
		function _detectLangCode() {
			contentAPI.ajax({
				url: 'http://ajax.googleapis.com/ajax/services/language/detect',
				method: 'POST',
				dataType: 'json',
				timeout: 5000,
				data: {
					v: "1.0",
					q: searchString,
					key: 'ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw'
				},
				beforeSend: function(request) {
					contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
				},
				success: function(data){
					if (data.responseStatus === 200) {
						fromLang = data.responseData.language;
					}
					_detectCallback();
				},
				error: function(request, status, errorThrown){
					_detectCallback();
				},
			});
		}
		
		function _detectCallback() {
			var toLang = 'en';
			if (fromLang && fromLang.length > 0) {
				if (fromLang !== 'zh-CN') {
					toLang = 'zh-CN';
				}
				_translate(toLang, _translateInitCallback);
			} else {
				self.endSearch(searchString, null, "google_translate");
			}
		}
		
		function _translate(toLang, callback) {
			contentAPI.ajax({
				url: 'http://ajax.googleapis.com/ajax/services/language/translate',
				method: 'POST',
				dataType: 'json',
				timeout: 5000,
				data: {
					v: "1.0",
					q: searchString,
					langpair: "|" + toLang,
					key: 'ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw'
				},
				beforeSend: function(request) {
					contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
				},
				success: function(data){
					callback(data, toLang);
				},
				error: function(request, status, errorThrown) {
					callback(null, toLang);
				}
			});
		}
		
		function _translateInitCallback(data, toLang) {
			try {
				var status = 'fail';
				if (data && data.responseStatus === 200) {
					var gtResult = {
						entry: {
							toLanguage: self.stripXss(code2name[toLang] ? code2name[toLang] : toLang),
							text: self.stripXss(data.responseData.translatedText)
						}
					};
					
					var template = unescape($('#googletrans-template').html());
					var gtContent = $('<div>').attr('id', 'googletrans-content');
					gtContent.html(TrimPath.parseTemplate(template).process(gtResult));
					for (var langCode in code2name) {
						if (langCode !== fromLang) {
							$('#googletrans-tlcode', gtContent).
								addOption(langCode, "翻译为 " + code2name[langCode]);						
						}
					}
					$('#googletrans-tlcode', gtContent).selectOptions(toLang);
					$('#googletrans-tlcode', gtContent).change(function() {
						$('.googletrans-item', gtContent).text('正在读取...');
						_translate($('#googletrans-tlcode', gtContent).selectedValues(), _translateSelectCallback);
					});
					$('.googletrans-button', gtContent).attr('href', transPageLinkBase + "sl=&tl=" + toLang);
					
					section.addResultPage(
								'谷歌翻译', 
								'google-section', 
								'googletrans-content', 
								gtContent, 
								'http://www.google.cn/favicon.ico',
								'http://translate.google.cn/translate_t?text=' + encodeURIComponent(searchString),
								rank);
					status = 'success';
				}
			} finally {
				self.endSearch(searchString, status, "google_translate");
			}
		}
		
		function _translateSelectCallback(data, toLang) {
			var gtContent = $('#googletrans-content');
			if (data && data.responseStatus === 200) {
				var innerHtml = "<span>" + self.stripXss(code2name[toLang] ? code2name[toLang] : toLang)
						+ "</span> " 
						+ self.stripXss(data.responseData.translatedText);
				$('.googletrans-item', gtContent).html(innerHtml);
			} else {
				$('.googletrans-item', gtContent).text("发生错误，或者试试翻译成其他语言~~");
			}
			$('.googletrans-button', gtContent).attr('href', transPageLinkBase + "sl=&tl=" + toLang);
		}
		
		_detectLangCode();
	},
	
	/** pictures section **/
	
	searchFlickr: function(searchString, section, rank){
		var self = this;
		self.beforeSearch(searchString, "Flickr");
		
		contentAPI.ajax({
			url: "http://api.flickr.com/services/rest?method=flickr.photos.search&api_key=33db8eb821f12753b480df732f0e3b11&text=" + encodeURIComponent(searchString) + "&sort=relevance&per_page=8&format=json&nojsoncallback=1",
			method: 'GET',
			dataType: 'json',
			timeout: 5000,
			beforeSend: function(request) {
			},
			success: function(data){
				try {
					var status = 'fail';
					if (data.photos && data.photos.total > 0) {
						var template = unescape($('#flickr-template').html());
						var templateObject = TrimPath.parseTemplate(template);
						var flickrResult = {
							photos: [],
							queryLink: "http://www.flickr.com/search/?q=" + encodeURIComponent(searchString) + "&m=text"
						};
						for (var i = 0; i < data.photos.photo.length; i += 1) {
							var photo = data.photos.photo[i];
							var link = "http://www.flickr.com/photos/" + photo.owner + "/" + photo.id;
							var thumbnail = "http://farm" + photo.farm + ".static.flickr.com/" + photo.server + "/" + photo.id + "_" + photo.secret + "_s.jpg";
							flickrResult.photos.push({
								link: link,
								thumbnail: thumbnail
							});
						}
						var flickrContent = $('<div>').attr('id', 'flickr-content');
						flickrContent.html(templateObject.process(flickrResult));
						section.addResultPage(
									'Flickr', 
									'flickr-section', 
									'flickr-content', 
									flickrContent, 
									'http://www.flickr.com/favicon.ico',
									flickrResult.queryLink,
									rank);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "Flickr");
				}
			},
			error: function(data) {
				self.endSearch(searchString, null, "Flickr");
			}
		});
	},
	
	searchGoogleImage: function(searchString, section, rank){
		var self = this;
		self.beforeSearch(searchString, "google_image");
		
		function pageInitFunc() {
			var images = $('#googleimage-content').find('img');
			if (images) {
				for (var i = 0; i < images.length; i += 1) {
					self.loadImage(images[i]);
				}
			}
		}
		
		contentAPI.ajax({
			url: "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=" + encodeURIComponent(searchString) + "&key=ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw&hl=zh-CN&rsz=large",
			method: 'GET',
			dataType: "json",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data) {
				try {
					var status = 'fail';
					if (data.responseStatus === 200 && data.responseData.results.length > 0) {
						var giResult = {
							photos: []
						};
						var imageCount = 8;
						for (var i = 0; i < data.responseData.results.length && i < imageCount; i+= 1) {
							var photo = data.responseData.results[i];
							giResult.photos.push({
								link: photo.originalContextUrl,
								thumbnail: photo.unescapedUrl
							});
						}
						var template = unescape($('#googleimage-template').html());
						var giContent = $('<div>').attr('id', 'googleimage-content');
						giContent.html(TrimPath.parseTemplate(template).process(giResult));
						$("img", giContent).load(function() {
							SearchPage.loadImage(this);	
						});
						
						section.addResultPage(
									'谷歌图片',
									'google-section',
									'googleimage-content',
									giContent,
									'http://www.google.cn/favicon.ico',
									'http://images.google.cn/images?q=' + encodeURIComponent(searchString),
									rank,
									pageInitFunc);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "google_image");
				}
			},
			error: function(data) {
				self.endSearch(searchString, null, "google_image");
			}
		});
	},
	
	searchTaobaoImgo: function(searchString, section, rank){
		var self = this;
		self.beforeSearch(searchString, "taobao_imgo");
		
		function pageInitFunc() {
			var images = $('#taobaoimgo-content').find('img');
			if (images) {
				for (var i = 0; i < images.length; i += 1) {
					self.loadImage(images[i]);
				}
			}
		}
		
		var link = contentAPI.newURI('http://go.taobao.com/browse/list_data.htm?title=' + searchString, "GB2312", null).spec;
		contentAPI.ajax({
			url: link,
			method: "GET",
			dataType: "json",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data) {
				try {
					var status = 'fail';
					if ("total" in data && data.total > 3) {
						// we won't show anything if there are not many items
						var imgoResult = {
							photos: []
						};
						var imgoCount = 8;
						for (var i = 0; i < data.data.length && i < imgoCount; i += 1) {
							var cloth = data.data[i];
							imgoResult.photos.push({
								thumbnail: cloth["smallThumbnailsTfs_80"],
								link: contentAPI.newURI("http://go.taobao.com/browse/compare.htm?sort=default&type=compare&id=" + cloth['id'] + "&mode=1&title=" + searchString + "&imgUrl=" + cloth['representSmallThumbnail'] + "&catId=16", "GB2312", null).spec
							});
						}
						var template = unescape($('#googleimage-template').html());
						var imgoContent = $('<div>').attr('id', 'taobaoimgo-content');
						imgoContent.html(TrimPath.parseTemplate(template).process(imgoResult));
						section.addResultPage(
									'淘宝看图购',
									'taobao-section',
									'taobaoimgo-content',
									imgoContent,
									'http://www.taobao.com/favicon.ico',
									'http://go.taobao.com/',
									rank,
									pageInitFunc);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "taobao_imgo");
				}
			},
			error: function(data) {
				self.endSearch(searchString, null, "taobao_imgo");
			}
		});
	},
	
	/*** video section ***/
	searchYouku: function(searchString, section, rank){
		var self = this;
		self.beforeSearch(searchString, "youku");
		
		contentAPI.ajax({
			url: "http://api.youku.com/api_ptvideo/pid_XNTk2_rt_1_tp_1_st_3_sv_" + encodeURIComponent(searchString) + "_pg_1_pz_10_ob_6_od_0_pd_4.html",
			method: "GET",
			dataType: "text",
			timeout: 5000,
			cache: false,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data){
				try {
					var status = 'fail';
					
					// Here be dragons
					// don't know why Firefox 3.5.2 doesn't handle encoding=utf-8 xml well and responseXML = null
					var dataText = data.substring('<?xml version="1.0" encoding="utf-8"?>'.length);
					dataText = dataText.replace(/\<\!\[CDATA\[/g, "");
					dataText = dataText.replace(/\]\]\>/g, "");
					var fakeDoc = $('<div>' + dataText);
					if (fakeDoc) {
						var items = fakeDoc.find("widget > items");
						var videoCount = 4;
						var youkuResult = {
							videos: []
						};
						for (var i = 0; i < videoCount && i < items.length; i += 1) {
							var videoName = $('VideoName', items[i]).text();
							var videoThumbnail = $('VideoPicture', items[i]).text();
							var videoLink = $('VideoURL', items[i]).text();
	
							var matches = videoLink.match(/^(.*)\/sid\/([^\/]*)\/v.swf$/);
							videoLink = "http://v.youku.com/v_show/id_" + matches[2] + ".html"; 
	
							youkuResult.videos.push({
								name: self.stripXss(videoName),
								thumbnail: videoThumbnail,
								link: videoLink
							});
						}					
					}
					if (youkuResult.videos.length > 0) {
						var template = unescape($('#video-template').html());
						var youkuContent = $('<div>').attr('id', 'youku-content');
						youkuContent.html(TrimPath.parseTemplate(template).process(youkuResult));
						section.addResultPage(
									'优酷网',
									'youku-section',
									'youku-content',
									youkuContent,
									'http://www.youku.com/favicon.ico',
									'http://so.youku.com/search_video/q_' + encodeURIComponent(searchString),
									rank);
						status = "success";
					}
				} finally {
					self.endSearch(searchString, status, "youku");
				}
			},
			error: function(request, status, errorThrown){
				self.endSearch(searchString, null, "youku");
			},
		});
	},
	
	searchTudou: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "tudou");
		
		contentAPI.ajax({
			url: "http://api.tudou.com/v2/i/search?channelId=0&inDays=all&sort=s&page=1&format=json&apikey=firefox-731529dcf094aa39188232a0376ac2f5&kw=" + encodeURIComponent(searchString),
			method: "GET",
			dataType: "json",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data){
				try {
					var status = 'fail';
					if (data.length > 1 && data[0] === 2000) {
						if (data[1].length > 0 && data[1][0] > 0) {
							var results = data[1][1];
							
							var videoCount = 4;
							var tudouResult = {
								videos: []
							};
							for (var i = 0; i < videoCount && i < results.length; i += 1) {
								tudouResult.videos.push({
									name: self.stripXss(results[i].title),
									thumbnail: results[i].picUrl,
									link: results[i].itemUrl
								});
							}
							
							if (tudouResult.videos.length > 0) {
								var template = unescape($('#video-template').html());
								var tudouContent = $('<div>').attr('id', 'tudou-content');
								tudouContent.html(TrimPath.parseTemplate(template).process(tudouResult));
								section.addResultPage(
									'土豆网',
									'tudou-section',
									'tudou-content',
									tudouContent,
									'http://www.tudou.com/favicon.ico',
									'http://so.tudou.com/isearch.do?kw=' + encodeURIComponent(searchString),
									rank);	
								status = 'success';						
							}
						}
					}
				} finally {
					self.endSearch(searchString, status, "tudou");
				}
			},
			error: function(data){
				self.endSearch(searchString, null, "tudou");
			},
		});
	},
	
	searchGoogleVideo: function(searchString, section, rank){
		var self = this;
		self.beforeSearch(searchString, "google_video");
		
		contentAPI.ajax({
			url: "http://ajax.googleapis.com/ajax/services/search/video?v=1.0&q=" + encodeURIComponent(searchString) + "&key=ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw&hl=zh-CN",
			method: "GET",
			dataType: "json",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data){
				try {
					var status = 'fail';
					if (data.responseStatus === 200 && data.responseData.results.length > 0) {
						var gvResult = {
							videos: []
						};
						var videoCount = 4;
						for (var i = 0; i < videoCount && i < data.responseData.results.length; i += 1) {
							var video = data.responseData.results[i];
							gvResult.videos.push({
								name: self.stripXss(video.titleNoFormatting),
								thumbnail: video.tbUrl,
								link: video.url
							});
						}
						var template = unescape($('#video-template').html());
						var gvContent = $('<div>').attr('id', 'googlevideo-content');
						gvContent.html(TrimPath.parseTemplate(template).process(gvResult));
						section.addResultPage(
									'谷歌视频',
									'google-section',
									'googlevideo-content',
									gvContent,
									'http://www.google.com/favicon.ico',
									'http://video.google.cn/videosearch?q=' + encodeURIComponent(searchString),
									rank);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "google_video");
				}
			},
			error: function(data){
				self.endSearch(searchString, null, "google_video");
			},
		});
	},
	
	/*** information section ***/
	searchGoogleNews: function(searchString, section, rank){
		var self = this;
		self.beforeSearch(searchString, "google_news");
		
		contentAPI.ajax({
			url: "http://ajax.googleapis.com/ajax/services/search/news?v=1.0&q=" + encodeURIComponent(searchString) + "&key=ABQIAAAASCaOeo3ta_dogUbwquyfCxSpqFEWLxmF2C8ASAeMYkWcm8RXShQKtE5gb4GQJT6JrnWVPp5dE67yyw&hl=zh-CN&rsz=large&ned=cn",
			method: "GET",
			dataType: "json",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data){
				try {
					var status = 'fail';
					if (data.responseStatus === 200 && data.responseData.results.length > 0) {
						var gnResults = {
							items: []
						};
						var newsCount = 6;
						for (var i = 0 ; i < data.responseData.results.length && i < newsCount; i += 1) {
							var item = data.responseData.results[i];
							gnResults.items.push({
								link: item.unescapedUrl,
								title: self.stripXss(item.titleNoFormatting)
							});						
						}
						var template = unescape($('#googlenews-template').html());
						var gnContent = $('<div>').attr('id', 'googlenews-content');
						gnContent.html(TrimPath.parseTemplate(template).process(gnResults));
						section.addResultPage(
										'谷歌资讯',
										'googlenews-section',
										'googlenews-content',
										gnContent,
										'http://www.gstatic.cn/news/img/favicon.ico',
										'http://news.google.cn/news/search?q=' + encodeURIComponent(searchString),
										rank);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "google_news");
				}
			},
			error: function(data){
				self.endSearch(searchString, null, "google_news");
			},
		});
	},
	
	searchStockQuote: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "stock");
		
		function loadSinaData(ids) {
			contentAPI.ajax({
				url: "http://hq.sinajs.cn/list=" + ids.join(","),
				method: "GET",
				dataType: "text",
				timeout: 5000,
				success: function(text) {
					var dataSets = text.split(";");
					for (var i = 0; i < dataSets.length; i += 1) {
						var content = jQuery.trim(dataSets[i]);
						if (content && content.length > 0) {
							var id = content.substring("var hq_str_".length, content.indexOf("="));
							var data = content.substring(content.indexOf('\"') + 1, content.length - 1).split(',');
							var currValue = data[3];
							var oldValue = data[2];
							
							$("#stock-" + id + " .stock-curr-value").text(currValue);
							$("#stock-" + id + " .stock-diff").text((currValue > oldValue ? "+" : "") + (currValue - oldValue).toFixed(2));
							$("#stock-" + id + " .stock-percentage").text(((currValue - oldValue) / oldValue * 100).toFixed(2) + "%");
							
							if (currValue >= oldValue) {
								$("#stock-" + id + " .stock-diff").addClass("stock-up");
								$("#stock-" + id + " .stock-percentage").addClass("stock-up");
							} else {
								$("#stock-" + id + " .stock-diff").addClass("stock-down");
								$("#stock-" + id + " .stock-percentage").addClass("stock-down");
							}
						}
					}
				},
				error: function(request, status) {
				},
			});
		}
		
		function displayStocks(stocks) {
			var template = unescape($('#stock-template').html());
			var stockContent = $('<div>').attr('id', 'stock-content');
			var result = {
				stocks: stocks
			}
			stockContent.html(TrimPath.parseTemplate(template).process(result));
			section.addResultPage(
				'股票财经',
				'stock-section',
				'stock-content',
				stockContent,
				'http://www.sina.com.cn/favicon.ico',
				'http://www.google.cn/finance?q=' + encodeURIComponent(searchString),
				rank);
			
			var sinaIds = [];
			for (var i = 0; i < stocks.length; i += 1) {
				if (stocks[i].market === "sz" || stocks[i].market === "sh") {
					sinaIds.push(stocks[i].id);
				}
			}
			
			if (sinaIds.length > 0) {
				loadSinaData(sinaIds);
			}
		}
		
		function createStockLink(token, market) {
			var link = "";
			if (market === 'sz') {
				link = "http://finance.sina.com.cn/realstock/company/sz" + token + "/nc.shtml"
			} else if (market === "sh") {
				link = "http://finance.sina.com.cn/realstock/company/sh" + token + "/nc.shtml"
			}
			return link;
		}
		
		// get match from Google Finance
		contentAPI.ajax({
			url: "http://www.google.cn/finance/match?matchtype=matchall&q=" + encodeURIComponent(searchString),
			method: "GET",
			dataType: "json",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data){
				try {
					var status = 'fail';
					if (data && data.matches && data.matches.length > 0) {
						var maxCount = 6;
						var stocks = [];
						for (var i = 0; i < data.matches.length; i += 1) {
							var stockName = "";
							if (data.matches[i].sugg && data.matches[i].sugg.length > 3) {
								stockName = data.matches[i].sugg[3];
							}
							if (!stockName || stockName.length === 0) {
								stockName = data.matches[i].n;
							}
							var stockToken = data.matches[i].t;
							var stockMarket = data.matches[i].e;
							if (stockMarket === "SHE") { stockMarket = 'sz'; }
							if (stockMarket === "SHA") { stockMarket = 'sh'; }
	
							if (stockMarket === "sz" || stockMarket === "sh") {
								stocks.push({
									name: self.stripXss(stockName),
									token: self.stripXss(stockToken),
									market: self.stripXss(stockMarket),
									id: self.stripXss(stockMarket + stockToken),
									link: createStockLink(stockToken, stockMarket)
								});							
							}
							
							if (stocks.length >= maxCount) break;
						}
						
						if (stocks.length > 0) {
							status = 'success';
							displayStocks(stocks);
						}
					}
				} finally {
					self.endSearch(searchString, status, "stock");
				}
			},
			error: function(request, status) {
				self.endSearch(searchString, null, "stock");
			},
		});
	},
	
	searchVerycd: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "verycd");
		
		contentAPI.ajax({
			url: "http://www.verycd.com/search/folders?format=rss&kw=" + encodeURIComponent(searchString),
			method: "GET",
			dataType: "text",
			timeout: 5000,
			cache: false,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(text){
				try {
					var data = jQuery.parseXML(text);
					var status = 'fail';
					var items = $(data).find('rss > channel > item');
					if (items && items.length > 0) {
						var itemCount = 3;
						var veryResult = {
							items: []
						};
						for (var i = 0; i < itemCount && i < items.length; i += 1) {
							veryResult.items.push({
								title: self.stripXss($('title', items[i]).text()),
								link: $('link', items[i]).text(),
								detail: self.stripXss($('description', items[i]).text().substring(0, 50)),
								thumbnail: $('enclosure', items[i]).attr('url')
							});
						}
						var template = unescape($('#verycd-template').html());
						var veryContent = $('<div>').attr('id', 'verycd-content');
						veryContent.html(TrimPath.parseTemplate(template).process(veryResult));
						section.addResultPage(
										'VeryCD电驴',
										'verycd-section',
										'verycd-content',
										veryContent,
										'http://www.verycd.com/favicon.ico',
										'http://www.verycd.com/search/folders/' + encodeURIComponent(searchString),
										rank);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "verycd");
				}
			},
			error: function(data){
				self.endSearch(searchString, null, "verycd");
			},
		});
	},
	
	searchDouban: function(searchString, api, apiCallback, doneCallback) {
		contentAPI.ajax({
			url: "http://api.douban.com/" + api + "/subjects?max-results=2&apikey=095eb11237aa6d291c1c1336a6ff477b&alt=json&q=" + encodeURIComponent(searchString),
			method: "GET",
			dataType: "json",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(data){
				if ('entry' in data && data.entry.length > 0) {
					var doubanResult = {
						items: []
					};
					for (var i = 0; i < data.entry.length; i += 1) {
						var item = data.entry[i];
						doubanResult.items.push(apiCallback(item));
					}
					doneCallback(doubanResult);
				} else {
					doneCallback(null);
				}
			},
			error: function(data){
				doneCallback(null);
			},
		});
	},
	
	searchDoubanBook: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "douban_book");
		
		function getBookObject(item) {
			var book = {
				title: self.stripXss(item.title['$t']),
				detail: '',
				rating: self.stripXss(item['gd:rating']['@average']),
				ratecount: self.stripXss(item['gd:rating']['@numRaters']),
				id: self.stripXss(item.id['$t']).substring("http://api.douban.com/book/subject/".length),
				link: 'http://www.douban.com/subject/',
				thumbnail: ''
			};
			book.link += book.id;
			
			var attributes = item['db:attribute'];
			var attMap = {};
			for (var j = 0; j < attributes.length; j += 1) {
				if (attributes[j]['@name'] === 'author') {
					if (!('author' in attMap)) {
						attMap['author'] = '';
					}
					attMap['author'] += attributes[j]["$t"] + " ";
				} else {
					attMap[attributes[j]['@name']] = attributes[j]['$t'];
				}
			}
			var x = [];
			if (attMap['author']) x.push(self.stripXss(attMap.author));
			if (attMap['pubdate']) x.push(self.stripXss(attMap.pubdate));
			if (attMap['publisher']) x.push(self.stripXss(attMap.publisher));
			book.detail = x.join(" / ");
			
			var links = item['link'];
			for (var j = 0; j < links.length; j += 1) {
				if (links[j]['@rel'] === 'alternate') {
					book.link = links[j]['@href'];
				} else if (links[j]['@rel'] === 'image') {
					book.thumbnail = links[j]['@href'];
				}
			}
			if (!book.thumbnail) book.thumbnail = "http://t.douban.com/pics/book-default-small.gif";
			
			return book;
		}
		
		function doneCallback(data) {
			var status = 'fail';
			try {
				if (data) {
					var template = unescape($('#douban-template').html());
					var dbContent = $('<div>').attr('id', 'doubanbook-content');
					dbContent.html(TrimPath.parseTemplate(template).process(data));
					section.addResultPage(
									'豆瓣图书',
									'douban-section',
									'doubanbook-content',
									dbContent,
									'http://www.douban.com/favicon.ico',
									'http://www.douban.com/subject_search?cat=1001&search_text=' + encodeURIComponent(searchString),
									rank);
					status = 'success';
				}
			} finally {
				self.endSearch(searchString, status, "douban_book");
			}
		}
		
		this.searchDouban(searchString, 'book', getBookObject, doneCallback);
	},
	
	searchDoubanMovie: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "douban_movie");
		
		function getMovieObject(item) {
			var movie = {
				title: self.stripXss(item.title['$t']),
				detail: '',
				rating: self.stripXss(item['gd:rating']['@average']),
				ratecount: self.stripXss(item['gd:rating']['@numRaters']),
				id: self.stripXss(item.id['$t']).substring("http://api.douban.com/movie/subject/".length),
				link: 'http://www.douban.com/subject/',
				thumbnail: ''
			};
			movie.link += movie.id;
			
			var attributes = item['db:attribute'];
			var attMap = {};
			for (var j = 0; j < attributes.length; j += 1) {
				if (attributes[j]['@name'] === 'author') {
					if (!('author' in attMap)) {
						attMap['author'] = '';
					}
					attMap['author'] += attributes[j]["$t"] + " ";
				} else if (attributes[j]['@name'] === 'cast') {
					if (!('cast' in attMap)) {
						attMap['cast'] = '';
					}
					attMap['cast'] += attributes[j]["$t"] + " ";
				} else {
					attMap[attributes[j]['@name']] = attributes[j]['$t'];
				}
			}
			var x = [];
			if (attMap['aka']) x.push(self.stripXss(attMap.aka));
			if (attMap['country']) x.push(self.stripXss(attMap.country));
			if (attMap['language']) x.push(self.stripXss(attMap.language));
			if (attMap['cast']) x.push(self.stripXss(attMap.cast.substring(0, 20)));
			if (attMap['author']) x.push(self.stripXss(attMap.author));
			if (attMap['pubdate']) x.push(self.stripXss(attMap.pubdate));
			movie.detail = x.join(" / ");
			
			var links = item['link'];
			for (var j = 0; j < links.length; j += 1) {
				if (links[j]['@rel'] === 'alternate') {
					movie.link = links[j]['@href'];
				} else if (links[j]['@rel'] === 'image') {
					movie.thumbnail = links[j]['@href'];
				}
			}
			if (!movie.thumbnail) movie.thumbnail = "http://t.douban.com/pics/movie-default-small.gif";
			
			return movie;
		}
		
		function doneCallback(data) {
			var status = 'fail';
			try {
				if (data) {
					var template = unescape($('#douban-template').html());
					var dbContent = $('<div>').attr('id', 'doubanmovie-content');
					dbContent.html(TrimPath.parseTemplate(template).process(data));
					section.addResultPage(
									'豆瓣电影',
									'douban-section',
									'doubanmovie-content',
									dbContent,
									'http://www.douban.com/favicon.ico',
									'http://www.douban.com/subject_search?cat=1002&search_text=' + encodeURIComponent(searchString),
									rank);
					status = 'success';
				}
			} finally {
				self.endSearch(searchString, status, "douban_movie");
			}
		}
		
		this.searchDouban(searchString, 'movie', getMovieObject, doneCallback);
	},
	
	/*** lifestyle section ***/
	searchLocalInfor: function(searchString, section, rank) {
		// we don't use geolocation for aibang		
		var self = this;
		self.beforeSearch(searchString, "aibang");
		
		var params = {
			cmd: "bizsearch",
			q: encodeURIComponent(searchString),
			format: 'xml',
			appkey: 'firefox',
			strict: '1'
		};

		var requestLink = "http://api.aibang.com/?";
		requestLink += [[key, params[key]].join('=') for (key in params)].join('&');
		
		contentAPI.ajax({
			url: requestLink,
			method: 'GET',
			dataType: 'text',
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(text) {
				try {
					var data = jQuery.parseXML(text);
					var status = 'fail';
					
					var resultCount = parseInt($('search > result_num', data).text());
					if (resultCount > 0) {
						var results = $('search > docs > doc', data);
						var localResults = {
								locals: []
						};
						var maxCount = 3;
						for (var i = 0; i < results.length && i < maxCount; i += 1) {
							localResults.locals.push({
								name: jQuery.trim(self.stripXss($('name', results[i]).text())),
								address: jQuery.trim(self.stripXss($('addr', results[i]).text())),
								description: jQuery.trim(self.stripXss($('desc', results[i]).text())),
								link: "http://aibang.com/detail/" + $('bizid', results[i]).text()
							});
						}
							
						var template = unescape($('#local-template').html());
						var localContent = $('<div>').attr('id', 'local-content');
						localContent.html(TrimPath.parseTemplate(template).process(localResults));
						section.addResultPage(
									'爱帮本地搜索',
									'local-section',
									'local-content',
									localContent,
									'http://aibang.com/favicon.ico',
									'http://aibang.com/?area=bizsearch&cmd=bigmap&q=' + encodeURIComponent(searchString),
									rank);
						status = 'success';							
					}
				} catch (e) {
					alert(e);
				} finally {
					self.endSearch(searchString, status, "aibang");
				}
			},
			error: function(request, status) {
				contentAPI.log(status);
				self.endSearch(searchString, null, "aibang");
			},
		});
	},
	
	searchYoudaoGouwu: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "youdao_gouwu");
		
		var params = {
			q: encodeURIComponent(searchString),
			doctype: 'xml',
			keyfrom: 'firefox',
			ue: 'utf8'
		};

		var requestLink = "http://gouwu.youdao.com/search?";
		requestLink += [[key, params[key]].join('=') for (key in params)].join('&');
		
		function showItemDetail(items, index, block) {
			if (index < 0 || index >= items.length)
				return;
				
			var template = unescape($('#youdao-marketplace-template').html());
			var renderObj = {
				product: items[index]
			};
			block.html(TrimPath.parseTemplate(template).process(renderObj));
		}
		
		contentAPI.ajax({
			url: requestLink,
			method: 'GET',
			dataType: 'text',
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(text) {
				try {
					var data = jQuery.parseXML(text);
					var status = 'fail';
					var results = $('response > hits > hit', data);
					if (results.length > 0) {
						var maxCount = 5;
						var products = {
							products: []
						};
						for (var i = 0; i < maxCount && i < results.length; i += 1) {
							var product = {};
							product['name'] = jQuery.trim(self.stripXss($('name', results[i]).text()));
							product['maxprice'] = jQuery.trim(self.stripXss($('maxPrice', results[i]).text()));
							product['minprice'] = jQuery.trim(self.stripXss($('minPrice', results[i]).text()));
							product['sitecount'] = jQuery.trim(self.stripXss($('siteCount', results[i]).text()));
							product['thumbnail'] = jQuery.trim($('imageUrl', results[i]).text());
							product['link'] = jQuery.trim($('sumUrl', results[i]).text());
							
							products.products.push(product);
						}
						var template = unescape($('#youdao-gouwu-template').html());
						var gouwuContent = $('<div>').attr('id', 'youdao-gouwu-content');
						gouwuContent.html(TrimPath.parseTemplate(template).process(products));
						section.addResultPage(
										'有道购物',
										'youdao-section',
										'youdao-gouwu-content',
										gouwuContent,
										'http://shared.youdao.com/images/favicon.ico',
										'http://gouwu.youdao.com/search?q=' + encodeURIComponent(searchString) + '&keyfrom=firefox&ue=utf8',
										rank);
						status = 'success';
						
						gouwuContent.find('img').each(function(index) {
							$(this).click(function() {
								showItemDetail(products.products, index, $('#youdao-gouwu-marketplace', gouwuContent));
							});
						})
						showItemDetail(products.products, 0, $('#youdao-gouwu-marketplace', gouwuContent));
						
					}
				} finally {
					self.endSearch(searchString, status, "youdao_gouwu");
				}
			},
			error: function(request, status) {
				self.endSearch(searchString, null, "youdao_gouwu");
			},
		});
	},
	
	searchBuy360: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "360buy");
		function showItemDetail(items, index, block) {
			if (index < 0 || index >= items.length)
				return;
				
			var template = unescape($('#marketplace-template').html());
			var renderObj = {
				item: items[index]
			};
			renderObj.item.mall = "京东";
			block.html(TrimPath.parseTemplate(template).process(renderObj));
		}
		
		contentAPI.ajax({
			url: "http://search.360buy.com/interface/firefox?product=" + encodeURIComponent(searchString),
			method: "GET",
			dataType: "text",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(text){
				var status = 'fail';
				try {
					var data = jQuery.parseXML(text);
					var items = $('widget > items > item', data);
					if (items.length > 0) {
						var buyResult = {
							items: []
						};
						var itemCount = 5;
						for (var i = 0; i < items.length && i < itemCount; i += 1) {
							var itemName = $('name', items[i]).text();
							var itemDescription = $('describe', items[i]).text().substring(0, 100) + "...";
							var itemThumbnail = $('image', items[i]).text();
							var itemCommonPrice = $('commonprice', items[i]).text();
							itemCommonPrice = itemCommonPrice.substring(0, itemCommonPrice.length - 2);
							var itemMyPrice = $('myprice', items[i]).text();
							itemMyPrice = itemMyPrice.substring(0, itemMyPrice.length - 2);
							var itemLink = $('link', items[i]).text();
							buyResult.items.push({
								name: self.stripXss(itemName),
								description: self.stripXss(itemDescription),
								commonprice: self.stripXss(itemCommonPrice),
								myprice: self.stripXss(itemMyPrice),
								link: itemLink,
								thumbnail: itemThumbnail
							});
						}
						var template = unescape($('#buy360-template').html());
						var buyContent = $('<div>').attr('id', 'buy360-content');
						buyContent.html(TrimPath.parseTemplate(template).process(buyResult));
						section.addResultPage(
										'京东商城',
										'buy360-section',
										'buy360-content',
										buyContent,
										'http://www.360buy.com/favicon.ico',
										contentAPI.getFullSpec('http://search.360buy.com/Search?keyword=' + searchString, 'GB2312', null),
										rank);
						status = 'success';
						buyContent.find('img').each(function(index) {
							$(this).click(function() {
								showItemDetail(buyResult.items, index, $('#buy360-marketplace', buyContent));
							});
						})
						showItemDetail(buyResult.items, 0, $('#buy360-marketplace', buyContent));
					}
				} finally {
					self.endSearch(searchString, status, "360buy");
				}
			},
			error: function(request, status, errorThrown){
				contentAPI.log("buy360 service error: " + status);
				self.endSearch(searchString, null, "360buy");
			},
		});
	},

	searchBettyKitchen: function(searchString, section, rank) {
		var self = this;
		self.beforeSearch(searchString, "bettykitchen");
		
		contentAPI.ajax({
			url: "http://www.bettyskitchen.com.cn/rss/search/recipe/?main_ingredient=_all&cuisine=_all&q=" + encodeURIComponent(searchString),
			method: "GET",
			dataType: "text",
			timeout: 5000,
			beforeSend: function(request) {
				contentAPI.setRequestHeader(request, "Referer", "http://g-fox.cn/");
			},
			success: function(text){
				try {
					var data = jQuery.parseXML(text);
					var status = 'fail';
					var items = $(data).find('rss > channel > item');
					if (items && items.length > 0) {
						var itemCount = 3;
						var bkResult = {
							recipes: []
						};
						for (var i = 0; i < itemCount && i < items.length; i += 1) {
							var itemTitle = $('title', items[i]).text();
							var itemLink = $('link', items[i]).text();
							
							var itemDescription = $('description', items[i]).text();
							var fakeDoc = $('<div>').html(itemDescription);
							var itemThumbnail = $('img', fakeDoc).attr('src');
							var itemDetail = $('p', fakeDoc).text().substring(0, 60);
							var itemRank = $('li', fakeDoc).text().substring(0, 6);
							
							bkResult.recipes.push({
								title: self.stripXss(itemTitle + " (" + itemRank + ")"),
								link: itemLink,
								thumbnail: itemThumbnail,
								detail: self.stripXss(itemDetail)
							});
						}
						
						var template = unescape($('#bettykitchen-template').html());
						var bkContent = $('<div>').attr('id', 'bettykitchen-content');
						bkContent.html(TrimPath.parseTemplate(template).process(bkResult));
						section.addResultPage(
										'贝太厨房',
										'bettykitchen-section',
										'bettykitchen-content',
										bkContent,
										'chrome://marginbox/skin/images/bettykitchen.png',
										'http://www.bettyskitchen.com.cn/search/recipe/?cuisine=_all&main_ingredient=_all&q=' + encodeURIComponent(searchString),
										rank);
						status = 'success';
					}
				} finally {
					self.endSearch(searchString, status, "bettykitchen");
				}
			},
			error: function(request, status){
				contentAPI.log("betty kitchen service error: " + status);
				self.endSearch(searchString, null, "bettykitchen");
			},
		});
	},
	
	loadImage: function(img) {
		var container = img.parentNode;
		$(container).height($(container).width());
		if (img.offsetWidth > img.offsetHeight) {
			img.style.height = "100%";
		} else {
			img.style.width = "100%";
		}
	},
};

function SearchSection(id) {
	this.id = id;
	this.results = {};
	this.activeId = '';
}

SearchSection.prototype = {
	ignoreRank: true,
	
	init: function() {
		var template = $('#section-template').html();
		var sectionDiv = $("<div>")
						.attr('id', this.id)
						.html(template)
						.hide();
		$('#content').append(sectionDiv);
	},
	
	addResultPage: function(title, pageClass, pageId, pageHtml, pageIcon, pageLink, rank, initFunc) {
		var sectionDiv = $("#" + this.id);
		var header = $(".container-header", sectionDiv);
		
		this.results[pageId] = {
			pageTitle: title,
			pageClass: pageClass,
			pageId: pageId,
			pageIcon: pageIcon,
			pageLink: pageLink,
			pageRank: rank,
			pageInitFunc: initFunc
		};
		if (this.activeId === '') {
			sectionDiv.append(pageHtml);
			sectionDiv.append($('<div>').attr('style', 'clear:both;'));
			
			sectionDiv.show();
			this.activeId = pageId;
			// update title and active section
			
			var chActive = $('.ch-active-section', header);
			chActive.addClass(pageClass);
			var chTitle = $('.ch-active-title', header);
			var titleLink = $('<a>').attr('href', pageLink)
					.attr('target', '_blank')
					.attr('title', '浏览器打开' + title + '搜索结果')
					.text(title);
			chTitle.html($('<div>').append(titleLink).html());
			
			if (initFunc) {
				initFunc();
			}
		} else {
			pageHtml.hide();
			sectionDiv.append(pageHtml);
			sectionDiv.append($('<div>').attr('style', 'clear:both;'));
			
			// update inactive-section
			this.addInactiveButton(pageId, pageIcon, title);
			
			// compare the rank with activePage, if lower than it, change to active
			if (!this.ignoreRank) {
				if (rank < this.results[this.activeId].pageRank) {
					this.switchToPage(pageId);
				}				
			}
		}
	},
	
	addInactiveButton: function(pageId, pageIcon, pageTitle){
		var sectionDiv = $("#" + this.id);
		var header = $(".container-header", sectionDiv);
		
		var chInactive = $('.ch-inactive-section', header);
		var inactiveIcon = $('<img>').attr('src', pageIcon).css('border', '0');
		var button = $('<a>').attr('href', 'javascript:void(0);')
					.attr('id', 'button-' + pageId)
					.attr('title', pageTitle)
					.css('margin-left', '4px')
					.append(inactiveIcon);

		var self = this;
		button.click(function() {
			self.switchToPage(pageId);
		});
			
		chInactive.append(button);
	},
	
	switchToPage: function(pageId){
		var sectionDiv = $("#" + this.id);
		var header = $(".container-header", sectionDiv);
		
		// update active header
		var chActive = $('.ch-active-section', header);
		chActive.removeClass(this.results[this.activeId].pageClass);
		chActive.addClass(this.results[pageId].pageClass);
		var chTitle = $('.ch-active-title', header);
		var titleLink = $('<a>')
					.attr('href', this.results[pageId].pageLink)
					.attr('target', '_blank')
					.attr('title', '浏览器打开' + this.results[pageId].pageTitle + '搜索结果')
					.text(this.results[pageId].pageTitle);
		chTitle.html($('<div>').append(titleLink).html());
		
		// update inactive header
		var chInactive = $('.ch-inactive-section', header);
		chInactive.html('');
		for (var id in this.results) {
			if (id === pageId) {
				continue;
			}
			
			this.addInactiveButton(id, this.results[id].pageIcon, this.results[id].pageTitle);
		}
		
		// update content section
		$("#" + this.activeId, sectionDiv).hide();
		$('#' + pageId, sectionDiv).show();
		if (this.results[pageId].pageInitFunc) {
			this.results[pageId].pageInitFunc();
		}
		this.activeId = pageId;
	},
};

function logObject(obj) {
	var x = [];
	for (var key in obj) {
		if (typeof obj[key] === 'function') {
			x.push(key + ": function");
		} else {
			x.push([key, obj[key]].join(' = '));			
		}
	}
	contentAPI.log(x.join('\r\n'));
}

function init() {
	$("#iframe_searchdetail").load(function() {
		SearchDetail.onDetailLoad(this);
	});
	SearchPage.init();
}