dialect "objectdraw"
import "animation" as animator
import "random" as rand
type Animated = {
  start -> Done
}

// Create bouncing ball with diameter ballSize that stays inside boundary
// and moves by a randomly chosen amount in x and y coordinates between
// minShift and maxShift pixels each move.  It can be hit by paddle.
class ballSize (ballSize: Number) inside (boundary: Graphic2D) 
              moveRange (minShift: Number,maxShift: Number) 
              hitBy (paddle: Graphic2D) on (canvas: DrawingCanvas) -> Animated {

    // randomly choose how far the ball moves each step in x and y directions
    var xShift: Number := rand.integerIn (minShift) to (maxShift)
    var yShift: Number := rand.integerIn (minShift) to (maxShift)
    def initYShift: Number = yShift
    
    def pauseTime: Number = 30  // time gap between moves of ball

    // start the ball bouncing in court
    method start -> Done {
        // representation of the ball as oval
        def theBall: Graphic2D = filledOvalAt(boundary.location+(1@1)) 
                             size (ballSize @ ballSize) on (canvas)
                    
        // Farthest ball can move to the right         
        def ballRight: Number = boundary.x + boundary.width - theBall.width

        animator.while{theBall.y < canvas.height} pausing (pauseTime) do {
            theBall.moveBy(xShift,yShift)
            // Fix speed and position if goes off sides
            if (theBall.x < boundary.x) then {  // off court on left
                xShift := -xShift
                theBall.moveTo(boundary.x @ theBall.y)
            } elseif {theBall.x > ballRight} then { // off on right
                xShift := -xShift
                theBall.moveTo (ballRight @ theBall.y) 
            } 
            
            // Fix speed and position if goes off top or hits paddle
            if (theBall.y < boundary.y) then {
                yShift := -yShift
                theBall.moveTo(theBall.x @ boundary.y)
            } elseif {theBall.overlaps(paddle)} then {
                yShift := -initYShift
            }
        } finally {
            theBall.removeFromCanvas
        }

    }
}