page.title=Search Results
@jd:body

<script src="http://www.google.com/jsapi" type="text/javascript"></script>
<script src="{@docRoot}assets/jquery-history.js" type="text/javascript"></script>
<script type="text/javascript">      
      var tabIndex = 0;
            
      google.load('search', '1');

      function OnLoad() {
        document.getElementById("search_autocomplete").style.color = "#000";

        // create search control
        searchControl = new google.search.SearchControl();

        // use our existing search form and use tabs when multiple searchers are used
        drawOptions = new google.search.DrawOptions();
        drawOptions.setDrawMode(google.search.SearchControl.DRAW_MODE_TABBED);
        drawOptions.setInput(document.getElementById("search_autocomplete"));

        // configure search result options
        searchOptions = new google.search.SearcherOptions();
        searchOptions.setExpandMode(GSearchControl.EXPAND_MODE_OPEN);

        // configure each of the searchers, for each tab
        devSiteSearcher = new google.search.WebSearch();
        devSiteSearcher.setUserDefinedLabel("All");
        devSiteSearcher.setSiteRestriction("001482626316274216503:zu90b7s047u");

        devGuideSearcher = new google.search.WebSearch();
        devGuideSearcher.setUserDefinedLabel("Dev Guide");
        devGuideSearcher.setSiteRestriction("http://developer.android.com/guide/");

        referenceSearcher = new google.search.WebSearch();
        referenceSearcher.setUserDefinedLabel("Reference");
        referenceSearcher.setSiteRestriction("http://developer.android.com/reference/");

        blogSearcher = new google.search.WebSearch();
        blogSearcher.setUserDefinedLabel("Blog");
        blogSearcher.setSiteRestriction("http://android-developers.blogspot.com");

        groupsSearcher = new google.search.WebSearch();
        groupsSearcher.setUserDefinedLabel("Developer Groups");
        groupsSearcher.setSiteRestriction("001283715400630100512:ggqrtvkztwm");

        sourceSiteSearcher = new google.search.WebSearch();
        sourceSiteSearcher.setUserDefinedLabel("Android Source");
        sourceSiteSearcher.setSiteRestriction("http://source.android.com");
 
        // add each searcher to the search control
        searchControl.addSearcher(devSiteSearcher, searchOptions);
        searchControl.addSearcher(devGuideSearcher, searchOptions);
        searchControl.addSearcher(referenceSearcher, searchOptions);
        searchControl.addSearcher(groupsSearcher, searchOptions);
        searchControl.addSearcher(sourceSiteSearcher, searchOptions);
        searchControl.addSearcher(blogSearcher, searchOptions);

        // configure result options
        searchControl.setResultSetSize(google.search.Search.LARGE_RESULTSET);
        searchControl.setLinkTarget(google.search.Search.LINK_TARGET_SELF);
        searchControl.setTimeoutInterval(google.search.SearchControl.TIMEOUT_LONG);
        searchControl.setNoResultsString(google.search.SearchControl.NO_RESULTS_DEFAULT_STRING);

        // upon ajax search, refresh the url and search title
        searchControl.setSearchStartingCallback(this, function(control, searcher, query) {
            $("#searchTitle").html("search results for <em>" + escapeHTML(query) + "</em>");

            // save the tab index from the hash
            tabIndex = location.hash.split("&t=")[1];
            $.history.add('q=' + query + '&t=' + tabIndex);
        });

        searchControl.setSearchCompleteCallback(this, function(control, searcher) {
            openTab();
        });

        // draw the search results box
        searchControl.draw(document.getElementById("leftSearchControl"), drawOptions);

        // get query and execute the search
        if (location.hash.indexOf("&t=") != -1) {
          searchControl.execute(decodeURI(getQuery(location.hash)));
        }

        document.getElementById("search_autocomplete").focus();
        addTabListeners();
      }
      // End of OnLoad


      google.setOnLoadCallback(OnLoad, true);

      // when an event on the browser history occurs (back, forward, load) perform a search
      $(window).history(function(e, hash) {
        var query = decodeURI(getQuery(hash));
        searchControl.execute(query);

        $("#searchTitle").html("search results for <em>" + escapeHTML(query) + "</em>");
      });

      // forcefully regain key-up event control (previously jacked by search api)
      $("#search_autocomplete").keyup(function(event) {
        return search_changed(event, false, '/');
      });

      // open a tab, specified by its array position
      function openTab() {
        tabIndex = location.hash.split("&t=")[1];

        // show the appropriate tab
        var tabHeaders = $(".gsc-tabHeader");
        $(tabHeaders[tabIndex]).click();
      }

      // add event listeners to each tab so we can track the browser history
      function addTabListeners() {
        var tabHeaders = $(".gsc-tabHeader");
        for (var i = 0; i < tabHeaders.length; i++) {
          $(tabHeaders[i]).attr("id",i).click(function() {
            var tabHeaders = $(".gsc-tabHeader");
            var tabIndex = $(this).attr("id");
            $.history.add('q=' + getQuery(location.hash) + '&t=' + tabIndex); // update the hash with the new tab
          });
        }
      }

      function getQuery(hash) {
        var hashParts = hash.split('&t=');
        var queryParts = hashParts[0].split('=');
        return queryParts[1];
      }

      /* returns the given string with all HTML brackets converted to entities
         TODO: move this to the site's JS library */
      function escapeHTML(string) {
        return string.replace(/</g,"&lt;")
                     .replace(/>/g,"&gt;");
      }

</script>

  <div id="mainBodyFixed" style="width:auto; margin:20px">
          <h2 id="searchTitle">search results</h2>
          <img src="{@docRoot}assets/images/hr_gray_main.jpg" />
          <div><br /></div>
          <div id="leftSearchControl" class="search-control">Loading...</div>
  </div>
