var SuberUploaderClass = function(){
  var myself = this;
  var target;
  var token;
  var progressURL;
  var processURL;
  var updateTimer;
  var responsePending = 0;
  var t0;
  var callingWindow = self;
  var running = false;

  var callbacks = {};

  this.startUpload = function(_target,_callingWindow,_token) {
    target = _target;
    token = _token;
    callingWindow = _callingWindow;
    responsePending = 0;
    updateTimer = new PeriodicalExecuter(function(){
      if (responsePending == 0) {
        responsePending++;
        new Ajax.Request(progressURL, {
          parameters: { target: target, t0: t0, i: token },
          onSuccess: function(response){
            responsePending--;
            if ( ! response.responseJSON ) {
              return;
            }
            var p = response.responseJSON;
            this.updateProgress(p);
            if ((p.status == 2) || (p.status == 4) ) {
              this.finishUpload(p);
            }
          }.bind(this)
        });
      }
    }.bind(this), 1);
    running = true;
  }

  this.cancelUpload = function(reload) {
    // console.log("aborting Upload.");
    if (updateTimer) {
      updateTimer.stop();
    }
    try {
      if (window.stop) {
        callingWindow.stop();
      }
      else {
        if( window.document.execCommand) {
          callingWindow.document.execCommand('Stop',false);
        }
      }
    }
    catch(e) {
      console.log(e.message);
    }

    if (reload && running) {
      try {
        callingWindow.document.location.href = callingWindow.document.location.href;
      }
      catch(e) {
        console.log(e.message)
      }
    }
    running = false;

    // console.log("Upload aborted");
  }

  this.updateProgress = function(p) {
    if (! p.filesize) {
      callbacks.onProgress(1,1,0);
    }
    else {
      var elapsedTime   = p.last_update - p.starttime;
      var remaining     = (p.filesize - p.bytes_read);
      var ratio         = p.ratio;
      var uploadSpeed   = p.speed;
      var remainingTime = (uploadSpeed) ? remaining / uploadSpeed : null;
      callbacks.onProgress(p.bytes_read, p.ratio, remainingTime);
      if ( p.status == 8 ) {
        // importing
        callbacks.onStandby();
      };
    }
  }

  this.finishUpload = function(p) {
    if (updateTimer) {
      updateTimer.stop();
    }
    if (p.status == 4) {
      // console.log("Upload Error: "+p.msg);
      var result = callbacks.onError(p.msg);
      // console.log("callbacks.onError finished");
      this.cancelUpload();
      // console.log("cancellation finished");
      return result;
    }
    callbacks.onSuccess(p.msg);
  }

  var onError = function (result) {
    updateTimer.stop();
    // console.log("onError called");
    callbacks.onError();
  }

  this.init = function(_progressURL, _params, _callbacks){
    var paramString = '?'+_params.toQueryString();

    // progressURL = _progressURL + paramString;
    progressURL = _progressURL;
    console.log(progressURL);

    t0          = _params.get('t0');

    callbacks = Object.extend({
      onProgress: function(){},
      onSuccess:  function(){},
      onError:    function(){},
      onStandby:  function(){}
    }, _callbacks || {});
  };
}

