content: /*
   * Copyright (C) 2015 Actor LLC. <https://actor.im>
   */
  
  package im.actor.runtime.js.threading;
  
  import com.google.gwt.core.client.JavaScriptObject;
  
  /**
   * setInterval/setTimeout implementation
   * that work in background tabs
   */
  public class JsSecureInterval extends JavaScriptObject {
  
      public static native JsSecureInterval create(boolean allowWorkers, Runnable runnable)/*-{
          console.warn("Create jsSecureInterval")
          try {
              if (allowWorkers && typeof(Worker) !== "undefined") {
  
                  var code = "var timerId;\n" +
                  "\n" +
                  "self.addEventListener('message', function(e){\n" +
                  "    switch (e.data.message) {\n" +
                  "        case 'schedule':\n" +
                  "            if (timerId) {\n" +
                  "                clearTimeout(timerId);\n" +
                  "                timerId = null;\n" +
                  "            }\n" +
                  "            timerId = setTimeout(function(){\n" +
                  "                self.postMessage('doSchedule');\n" +
                  "            }, e.data.delay);\n" +
                  "            break;\n" +
                  "        case 'cancel':\n" +
                  "            if (timerId) {\n" +
                  "                clearTimeout(timerId);\n" +
                  "                timerId = null;\n" +
                  "            }\n" +
                  "            break;\n" +
                  "    };\n" +
                  "});\n"
  
                  var codeBlob = new Blob([code]);
                  var codeBlobURL = window.URL.createObjectURL(codeBlob);
  
                  var worker = new Worker(codeBlobURL);
                  var _runnable = runnable;
                  worker.addEventListener('error', function() {
                      console.warn("Worker error")
                  }, false);
                  worker.onmessage = function() {
                      _runnable.@java.lang.Runnable::run()();
                  };
                  return {runnable: runnable, useWebWorker: true, worker: worker};
              }
          } catch (e) {
              // Ignore
          }
  
          return {runnable: runnable, useWebWorker: false};
      }-*/;
  
      protected JsSecureInterval() {
  
      }
  
      public final void scheduleNow() {
          schedule(0);
      }
  
      public native final void schedule(int msec)/*-{
          if (this.useWebWorker) {
              this.worker.postMessage({message: "schedule", delay: msec});
          } else {
              if (this.timerId) {
                  clearTimeout(this.timerId);
                  this.timerId = null;
              }
              var _runnable = this.runnable
              this.timerId = setTimeout(function() {
                  _runnable.@java.lang.Runnable::run()();
              }, msec);
          }
      }-*/;
  
      public native final void cancel()/*-{
          if (this.useWebWorker) {
              this.worker.postMessage({message: "cancel"});
          } else {
              if (this.timerId) {
                  clearTimeout(this.timerId);
                  this.timerId = null;
              }
          }
      }-*/;
  }
  