var core = use('core')
var camera = use('camera')
var compositor = use('compositor')
var input = use('input')
var shape = use('shape2d')
var text2d = use('text2d')

var GW = 480, GH = 270
var paddleW = 8, paddleH = 50, speed = 200
var ballSize = 8
var bvx = 220, bvy = 150
var score1 = 0, score2 = 0

// Cameras: game at pixel-art res, HUD at native
var game_cam = camera.make({width: GW, height: GH, pos: {x: GW / 2, y: GH / 2}})
var hud_cam = camera.make({width: 960, height: 540, pos: {x: 480, y: 270}})

// Action mapping
input.configure({
  action_map: {
    p1_up: ['w'],
    p1_down: ['s'],
    p2_up: ['up'],
    p2_down: ['down']
  }
})

// Retained shapes — game plane
var midline = shape.rect({
  pos: {x: GW / 2, y: GH / 2}, width: 2, height: GH,
  fill: {r: 0.3, g: 0.3, b: 0.3, a: 1}, plane: 'game'
})

var p1 = shape.rect({
  pos: {x: 20, y: GH / 2}, width: paddleW, height: paddleH,
  fill: {r: 1, g: 1, b: 1, a: 1}, plane: 'game'
})

var p2 = shape.rect({
  pos: {x: GW - 20, y: GH / 2}, width: paddleW, height: paddleH,
  fill: {r: 1, g: 1, b: 1, a: 1}, plane: 'game'
})

var ball = shape.rect({
  pos: {x: GW / 2, y: GH / 2}, width: ballSize, height: ballSize,
  fill: {r: 1, g: 1, b: 1, a: 1}, plane: 'game', groups: ['glow']
})

// HUD plane — score text
var score_label = text2d({
  text: "0   0", pos: {x: 420, y: 490},
  plane: 'hud', size: 32, color: {r: 1, g: 1, b: 1, a: 1}
})

function reset_ball() {
  ball.pos.x = GW / 2
  ball.pos.y = GH / 2
  bvy = (bvy > 0 ? -1 : 1) * 150
  bvx = bvx > 0 ? -220 : 220
}

// Compositor: game plane with bloom on ball, HUD overlay
var comp_config = {
  clear: {r: 0, g: 0, b: 0, a: 1},
  planes: [
    {name: 'game', camera: game_cam, resolution: {width: GW, height: GH}, presentation: 'letterbox'},
    {name: 'hud', camera: hud_cam, resolution: {width: 960, height: 540}, presentation: 'stretch'}
  ],
  group_effects: {
    glow: {effects: [{type: 'bloom', threshold: 0.3, intensity: 2}]}
  }
}

core.start({
  width: 960, height: 540, title: "Pong",

  update: function(dt) {
    var down = input.player1().down()

    // Move paddles
    if (down.p1_up) p1.pos.y += speed * dt
    if (down.p1_down) p1.pos.y -= speed * dt
    if (down.p2_up) p2.pos.y += speed * dt
    if (down.p2_down) p2.pos.y -= speed * dt

    // Clamp paddles
    var hh = paddleH / 2
    if (p1.pos.y < hh) p1.pos.y = hh
    if (p1.pos.y > GH - hh) p1.pos.y = GH - hh
    if (p2.pos.y < hh) p2.pos.y = hh
    if (p2.pos.y > GH - hh) p2.pos.y = GH - hh

    // Move ball
    ball.pos.x += bvx * dt
    ball.pos.y += bvy * dt

    // Bounce top/bottom
    var bs = ballSize / 2
    if (ball.pos.y - bs < 0 || ball.pos.y + bs > GH) bvy = -bvy

    // Paddle collisions
    var bx = ball.pos.x, by = ball.pos.y
    var pw = paddleW / 2, ph = paddleH / 2
    if (bx - bs < p1.pos.x + pw && bx + bs > p1.pos.x - pw &&
        by + bs > p1.pos.y - ph && by - bs < p1.pos.y + ph)
      bvx = abs(bvx)
    if (bx + bs > p2.pos.x - pw && bx - bs < p2.pos.x + pw &&
        by + bs > p2.pos.y - ph && by - bs < p2.pos.y + ph)
      bvx = -abs(bvx)

    // Scoring
    if (bx < 0) {
      score2++
      score_label.text = score1 + "   " + score2
      reset_ball()
    }
    if (bx > GW) {
      score1++
      score_label.text = score1 + "   " + score2
      reset_ball()
    }
  },

  render: function() {
    return compositor.execute(compositor.compile(comp_config))
  }
})
