//
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2008
// 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
//

const SM_CONTRACTID = '@flock.com/search-migratable;1';
const SM_CLASSID    = Components.ID('{24ddbfe0-4216-40cb-a037-2c17ab7d5a47}');
const SM_CLASSNAME  = 'Flock Search Service Migratable';

const SEARCHELSEWHERE_EXCLUSION_PREF  = "flock.search.excludedEngines";
const ENABLEDSERVICES_PREF = "flock.liveSearch.enabledServices";
const SHOWFAVORITES_PREF = "flock.search.flyout.showFavorites";
const SHOWHISTORY_PREF = "flock.search.flyout.showHistory";
const SHOWYAHOORESULTS_PREF = "flock.search.flyout.showYahooLiveResults";

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

Components.utils.import("resource:///modules/FlockStringBundleHelpers.jsm");


function SearchMigratable() {
}

SearchMigratable.prototype = {
  get migrationName() {
    return flockGetString("common/migrationNames", "migration.name.search");
  },

  needsMigration: function SM_needsMigration(oldVersion) {
    var minorVersion = oldVersion.substr(0, 3);
    if (minorVersion == "0.7" || minorVersion == "0.9") {
      var prefs = Cc['@mozilla.org/preferences-service;1']
        .getService(Ci.nsIPrefBranch);
      return prefs.prefHasUserValue(SEARCHELSEWHERE_EXCLUSION_PREF)
              || prefs.prefHasUserValue(SHOWFAVORITES_PREF)
              || prefs.prefHasUserValue(SHOWHISTORY_PREF)
              || prefs.prefHasUserValue(SHOWYAHOORESULTS_PREF);
    } else {
      return false;
    }
  },
  startMigration: function SM_startMigration(oldVersion, listener) {
    var minorVersion = oldVersion.substr(0, 3);

    var prefs = Cc['@mozilla.org/preferences-service;1']
      .getService(Ci.nsIPrefBranch);

    var enabled = prefs.getCharPref(ENABLEDSERVICES_PREF).split(",");

    if (minorVersion == "0.7") {
      // If both favorites and history are disabled, disable flock livesearch.
      var flock_pref = prefs.getBoolPref(SHOWFAVORITES_PREF);
      if (!flock_pref) {
        flock_pref = prefs.getBoolPref(SHOWHISTORY_PREF);
      }
      if (!flock_pref) {
        var filterFlockFunc = function SM_filterFlockFunc(aElem, aIdx, aArray) {
          return (aElem != "flock");
        };
        enabled = enabled.filter(filterFlockFunc);
      }
  
      // Disable yahoo live results if previously disabled.
      var yahoo_pref = prefs.getBoolPref(SHOWYAHOORESULTS_PREF);
      if (!yahoo_pref) {
        var filterYahooFunc = function SM_filterYahooFunc(aElem, aIdx, aArray) {
          return (aElem != "yahoo");
        };
        enabled = enabled.filter(filterYahooFunc);
      }
    }

    var excluded = prefs.getCharPref(SEARCHELSEWHERE_EXCLUSION_PREF);

    var ctxt = {
      listener: listener,
      minorVersion: minorVersion,

      oldExcluded: excluded.split(","),
      newExcluded: [],
      newEnabled: enabled
    };

    return { wrappedJSObject: ctxt };
  },
  finishMigration: function SM_finishMigration(ctxtWrapper) {
    var ctxt = ctxtWrapper.wrappedJSObject;

    var prefs = Cc['@mozilla.org/preferences-service;1']
      .getService(Ci.nsIPrefBranch);
    prefs.setCharPref(SEARCHELSEWHERE_EXCLUSION_PREF, ctxt.newExcluded.join());

    if (ctxt.minorVersion == "0.7") {
      prefs.setCharPref(ENABLEDSERVICES_PREF, ctxt.newEnabled.join());
    }
  },
  doMigrationWork: function SM_doMigrationWork(ctxtWrapper) {
    var ctxt = ctxtWrapper.wrappedJSObject;

    var oldEngine = ctxt.oldExcluded.shift();
    var newEngine;

    if (ctxt.minorVersion == "0.7") {
      var replaceFunc = function SM_cardinalEngineReplace(aMatch, a1, aStr) {
        dump("\n" + a1 + "\n");
        if (!a1) {
          return "";
        }
        var newEngine = a1;
        switch (a1) {
          case "jeeves":
            newEngine = "Ask.com";
          break;
          case "winkflock":
            newEngine = "Wink People";
          break;
          case "wikipedia":
            newEngine = "Wikipedia (EN)";
          break;
          case "eBay":
            newEngine = "eBay";
          break;
          case "jajah":
            newEngine = "Jajah Telephony";
          break;
          case "bittorrent":
            newEngine = "BitTorrent";
          break;
          case "blogger":
            newEngine = "Blogger Blog Search";
          break;
          case "craigslist_forsale":
            newEngine = "Craigs List For Sale";
          break;
          case "del.icio.us":
            newEngine = "del.icio.us tag";
          break;
          case "dictionary":
            newEngine = "Dictionary.com";
          break;
          case "espn":
            newEngine = "ESPN";
          break;
          case "foodtv":
            newEngine = "Food Network Recipes";
          break;
          case "googleimages":
            newEngine = "Google Images";
          break;
          case "hollywoodvideo":
            newEngine = "HollyWood Video Search";
          break;
          case "itunesuk":
            newEngine = "iTunes Music Store";
          break;
          case "linkedin-bf":
            newEngine = "LinkedIn";
          break;
          case "lj-int":
            newEngine = "Livejournal Interest";
          break;
          case "lonelyplanet":
            newEngine = "Lonely Planet Online";
          break;
          case "marketwatch":
            newEngine = "MarketWatch";
          break;
          case "pg":
            newEngine = "PriceGrabber";
          break;
          case "urbandictionary":
            newEngine = "UrbanDictionary.com";
          break;
          case "weather":
            newEngine = "weather.com";
          break;
          case "amazondotcom":
            newEngine = "Amazon.com";
          break;
          case "expediadotcom":
            newEngine = "Expedia.com";
          break;
          case "youtube":
            newEngine = "youtube";
          break;
          case "myspace":
            newEngine = "Myspace.com";
          break;
          case "xanga":
            newEngine = "Xanga.com";
          break;
          default:
            if (a1.indexOf("babelfish_") == 0) {
              var langs = a1.substr(a1.indexOf("_") + 1).split("2");
              var lang0 = langs[0].charAt(0).toUpperCase() + langs[0].substr(1);
              var lang1 = langs[1].charAt(0).toUpperCase() + langs[1].substr(1);
              
              newEngine = "Babel Fish " + lang0 + "->" + lang1;
            } else { //Yahoo, Google, Technorati, Shadows, Facebook, Gmail,
                     //IMDb, MSN, Yahooligans
              newEngine = a1.charAt(0).toUpperCase() + a1.substr(1);
            }
          break;
        }
        return newEngine;
      };
      newEngine =
        oldEngine.replace(/NC:SearchCategory\?engine=urn:search:engine:(.+)\.src/,
                          replaceFunc);
    } else { // if (ctxt.minorVersion == "0.9")
      newEngine = oldEngine;
    }

    if (newEngine) {
      if (newEngine == "Yahoo") {
        newEngine = "Yahoo!";
      }
      ctxt.newExcluded.push(newEngine);
    }

    return Boolean(ctxt.oldExcluded.length);
  },

  getInterfaces: function SM_getInterfaces(countRef) {
    var interfaces = [Ci.flockIMigratable, Ci.nsIClassInfo, Ci.nsISupports];
    countRef.value = interfaces.length;
    return interfaces;
  },
  getHelperForLanguage: function SM_getHelperForLanguage(language) {
    return null;
  },
  contractID: SM_CONTRACTID,
  classDescription: SM_CLASSNAME,
  classID: SM_CLASSID,
  implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
  flags: Ci.nsIClassInfo.SINGLETON,

  QueryInterface: function SM_QueryInterface(iid) {
    if (iid.equals(Ci.flockIMigratable) ||
        iid.equals(Ci.nsIClassInfo) ||
        iid.equals(Ci.nsISupports))
      return this;
    throw Cr.NS_ERROR_NO_INTERFACE;
  }
}


function GenericComponentFactory(ctor) {
  this._ctor = ctor;
}

GenericComponentFactory.prototype = {

  _ctor: null,

  // nsIFactory
  createInstance: function(outer, iid) {
    if (outer != null)
      throw Cr.NS_ERROR_NO_AGGREGATION;
    return (new this._ctor()).QueryInterface(iid);
  },

  // nsISupports
  QueryInterface: function(iid) {
    if (iid.equals(Ci.nsIFactory) ||
        iid.equals(Ci.nsISupports))
      return this;
    throw Cr.NS_ERROR_NO_INTERFACE;
  },
};

var Module = {
  QueryInterface: function(iid) {
    if (iid.equals(Ci.nsIModule) ||
        iid.equals(Ci.nsISupports))
      return this;

    throw Cr.NS_ERROR_NO_INTERFACE;
  },

  getClassObject: function(cm, cid, iid) {
    if (!iid.equals(Ci.nsIFactory))
      throw Cr.NS_ERROR_NOT_IMPLEMENTED;

    if (cid.equals(SM_CLASSID))
      return new GenericComponentFactory(SearchMigratable)

    throw Cr.NS_ERROR_NO_INTERFACE;
  },

  registerSelf: function(cm, file, location, type) {
    var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
    cr.registerFactoryLocation(SM_CLASSID, SM_CLASSNAME, SM_CONTRACTID,
                               file, location, type);

    var catman = Cc['@mozilla.org/categorymanager;1']
      .getService(Ci.nsICategoryManager);
    catman.addCategoryEntry('flockMigratable', SM_CLASSNAME, SM_CONTRACTID,
                            true, true);
  },

  unregisterSelf: function(cm, location, type) {
    var cr = cm.QueryInterface(Ci.nsIComponentRegistrar);
    cr.unregisterFactoryLocation(SM_CLASSID, location);
  },

  canUnload: function(cm) {
    return true;
  },
};

function NSGetModule(compMgr, fileSpec)
{
  return Module;
}
