/*
 * A basic filter for option values
 */
function OptionFilter() {

  /*
   * Converts the option value
   */
  this.convert = function(value) {
  
    return value;
  }
  
  /*
   * Restores the option value
   */
  this.revert = function(value) {
  
    return value;
  }
}

/*
 * An option value filter for data
 * representable in JSON notation
 */
function JSONOptionFilter() {

  /*
   * Converts a literal object into a JSON string
   */
  this.convert = function(value) {
  
    return JSON.stringify(value);
  }
  
  /*
   * Converts a JSON string into a literal object
   */
  this.revert = function(value) {
  
    try {
    
      return JSON.parse(value);
    } catch (e) {
    
      return null;
    }
  }
}
JSONOptionFilter.prototype = new OptionFilter;
providers.addProvider("optionFilters", "view.visibleProperties", new JSONOptionFilter());

/*
 * An option value filter for storage
 * and retrieval of source lists
 */
function SourcesOptionFilter() {

  /*
   * Converts a list of sources
   * into a list of source URLs
   */
  this.convert = function(sources) {
  
    var value = [];
    
    for (var i = 0; i < sources.length; ++i) {
    
      value.push(sources[i].url);
    }
  
    return SourcesOptionFilter.prototype.convert.call(this, value);
  }
}
SourcesOptionFilter.prototype = new JSONOptionFilter;
providers.addProvider("optionFilters", "sourceURLs", new SourcesOptionFilter());

var settings = {};

/**
 * Stores and retrieves options including value filtering
 */
(function() {

  var $this = $(this);
  // Local reference to the Storage object
  var storage = window.localStorage || {};
  // Map of filters to apply on option value get/set
  var filters = {};
  
  /**
   * Retrieves the value of an option
   */
  this.get = function(option) {
  
    var value = storage[option];
    var filter = providers.getProvider("optionFilters", option);
    
    if (filter) {
    
      value = filter.revert(value);
    }
  
    return value;
  };
  
  /**
   * Stores the value of an option
   */
  this.set = function(option, value) {
  
    var filter = providers.getProvider("optionFilters", option);
    
    if (filter) {
    
      value = filter.convert(value);
    }
    
    if (!value || value === storage[option]) {
    
      return;
    }
    
    storage[option] = value;

    var optionSetEvent = new jQuery.Event("optionSet");
    optionSetEvent.option = option;
    optionSetEvent.value = value;
    
    $this.trigger(optionSetEvent);
  
    return value;
  };
  
  /*
   * Registers a default value of an option
   */
  this.setDefault = function(option, defaultValue) {
  
    if (!(option in storage) || !this.get(option)) {
    
      this.set(option, defaultValue);
    }
  };
  
  this.toString = function() {
  
    return "[object SettingsManager]";
  };
}).call(settings);
