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 {
          contentAPI.makeObjAccessible(data);
          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;
    }

    // Since FF17, the result is readonly, we need to clone it.
    result = JSON.parse(JSON.stringify(result));

    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) {
        contentAPI.makeObjAccessible(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) {
          contentAPI.makeObjAccessible(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 {
          contentAPI.makeObjAccessible(data);
          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){
          contentAPI.makeObjAccessible(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 {
          contentAPI.makeObjAccessible(data);
          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 {
          contentAPI.makeObjAccessible(data);
          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 {
          contentAPI.makeObjAccessible(data);
          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 {
          contentAPI.makeObjAccessible(data);
          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 {
          contentAPI.makeObjAccessible(data);
          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 {
          contentAPI.makeObjAccessible(data);
          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 {
          contentAPI.makeObjAccessible(data);
          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 {
          contentAPI.makeObjAccessible(data);
          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){
        contentAPI.makeObjAccessible(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();
}

