// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2009
// http://flock.com
//
// This file may be used under the terms of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL

var EXPORTED_SYMBOLS = ["FlockLiveSearchProvider"];

const CC = Components.classes;
const CI = Components.interfaces;
const CR = Components.results;
const CU = Components.utils;

CU.import("resource:///modules/FlockXPCOMUtils.jsm");
CU.import("resource:///modules/FlockStringBundleHelpers.jsm");


const NAME_SUFFIX = "Live Search";

var FlockLiveSearchProvider = {
  generateComponent: function FLSP_generateComponent(aName,
                                                     aCID,
                                                     aCtor,
                                                     aEngine,
                                                     aIconURL,
                                                     aFullResultsURL)
  {
    var shortName = aName.replace(/\s+/, "").toLowerCase();
    var className = aName + " " + NAME_SUFFIX;
    var contractID = "@flock.com/live-search/" + shortName + ";1";

    var prototype = new FlockXPCOMUtils.genericComponent(
      className, aCID, contractID, aCtor,
      CI.nsIClassInfo.SINGLETON, [CI.flockISearchService]
    );

    prototype._xpcom_categories = [
      { category: "flockISearchService", entry: shortName }
    ];

    prototype._init = function FLSP__init() {
      this._logger = CC["@flock.com/logger;1"].createInstance(CI.flockILogger);
      this._logger.init(shortName + "livesearch");

      if (aEngine) {
        var ss = CC["@mozilla.org/browser/search-service;1"]
                 .getService(CI.nsIBrowserSearchService);
        this._engine = ss.getEngineByName(aEngine);
        if (!this._engine) {
          shortName = null;
          return;
        }
        this._engine = this._engine.QueryInterface(CI.flockISearchEngine);
        this._iconURL = aIconURL ? aIconURL : this._engine.iconURI.spec;
      } else {
        this._engine = null;
        this._iconURL = aIconURL;
      }
    };

    prototype.__defineGetter__("serviceName",
      function FLSP_serviceName() {
        if (this._engine) {
          return this._engine.description;
        }
        return flockGetString("search/search",
                              "flock.search.api.live",
                              [aName]);
      }
    );

    prototype.__defineGetter__("shortName", function FLSP_shortName() {
      return shortName;
    });

    prototype.__defineGetter__("icon", function FLSP_icon() {
      return this._iconURL;
    });

    if (aEngine || aFullResultsURL) {
      prototype.getFullResultsURL = function FLSP_getFullResultsURL(aQuery) {
        if (this._engine && !aFullResultsURL) {
          var submission = this._engine.getSubmissionByContext(aQuery,
                                                               null,
                                                               "a");
          return submission.uri.spec;
        } else {
          return aFullResultsURL + encodeURIComponent(aQuery);
        }
      };
    }

    prototype.search = function FLSP_search(aQuery,
                                            aNumResults,
                                            aSearchListener)
    {
      var inst = this;

      if (!aQuery.length) {
        return;
      }

      var url, postData;
      if (this._engine) {
        var submission = this._engine.getLiveSubmission(aQuery, aNumResults,
                                                        null);
        url = submission.uri.spec;
        postData = submission.postData;
      } else {
        url = inst._getQueryURL(aQuery, aNumResults);
        postData = null;
      }

      this._logger.debug("call: " + url);

      var xhr = CC["@mozilla.org/xmlextras/xmlhttprequest;1"]
                .createInstance(CI.nsIXMLHttpRequest);

      xhr.onload = function FLSP_onload(aEvent) {
        if (xhr.status == 200 || xhr.status == 201) {
          var results;
          try {
            results = inst._getResults(xhr, aNumResults);
          } catch (ex) {
            inst._logger.error("getResults failed: " + ex);
            results = [];
          }

          for each (let result in results) {
            if (!result.icon) {
              result.icon = inst._iconURL;
            }
          }

          aSearchListener.foundResults(results, shortName, aQuery);
        }
      };

      xhr.mozBackgroundRequest = true;
      xhr.open("GET", url);

      if (this._requestHook) {
        this._requestHook(xhr);
      }

      xhr.send(postData);
    };

    return prototype;
  },

  generateNSGetModule: function FLSP_generateNSGetModule(aName, aCtor) {
    return FlockXPCOMUtils.generateNSGetModule(aName + " " + NAME_SUFFIX,
                                               [aCtor]);
  }
};
