if (!('startsWith' in String)) {
  String.prototype.startsWith = function(str) {
    return (this.match("^" + str.regexEscape()) || [null])[0] === str;
  };
}
window.Sparkbuy = (function() {
  var root = this;
  var listeners = {};
  var storage = root.localStorage;
  var store = function(obj, key, val) {
    var old = obj[key];
    if (old != val) {
      var l = listeners[key]
      if (val) {
        obj[key] = val;
      } else {
        delete obj[key];
      };
      if (storage) {
        if (val) {
          try {
            storage.setItem(key, JSON.stringify(val));
          } catch(error) {
            storage.removeItem(key);
          }
        } else {
          storage.removeItem(key)
        }
      }
      if (l) {
        var len = l.length;
        for (var i = 0; i < len; ++i) {
          l[i](val, old);
        }
      };
    }
  }
  var Sparkbuy = function() {
    var sparkbuy = arguments.callee;
    var args = arguments[0];
    if (!args) {
      return;
    }
    if (arguments.length == 1 && isString(args)) {
      return sparkbuy[args];
    }
    if (arguments.length == 2) {
      store(sparkbuy, arguments[0], arguments[1])
    } else {
      for (var key in args) {
        if (args.hasOwnProperty(key)) {
          store(sparkbuy, key, args[key]);
        }
      }
    }
  }
  var paramCacheBuster = Sparkbuy.cacheBuster = function(p) {
    return p + "?" + new Date().getTime();
  }
  var fullCacheBuster = function(p) {
    return "//assets" + p.hashCode(4) + ".sparkbuy.com" + pathCacheBuster(p)
  }
  var pathCacheBuster = function(p) {
    return "/rel-" + Sparkbuy.releaseNumber + p;
  }
  var updateEnvironment = function(e) {
    if (e == 'production') {
      Sparkbuy.cacheBuster = fullCacheBuster;
    } else if (e == 'staging' || e == 'preview') {
      Sparkbuy.cacheBuster = pathCacheBuster;
    } else {
      Sparkbuy.cacheBuster = paramCacheBuster;
    }
  }
  Sparkbuy.when = function(key, f) {
    var l = listeners[key], val = Sparkbuy[key];
    if (!l) {
      l = listeners[key] = [];
    }
    if (val) {
      f(val);
    };
    l.push(f);
  }
  Sparkbuy.once = function(key, f) {
    Sparkbuy.when (key, function(val) {
      if (arguments.callee._called) {
        return;
      }
      f(val);
      arguments.callee._called = true;
    });
  }
  Sparkbuy.json = function(key, version, val) {
    fullkey = key + '/' + version;
    if (storage) {
      for (var i = 0; i < storage.length; ++i) {
        var cur = storage.key(i);
        if (cur != fullkey && cur.startsWith(key)) {
          storage.removeItem(cur);
        }
      }
    }
    store(Sparkbuy, fullkey, val);
  }
  var initFunction = function(key) {
    return function(dfd) {
      var key = root.Sparkbuy[key]
      if (key) {
        dfd.resolve(key);
      }
    }
  }
  isString = function(obj) {
    return !!(obj === '' || (obj && obj.charCodeAt && obj.substr));
  }
  Sparkbuy.when('environment', updateEnvironment);
  if (storage) {
    for (var i = 0; i < storage.length; ++i) {
      var key = storage.key(i), val = null;
      try {
        val = JSON.parse(storage.getItem(key))
      } catch (error) {
        // bogus data in the storage. remove it.
        storage.removeItem(key);
      }
      store(Sparkbuy, key, val);
    }
  }
  return Sparkbuy;
}).call(window);

