var EXPORTED_SYMBOLS = ["YOONO_PREFS"];

var yoono = {};
var log = {info:function() {},debug:function() {},warn:function(){},error:function (){},fatal:function(){}};

// Globals
const CI = Components.interfaces;
const CL = Components.classes;
const PREFSSERVICE = CL["@mozilla.org/preferences-service;1"].getService(CI.nsIPrefService);
const WMED = CL['@mozilla.org/appshell/window-mediator;1'].getService(CI.nsIWindowMediator);
const DIRSERVICE = CL['@mozilla.org/file/directory_service;1'].getService(CI.nsIProperties);
const PREFS = PREFSSERVICE.getBranch("extensions.yoono.");

function Prefs() {
	this.wrappedJSObject=this;

	// constructeur
	PREFSSERVICE.QueryInterface(CI.nsIPrefBranch2);
	PREFSSERVICE.addObserver("extensions.yoono.debug", this, false);
	this.loadAllPrefs();
}

Prefs.prototype.init = function (y) {
	yoono = y;
	log = y.log;
}

Prefs.prototype.getPrefType = function (name) {
  return(PREFS.getPrefType(name));
}

Prefs.prototype.get = function (name) {
  try {
    var type = PREFS.getPrefType(name);
    switch (type) {
    case PREFS.PREF_STRING :
      return PREFS.getCharPref(name);
    case PREFS.PREF_BOOL :
      return PREFS.getBoolPref(name);
    case PREFS.PREF_INT :
      return PREFS.getIntPref(name);
    default :
      log.warn('Prefs.getPref unknown type for pref :  ' + name);
      break;
    }
  } catch(e) {
    log.exception("Prefs.getPref : '" + name + "': ", e);
  }
  return null;
}

Prefs.prototype.traverseBrowsers = function (fun) {
	var windowsenum = WMED.getEnumerator("navigator:browser");
	var win;
	while (windowsenum.hasMoreElements()) {
		win = windowsenum.getNext();
		fun (win);
	}
}

Prefs.prototype.loadAllPrefs = function () {
	var prefName, type;
	var childArray = PREFS.getChildList('', {});
	for (var i = childArray.length ; i-- > 0 ; ) {
		prefName = childArray[i];
		type = PREFS.getPrefType(prefName);
		this.loadPref(prefName, type);
	}
}

Prefs.prototype.loadPref = function (aprefName, type) {
  log.debug('loading pref');
  // Is it an update ?
  var update = false;
  var release = '';
  try {
    release = PREFS.getCharPref('release');
    update = true;
  } catch(e) {
  }
  // Check if pref nosynchro exists
  try {
    var noSync = PREFS.getBoolPref('nosynchro');
  } catch(e) {
    // Exception means either pref nosync did not exist (first install), or was set to
    // false while false was default (releases before 5)
    // or true while true was default (releases since 5)
    // 'release' existance and value allows to know which case it is
    if(update) {
      // The user left the original default value: set it to that value
      // Check if previous release was 4 (release number is not yet updated at
      // this point)
      // in releases before 5, default was false
      if(release.substring(0,1) < '5') {
        PREFS.setBoolPref('nosynchro', false);
      } else {
        PREFS.setBoolPref('nosynchro', true);
      }
    } else {
      // The pref did not exist because this is an installation
      PREFS.setBoolPref('nosynchro', true);
    }
  }
  try {
    switch (type) {
    case PREFS.PREF_STRING :
      this[aprefName] = PREFS.getCharPref(aprefName);
      break;
    case PREFS.PREF_BOOL :
      this[aprefName] = PREFS.getBoolPref(aprefName);
      break;
    case PREFS.PREF_INT :
      this[aprefName] = PREFS.getIntPref(aprefName);
      break;
    default :
      log.error('error loading pref : ' + aprefName);
      break;
    }
  } catch(e) {
    log.error('error loading pref : ' + aprefName+" - "+e);
  }
};

Prefs.prototype.resetSynchro = function () {
	this.reset('synchroaction');
	this.reset('synchroask');
};

// on ajuste dynamiquement les fonctions de log
// selon la valeur de debug
Prefs.prototype.observe = function(aSubject, aTopic, aData) {
	if (aTopic != "nsPref:changed" ) {
		log.info ('aTopic != nsPref:changed : ' + aTopic);
		return;
	}
	this.loadPref('debug.level', PREFS.PREF_INT);
};

/*
	@param option
	@param value
	@param type : optionnel
*/
// on sauvegarde automatiquement
Prefs.prototype.set = function (option, value, type) {
	//log.debug("set : " + option + ' : ' + value);
	this[option] = value;
	if (type != PREFS.PREF_STRING && type != PREFS.PREF_BOOL && type != PREFS.PREF_INT) {
		type = PREFS.getPrefType(option);
	}
  if (type==PREFS.PREF_INVALID) {
    if (typeof value=="boolean")
      type = PREFS.PREF_BOOL;
    else if (typeof value=="number")
      type = PREFS.PREF_INT;
    else
      type = PREFS.PREF_STRING;
  }
	switch (type) {
	case PREFS.PREF_STRING :
		PREFS.setCharPref(option, value);
		break;
	case PREFS.PREF_BOOL :
		PREFS.setBoolPref(option, value);
		break;
	case PREFS.PREF_INT :
		PREFS.setIntPref(option, value);
		break;
  default :
    log.error('error setting pref : ' + option + " type="+type);
		break;
	}
};

Prefs.prototype.reset = function (option) {
	if (PREFS.prefHasUserValue(option)) {
		PREFS.clearUserPref(option);
		this.loadPref(option, PREFS.getPrefType(option));
	}
};

/**
* @return true if bookmarks.html has changed (based on lastModifiedTime).
**/
Prefs.prototype.storeLastModified = function (aSource) {
  var aProfDir = null;
  try {
	  aProfDir = DIRSERVICE.get("ProfD",CI.nsIFile);
  } catch(e) {
    return(false);
  }

  aProfDir.append("places.sqlite");

  //	var	aBookmarksLastModified = aProfDir.lastModifiedTime;

	var aBookmarksLastModified = aProfDir.fileSize;
	var aResult = true;
	var aPreviousLastModified = PREFS.getCharPref("bookmarksLastModified");
	log.debug("previous:"+aPreviousLastModified+" / current:"+aBookmarksLastModified);
	if( aPreviousLastModified == aBookmarksLastModified ) {
		aResult = false;
	}
	this.set("bookmarksLastModified",aBookmarksLastModified,PREFS.PREF_STRING);

	return aResult;
}



var YOONO_PREFS = new Prefs();

