EXPORTED_SYMBOLS = ["module"];
var module = function (application) {
var log = function (message) {
application.api.logger.trace("[Lazy Updater] " + message);
}
;
var mailman = application.mailman;
var Cache = application.Cache;
function LazyUpdater() {
this._latestUpdate = 0;
this._interval = null;
this._initialized = false;
this._started = false;
this._timer = null;
this.__timer = null;
}

LazyUpdater.prototype.init = function (settingName, message) {
if (this._initialized)
{
log("Already initialized.");
return;
}

this._message = message;
this._settingName = settingName;
this._cache = new Cache("updater.json");
this._latestUpdate = this._cache.get("latest_update") || 0;
log("Latest update timestamp: " + this._latestUpdate);
var updater = this;
mailman.addSubscriber({
subject: "settings-available",
subscriber: {
receive: function ({body: wiid}) {
var interval = application.api.Settings.getValue(updater._settingName,wiid);
updater._setInterval(interval);
}
}});
mailman.addSubscriber({
subject: "setting-changed",
subscriber: {
receive: function ({body: data}) {
if (updater._settingName === data.name)
{
updater._setInterval(data.value);
}

}
}});
this._initialized = true;
}
;
LazyUpdater.prototype._setInterval = function (interval) {
log("Update interval is " + interval + " min.");
this._interval = interval;
if (0 === this._interval)
{
this._interval = Infinity;
}

if (this._started)
{
this._scheduleNextUpdate();
}

}
;
LazyUpdater.prototype.start = function () {
if (! this._initialized)
{
log("Call init() before start().");
return;
}

if (this._started)
{
log("Already started.");
return;
}

this._scheduleNextUpdate();
this._started = true;
}
;
LazyUpdater.prototype._fireUpdateEvent = function () {
log("Send message " + JSON.stringify(this._message) + ".");
mailman.send(this._message);
this._latestUpdate = (new Date()).getTime();
}
;
LazyUpdater.prototype._scheduleNextUpdate = function () {
if (null === this._interval)
{
log("Update interval is unknown for now.");
return;
}

var updatesMaster = this;
var newTimeout;
var currentTime = (new Date()).getTime();
var intervalInMilliseconds = this._interval * 60 * 1000;
var gap = currentTime - this._latestUpdate;
if (gap > intervalInMilliseconds)
{
newTimeout = intervalInMilliseconds;
this._fireUpdateEvent();
}
 else
{
newTimeout = intervalInMilliseconds - gap;
}

log("Next update scheduled in ~" + Math.round(newTimeout / 1000 / 60) + " minutes (" + Math.round(newTimeout / 1000) + " seconds).");
if (null !== this._timer)
{
this._timer.cancel();
}

this._timer = this.__timer ? this.__timer : (this.__timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer));
this._timer.initWithCallback({
notify: function () {
log("Run scheduled update.");
updatesMaster._fireUpdateEvent();
updatesMaster._scheduleNextUpdate();
}
},newTimeout,Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}
;
LazyUpdater.prototype.stop = function () {
if (false === this._started)
{
log("Already stopped.");
return;
}

if (null !== this._timer)
{
this._timer.cancel();
}

this._started = false;
}
;
LazyUpdater.prototype.destroy = function () {
this.stop();
this._cache.put("latest_update",String(this._latestUpdate));
}
;
return LazyUpdater;
}
;
