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 Developers Site");
        devSiteSearcher.setSiteRestriction("http://developer.android.com/");

        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");

        homeSiteSearcher = new google.search.WebSearch();
        homeSiteSearcher.setUserDefinedLabel("Android Home");
        homeSiteSearcher.setSiteRestriction("http://www.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) {
            // save the tab index from the hash
            tabIndex = location.hash.split("&t=")[1];

            $("#searchTitle").html("search results for <em>" + escapeHTML(query) + "</em>");
            $.history.add('q=' + query + '&t=' + tabIndex);
            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>
