
var GoogleSearch = {};

 (function(){

     GoogleSearch.callback = {};
     var callbackCounter = 0;
     var beginRequestListener = function () {};
     var endRequestListener = function () {};
     var beginNetworkListener = function () {};
     var endNetworkListener = function () {};

     var outstandingRequests = 0;

     GoogleSearch.doSearch = function (query, args, callback) {

         // Allocate a callback slot.
         var callbackIndex = callbackCounter++;
         var callbackLocalName = "c"+callbackIndex;
         var callbackFullName = "GoogleSearch.callback."+callbackLocalName;
         args.callback = callbackFullName;
         delete args.context;

         args.q = query;
         if (! args.v) args.v = "1.0";

         var queryStringBits = [];
         for (var key in args) {
             var value = args[key];

             if (value === true) value = "1";
             else if (value === false) value = "0";

             queryStringBits.push([
                 encodeURIComponent(key),
                 encodeURIComponent(value)
             ].join('='));
         }

         var queryString = queryStringBits.join("&");
         var url = [
             "http://ajax.googleapis.com/ajax/services/search/web",
             queryString
         ].join("?");

         var scriptNode = document.createElement("script");
         scriptNode.type = "text/javascript";
         scriptNode.src = url;

         var realCallback = function (data, details, status) {
             // Call the caller's callback
             callback(data, details, status);

             // Clean up our temporary junk
             if (scriptNode.parentNode) {
                 scriptNode.parentNode.removeChild(scriptNode);
             }
             GoogleSearch.callback[callbackLocalName] = undefined;
             outstandingRequests--;

             if (endRequestListener) {
                 endRequestListener(args);
             }

             if (outstandingRequests == 0) {
                 // We're now idle, so let's take the opportunity to
                 // reset everything.
                 GoogleSearch.callback = {};
                 callbackCounter = 0;

                 if (endNetworkListener) {
                     endNetworkListener();
                 }
             }
         };

         if (outstandingRequests == 0) {
             if (beginNetworkListener) {
                 beginNetworkListener();
             }
         }
         beginRequestListener(args);
         outstandingRequests++;

         GoogleSearch.callback[callbackLocalName] = realCallback;
         document.body.appendChild(scriptNode);

     };

 })();


