//
// 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
//

#ifndef XP_MACOSX
var Cc = Components.classes;
var Ci = Components.interfaces;
var Cr = Components.results;
var Cu = Components.utils;
#endif

Cu.import("resource:///modules/FlockPrefsUtils.jsm");

const ELSEWHERE_ENGINES_PREF = "flock.search.elsewhereEngines";
const DEFAULT_BROWSER_ENGINE = "browser.search.defaultenginename";
const SELECTED_SEARCH_ENGINE = "browser.search.selectedEngine";
const ENABLED_LIVE_SEARCH_ENGINES = "flock.liveSearch.enabledServices";
const LIVESEARCH_ORDERED_SVCS = "flock.liveSearch.orderedServices";
const SEARCH_SERVICE_CONTRACTID = "@mozilla.org/browser/search-service;1";
const FLOCK_SEARCH_MANAGER_CONTRACTID = "@flock.com/search-manager;1";
const OPEN_LINK_PREF = "browser.link.open_external";

const PLACEHOLDER_ICON = "chrome://flock/skin/search/placeholderIcon16.png";

var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).getBranch(null);
var browserSearchSvc = Cc[SEARCH_SERVICE_CONTRACTID].getService(Ci.nsIBrowserSearchService);

var gSearchPane = {
  initComplete: false,

  init: function() {
    window.addEventListener("unload", this, false);
    var prefBranch = Cc["@mozilla.org/preferences-service;1"].
      getService(Ci.nsIPrefBranch2);
    prefBranch.addObserver(SELECTED_SEARCH_ENGINE, this, false);
    gLiveSearchView = new LiveSearchView(document.getElementById("liveSearchServices"));
    setupLiveSearchList();
    buildDefaultSearchPopup();
    buildSearchElsewhere();
    flock_setupSearchPrefs();
    if (prefBranch.getBoolPref("flock.search.dnsnotfound.partnersearch.enabled")) {
      document.getElementById("showPartnerSearchOnDomainError")
              .setAttribute("checked", "true");
    }
    this.initComplete = true;
  },
  
  uninit: function() {
    var prefBranch = Cc["@mozilla.org/preferences-service;1"].
      getService(Ci.nsIPrefBranch2);
    prefBranch.removeObserver(SELECTED_SEARCH_ENGINE, this);
    window.removeEventListener("unload", this, false);
  },

  handleEvent: function(aEvent) {
    if (aEvent.type == "unload") {
      this.uninit();
    }
  },

  observe: function(aSubject, aTopic, aData) {
    if (aTopic == "nsPref:changed") {
      switch (aData) {
        case SELECTED_SEARCH_ENGINE:
          flock_setDefaultEnginePopup();
          break;
      }
    }
  }

};

var gLiveSearchView;


function flock_setupSearchPrefs() {
  var flockSearchListbox = document.getElementById("flockSearchListbox");
  var engineItems = flockSearchListbox.getElementsByTagName("listitem");
  var elsewhereEngines =
    FlockPrefsUtils.getLocalizedPref(ELSEWHERE_ENGINES_PREF, "");
  for (var i =0; i < engineItems.length; i++) {
    var searchName = engineItems[i].childNodes[1].getAttribute("label");
    if (elsewhereEngines.indexOf(searchName) != -1) {
      engineItems[i].firstChild.firstChild.setAttribute("checked", true);
    }
  }
  flock_setDefaultEnginePopup();
}

function flock_saveSelectedEnginePrefs() {
  var flockSearchListbox = document.getElementById("flockSearchListbox");
  var engineItems = flockSearchListbox.getElementsByTagName("listitem");
  var prefString = "";
  for (var i = 0; i < engineItems.length; i++) {
    if (engineItems[i].firstChild.firstChild.checked == true) {
      prefString = prefString + engineItems[i].childNodes[1].getAttribute("label") + ",";
    }
  }
  FlockPrefsUtils.setLocalizedPref(ELSEWHERE_ENGINES_PREF, prefString);
}

function flock_setDefaultEngine() {
  var selectedEngine = document.getElementById("flockDefaultSearchMenu").selectedItem;
  var engineName = selectedEngine.getAttribute("label");

  var previousEngineName = browserSearchSvc.currentEngine.name;

  var engines = browserSearchSvc.getEngines({});
  for each (var engine in engines) {
    if (engine.name == engineName) {
      browserSearchSvc.currentEngine = engine;
      break;
    }
  }
  var elsewhereList =
    FlockPrefsUtils.getLocalizedPref(ELSEWHERE_ENGINES_PREF, "").split(",");
  var defaultEngine =
    FlockPrefsUtils.getLocalizedPref(DEFAULT_BROWSER_ENGINE, "");

  // If previous chrome search engine is the default browser engine,
  // then add it to elsewhere list
  if (previousEngineName == defaultEngine) {
    if (elsewhereList.indexOf(previousEngineName) == -1) {
      elsewhereList.push(previousEngineName);
      FlockPrefsUtils.setLocalizedPref(ELSEWHERE_ENGINES_PREF,
                                       elsewhereList.join(","));
      flock_setupSearchPrefs();
    }
  }
}

function flock_setDefaultEnginePopup() {
  // Has the user set this preference?
  var userPrefSet = prefService.prefHasUserValue(SELECTED_SEARCH_ENGINE);

  // Did we find the engine set in the preferences in the menulist?
  var prefMatches = false;

  if (userPrefSet) {
    var currentEngine = browserSearchSvc.currentEngine.name;
    setMenulistSelection(currentEngine);
  }

  function setMenulistSelection(aEngine) {
    var flockSearchListbox = document.getElementById("flockSearchListbox");
    var engineItems = flockSearchListbox.getElementsByTagName("listitem");
    for (var i = 0; i < engineItems.length; i++) {
      if (engineItems[i].childNodes[1].getAttribute("label") == aEngine) {
        document.getElementById("flockDefaultSearchMenu").selectedIndex = i;
        prefMatches = true;
      }
    }
  }

  // If we didn't find it, remove the invalid value so we revert to default.
  if (!prefMatches) {
    var defaultEngine = browserSearchSvc.defaultEngine.name;
    setMenulistSelection(defaultEngine);
    if (userPrefSet) {
      prefService.clearUserPref(SELECTED_SEARCH_ENGINE);
    }
  }
}


function setupLiveSearchList() {
  var searchMgrSvc = Cc[FLOCK_SEARCH_MANAGER_CONTRACTID].getService(Ci.flockISearchManager);
  var liveSearchListEnum = searchMgrSvc.orderedServices;
  var liveSearchContainer = document.getElementById("liveSearchServices");
  var service, listitem, listcell, checkbox;
  while (liveSearchListEnum.hasMoreElements()) {
    service = liveSearchListEnum.getNext();
    if (!service.shortName) {
      // Sulfur does not have all the required engines (xml).
      continue;
    }
    listitem = document.createElement("listitem");
    listitem.setAttribute("value", service.shortName);
    listitem.setAttribute("allowevents", true);
    
    listcell = document.createElement("listcell");
    checkbox = document.createElement("checkbox");
    checkbox.setAttribute("checked", searchMgrSvc.isServiceEnabled(service.shortName));
    checkbox.setAttribute("oncommand", "gLiveSearchView.synchToPref();");
    listcell.appendChild(checkbox);
    listitem.appendChild(listcell);
    
    listcell = document.createElement("listcell");
    listcell.setAttribute("label", service.serviceName);
    listitem.appendChild(listcell);
    
    liveSearchContainer.appendChild(listitem);
  }
}

var LiveSearchView = function(aListbox) {
  this.mListbox = aListbox;
  this.mSelectedIndex = null;
  this.mTotalItems = null;
  this.mGoDownButton = null;
  this.mGoUpButton = null;
  
  this.init();
}

LiveSearchView.prototype = {
  init: function() {
    this.mGoDownButton = document.getElementById("goDownButton");
    this.mGoUpButton = document.getElementById("goUpButton");
    this.mGoUpButton.setAttribute("disabled", true);
    this.mGoDownButton.setAttribute("disabled", true);
  },
  
  onSelect: function() {
    // buttons only work if an engine is selected and it's not the last engine
    var disableButtons = (this.mListbox.selectedIndex == -1);
    var lastSelected = (this.mListbox.selectedIndex == this.mListbox.getRowCount() - 1);
    var firstSelected = (this.mListbox.selectedIndex == 0);

    this.mGoUpButton.setAttribute("disabled", disableButtons || firstSelected);
    this.mGoDownButton.setAttribute("disabled", disableButtons || lastSelected);
  },
  
  bump: function(aDir) {
    //liveSearchOrder.mListbox.selectedIndex--;
    var lastIndex = this.mListbox.selectedIndex;
    var clonedNode = this.mListbox.selectedItem.cloneNode(true);
    clonedNode.removeAttribute("selected");
    clonedNode.removeAttribute("current");
    
    if (aDir == 1) {
      this.mListbox.insertBefore(clonedNode, this.mListbox.selectedItem.previousSibling);
      this.mListbox.removeItemAt(lastIndex+1);
    } else if (aDir == -1) {
      var nextSibling = this.mListbox.selectedItem.nextSibling;
      this.mListbox.removeItemAt(lastIndex);
      if (nextSibling.nextSibling) {
        this.mListbox.insertBefore(clonedNode, nextSibling.nextSibling);
      } else {
        this.mListbox.appendChild(clonedNode);
      }
    }
    
    this.mListbox.selectedItem = clonedNode;
    this.mListbox.ensureElementIsVisible(this.mListbox.selectedItem); 
    this.synchToPref();
    this.onSelect();
  },
  
  synchToPref: function() {
    var liveSearchItems = this.mListbox.childNodes;
    var enabledString = "";
    var orderedString = "";
    for (var i = 0; i < liveSearchItems.length; i++) {
      var shortName = liveSearchItems[i].getAttribute("value");
      if (!shortName || !shortName.length) {
        continue;
      }
      orderedString += shortName + ",";
      if (liveSearchItems[i].firstChild.firstChild.getAttribute("checked") == "true") {
        enabledString += shortName + ",";
      }
    }
    prefService.setCharPref(ENABLED_LIVE_SEARCH_ENGINES, enabledString);
    prefService.setCharPref(LIVESEARCH_ORDERED_SVCS, orderedString);
  }
};
  
function getOpenLinkPref() {
  var openLinkPref = prefService.getIntPref(OPEN_LINK_PREF);
  if (openLinkPref == "3") {
    return "tab";
  } else {
    return "window";
  }
}

function buildDefaultSearchPopup() {
  var engines = browserSearchSvc.getEngines({});
  var defaultSearchPopup = document.getElementById("flockDefaultSearchPopup");
  for (var i = 0; i < engines.length; i++ ) {
    var menuItem = document.createElement("menuitem");
    menuItem.setAttribute("label", engines[i].name);
    menuItem.setAttribute("image", engines[i].iconURI ? engines[i].iconURI.spec
                                                      : PLACEHOLDER_ICON);
    menuItem.setAttribute("class", "menuitem-iconic");
    menuItem.setAttribute("oncommand", "flock_setDefaultEngine();");
    defaultSearchPopup.appendChild(menuItem);
  }
}

function buildSearchElsewhere() {
  var engines = browserSearchSvc.getEngines({});
  var searchListBox = document.getElementById("flockSearchListbox");
  var listitem, listcell, checkbox;
  for (var i = 0; i < engines.length; i++ ) {
    listitem = document.createElement("listitem");
    listitem.setAttribute("allowevents", true);
    
    listcell = document.createElement("listcell");
    checkbox = document.createElement("checkbox");
    checkbox.setAttribute("oncommand", "flock_saveSelectedEnginePrefs();");
    listcell.appendChild(checkbox);
    listitem.appendChild(listcell);
    
    listcell = document.createElement("listcell");
    listcell.setAttribute("label", engines[i].name);
    listcell.setAttribute("image", engines[i].iconURI ? engines[i].iconURI.spec
                                                      : PLACEHOLDER_ICON);
    listcell.setAttribute("class", "listcell-iconic");
    listitem.appendChild(listcell);
    
    searchListBox.appendChild(listitem);
  }
}

// Upon the first load of the Preferences Menu the Searching Pane
// isn't populated with data; ensure it initializes with a timer
var gTimer = null;
gTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
gTimer.initWithCallback({
  notify: function searchPref_ensureInit() {
    if (!gSearchPane.initComplete) {
      gSearchPane.init();
    }
  }
}, 50, Ci.nsITimer.TYPE_ONE_SHOT);
