require 'canvas'
require 'thread'

W = 640
H = 480

class State
  attr_accessor :y, :index, :cpu

  def initialize(index, cpu=true)
    @y = H / 2
    @index = index
    @cpu = cpu
  end
end

class PongApp < App
  MAX_PLAYERS = 2
  BOARD_SIZE = 80

  def initialize
    @ws = {}
    @mu = Mutex.new
    @turn = 0

    @bx = W / 2
    @by = H / 2
    @bvx = 5
    @bvy = 5

    @players = Array.new(MAX_PLAYERS){|i|State.new(i)}
  end

  def onTimer
    @turn += 1

    ctx = CanvasContext.new
    ctx.fillStyle = 'rgba(0,0,0,0.8)'
    ctx.fillRect(0, 0, W, H)

    ctx.fillStyle = 'rgb(255,255,255)'

    @bx += @bvx
    @by += @bvy
    if @by < 0
      @bvy = -@bvy
    elsif @by > H
      @bvy = -@bvy
    end

    if @bx < 0
      @bx = W / 2
    elsif @bx > W
      @bx = W / 2
    elsif @bx < 15 && @bvx < 0 && (@players[0].y - @by).abs < BOARD_SIZE / 2
      @bvx = -@bvx
    elsif @bx > W-15 && @bvx > 0 && (@players[1].y - @by).abs < BOARD_SIZE / 2
      @bvx = -@bvx
    end

    ctx.add_code("ctx.drawImage(icon, #{@bx-16}, #{@by-16});")
    #ctx.beginPath()
    #ctx.arc(@bx, @by, 15, 0, Math::PI * 2, 1)
    #ctx.fill()

    @players.each{|player|
      if player.cpu
      end

      side = player.index % 2
      x = side == 0 ? 5 : W - 15
      ctx.fillRect(x, player.y - BOARD_SIZE / 2, 10, BOARD_SIZE)
    }

#     ctx.fillStyle = 'rgb(128,0,0)'
#     7.times{|i|
#       r = ((i+3) * Math::PI / 180) * @turn
#       x = 150 * Math.cos(r) + W / 2
#       y = 150 * Math.sin(r) + 250
#       ctx.beginPath()
#       ctx.arc(x, y, 10, 0, Math::PI * 2, 1)
#       ctx.fill()
#     }

    @mu.synchronize do
      @ws.each do |ws, st|
        begin
          ws.send(ctx.code)
        rescue
          puts $!
          puts $!.backtrace
          @ws.delete(ws)
        end
      end
    end
  end

  def onOpen(ws)
    @mu.synchronize do
      index = (0...MAX_PLAYERS).find{|i|@players[i].cpu}
      if index
        puts "Add user#{index}"
        st = State.new(index, false)
        @ws[ws] = st
        @players[index] = st
      else
        @ws[ws] = nil
      end
    end
  end

  def onClose(ws)
    @mu.synchronize do
      if @ws[ws]
        index = @ws[ws].index
        puts "Remove user#{index}"
        @players[index].cpu = true
      end
      @ws.delete(ws)
    end
  end

  def onMouseMove(ws, x, y)
    if @ws[ws]
      @ws[ws].y = y
    end
  end
end

def newApp
  PongApp.new
end
