function BBall(_width, _height) {
  var _self = this;
  this.mode = null;
  this.basket = null;
  this.runs = false;
  this.img = $("Ball");
  this.parent = $("Game");
  this.x = 100;
  this.y = 100;
  this.radius = 0;
  this.vx = this.vy = 0; // velocity * 256
  this.vydelta = 0;
  this.daempfung = 0; // * 256
  this.oldx = this.oldy = 0;
  this.withCeiling = false;
  this.width = _width;
  this.height = _height;
 
  var background;
  var oldvy;

  this.setGravity = function(gravity) {
    this.vydelta = gravity * 10 * this.radius / 8;
    // 102 = 0.4 for radius 8*
  }

  this.setVelocity = function(vx, vy) {
    this.setVelocity(vx, vy, 1);
  }

  this.setVelocity = function(vx, vy, factor) {
    this.vx = (vx << 8) / factor;
    this.vy = (vy << 8) / factor;
    this.oldvy = -1;
  }
  
  this.radius = this.img.width / 2;
  this.setGravity(102);
  this.x = this.width / 2;
  this.y = this.height / 2;
  this.oldx = this.x;
  this.oldy = this.y;
  this.oldvy = -1;
  this.setVelocity(0, 0);
  this.daempfung = 180; // 0.7
  this.runs = false;

  this.setWithCeiling = function(withCeiling) {
    this.withCeiling = withCeiling;
  }

  this.draw = function(_self) {
    if (this.img != null) {  
      this.img.style.left = this.x - this.radius + "px";
      this.img.style.top = this.y - this.radius + "px";
      this.oldx = this.x;
      this.oldy = this.y;
    }
  }

  this.clear = function() {
    if (img != null) {
    }
  }

  this.start = function() {
    this.runs = true;
    this.time = new Date().getTime();
    this.ballthread = window.setInterval(this.run, 50);
    this.mode.shot();
  }

  this.run = function() {
    try {
      var oldtime;
      var diff;
      var repeat;
      var delay = 62;
      oldtime = _self.time;
      _self.time = new Date().getTime();
      diff = delay - (_self.time - oldtime);
      repeat = parseInt(-diff / delay + 2);
      if (repeat > 2) {
        repeat = 2;
      }
      while ((repeat-- > 0) && _self.runs) {
        _self.bewegung();
      }
      //_self.draw(_self);
      //_self.stop();
    }
    catch (e) {
      debug(e);
    }
  }

  this.stop = function() {
    this.vx = 0;
    this.vy = 0;
    this.oldvy = -1;
    this.runs = false;
    window.clearInterval(this.ballthread);
    this.mode.stopped();
  }

  this.inside = function(x, y) {
    return (((this.x - x) * (this.x - x) + (this.y - y) * (this.y - y) - this.radius
        * this.radius) <= 0);
  }

  this.move = function(x, y) {
    var bounced = false;

    this.setXY(x, y);
    if ((Math.abs(this.vx) < 256) && (this.vy <= this.vydelta) && (this.y >= this.height - this.radius)) {
      this.y = this.height - this.radius;
      this.stop();
    }
    bounced = this.checkWall();
    var isBasket = this.checkBasket();
    bounced = bounced | isBasket;
    if (this.checkTreffer() != 0) {
      var y = this.basket.baskety + this.radius / 3;
      if (this.basket.left) {
        this.setXY(this.basket.getBasketWidth() - this.basket.getBasketOpening() / 2, y);
      }
      else {
        this.setXY(this.basket.basketx + this.basket.getBasketOpening() / 2, y);
      }
      this.stop();
      if (this.mode) {
        this.mode.hit();
      }      
    }
    this.draw();
    return !bounced;
  }

  /*
   * protected double atan2(double x, double y) { if ((x == 0.0) && (y == 0.0))
   * return Math.atan2(0.0, 1.0); else return Math.atan2(x, y); }
   */

  this.checkBasket = function() {
    // double angle, vangle, vbetrag;
    var bx = this.basket.basketx, by = this.basket.baskety;

    if (this.inside(bx, by)) {
      // vx = -vx;
      if (Math.abs(this.vx) < 256) {
        this.vx = 256;
      }
      if (bx < this.x) {
        this.vx = Math.abs(this.vx);
      }
      else {
        this.vx = -Math.abs(this.vx);
      }
      this.vy = -this.vy;
      if ((Math.abs(this.vx) > 512) || (Math.abs(this.vy) > 512)) {
        this.Daempfung(100); // 0.4
      }
      return true;
    }
    bx = this.basket.basketx + this.basket.getBasketOpening();
    if (this.inside(bx, by)) {
      if (Math.abs(this.vx) < 256) {
        this.vx = 256;
      }
      if (bx < this.x) {
        this.vx = Math.abs(this.vx);
      }
      else {
        this.vx = -Math.abs(this.vx);
      }
      // vx = -vx;
      this.vy = -this.vy;
      // vy = Math.abs(vy);
      if ((Math.abs(this.vx) > 512) || (Math.abs(this.vy) > 512)) {
        this.Daempfung(100); // 0.8
      }
      // Daempfung(daempfung);
      return true;
    }
    return false;
  }

  this.checkWall = function() {
    var hit = false;
    if (this.x <= this.radius) {
      this.setXY(2 * this.radius - this.x, this.y);
      this.vx = -this.vx;
      this.Daempfung(this.daempfung);
      hit = true;
    }
    else if (this.x >= this.width - this.radius) {
      this.setXY(2 * (this.width - this.radius) - this.x, this.y);
      this.vx = -this.vx;
      this.Daempfung(this.daempfung);
      hit = true;
    }
    if (this.y >= this.height - this.radius) {
      if (this.oldvy < 0) {
        this.oldvy = this.vy;
      }
      if (this.oldvy < this.vy) {
        this.vy = 0;
      }
      this.oldvy = this.vy;
      this.setXY(this.x, this.height - this.radius);
      this.vy = -this.vy;
      this.Daempfung(this.daempfung);
      return true;
    }
    else if (this.withCeiling && this.y <= this.radius) {
      if (this.oldvy < 0) {
        this.oldvy = this.vy;
      }
      if (this.oldvy < this.vy) {
        this.vy = 0;
      }
      this.oldvy = this.vy;
      this.setXY(this.x, 2 * this.radius - this.y);
      this.vy = -this.vy;
      this.Daempfung(this.daempfung);
      return true;
    }
    return hit;
  }

  var lasty = 0;

  this.checkTreffer = function() {
    if ((this.x > this.basket.basketx)
        && (this.x < this.basket.basketx + this.basket.getBasketOpening())
        && (this.y >= this.basket.baskety) && (lasty < this.basket.baskety) && (this.vy >= 0)) {
      lasty = this.y;
      return 1;
    }
    lasty = this.y;
    return 0;
  }

  this.Daempfung = function(daempfung) {
    /*
     * double vbetrag, vangle;
     * 
     * vbetrag = Math.sqrt(vx*vx + vy*vy)*(1 - daempfung); vangle = atan2(vx,
     * vy); //System.out.println(vangle); vx = vbetrag*Math.sin(vangle); vy =
     * vbetrag*Math.cos(vangle);
     */
    this.vx = (this.vx * this.daempfung) >> 8;
    this.vy = (this.vy * this.daempfung) >> 8;
  }

  this.bewegung = function() {
    this.move(this.x + (this.vx >> 8), this.y + (this.vy >> 8));
    /*
     * if ((Math.abs(vx)<256) && (Math.abs(vy)<512) && (y>=height-radius)) { y =
     * height - radius; stop(); }
     */
    this.vy += this.vydelta;
  }

  this.setXY = function(x, y) {
    this.x = x;
    this.y = y;
  }
}