     else
       battle_field_object instanceof Missile
   type: -> "water"
-  layer: 0
 
 class IceTerrain extends Terrain
   accept: (battle_field_object) -> true
   type: -> "ice"
-  layer: 0
 
 class GrassTerrain extends Terrain
   accept: (battle_field_object) -> true
   type: -> "grass"
-  layer: 2
 
 class HomeTerrain extends Terrain
   is_defeated: false

class Commander
  constructor: (@battle_field_object) ->
    @direction = @battle_field_object.direction
  direction_map: {
    up: 0,
    down: 180,
    left: 270,
    right: 90
  }
  next_commands: -> []
  direction_command: (direction) ->
    {
      type: "direction",
      params: { direction: direction }
    }
  start_move_command: -> { type: "start_move" }
  stop_move_command: -> { type: "stop_move" }
  fire_command: -> { type: "fire" }

class UserCommander extends Commander
  constructor: (@battle_field_object, key_setting) ->
    super(@battle_field_object)
    for action, key of key_setting
      @key_map[key] = action
    @clear_inputs()
  key_map: {}
  inputs: null
  inputs_key_pressed: {
    up: false,
    down: false,
    left: false,
    right: false
  }
  clear_inputs: () ->
    @inputs = {
      up: [],
      down: [],
      left: [],
      right: [],
      fire: []
    }
  is_pressed: (action) ->
    @inputs_key_pressed[action]
  add_key_event: (type, key_code) ->
    switch type
      when "keyup"
        return true if _.isUndefined(@key_map[key_code])
        action = @key_map[key_code]
        @inputs_key_pressed[action] = false
        @inputs[action].push("keyup")
      when "keydown"
        return true if _.isUndefined(@key_map[key_code])
        action = @key_map[key_code]
        @inputs_key_pressed[action] = true
        @inputs[action].push("keydown")
  commands: []
  next_commands: ->
    @commands = []
    for action, key_actions of @inputs
      continue if _.size(key_actions) == 0
      switch (action)
        when "up", "down", "left", "right"
          break if @change_direction(action)
          @do_move(action)
        when "fire"
          @commands.push(@fire_command())
    for action in ["up", "down", "left", "right"]
      if @is_pressed(action)
        @change_direction(action)
        @commands.push(@start_move_command())
    @clear_inputs()
    @commands
  change_direction: (action) ->
    new_direction = @direction_map[action]
    if @direction != new_direction
      @direction = new_direction
      @commands.push(@direction_command(new_direction))
      true
    else
      false
  do_move: (action) ->
    keyup = _.contains(@inputs[action], "keyup")
    keydown = _.contains(@inputs[action], "keydown")
    if keydown
      @commands.push(@start_move_command())
    else
      @commands.push(@stop_move_command()) if keyup

class EnemyAICommander extends Commander
  next_commands: -> []

class MissileCommander extends Commander
  constructor: (@battle_field_object) ->
  next_commands: -> [@start_move_command()]

class TerrainBuilder
  constructor: (@battle_field, @default_width, @default_height) ->

class Tank extends MovableBattleFieldObject
  accept: (battle_field_object) ->
    (battle_field_object instanceof Missile) and (battle_field_object.parent is this)

  life: 1
  set_life: (@life) ->
  dead: -> @life <= 0
  power: 1
  level: 1
  max_missile: 1
  missiles: []
  update_level: (@level) ->
    switch @level
      when 1
        @power = 1
        @max_missile = 1
      when 2
        @power = 2
        @max_missile = 2

  ship: false
  update_ship: (@ship) ->

  guard: false
  update_guard: (@guard) ->

  fire: () ->
    if _.size(@missiles) < @max_missile
      missile = @battle_field.add_missile(this)
      @missiles.push(missile)

  integration: (delta_time) ->
    super(delta_time)
    @fire() for command in _.select(@commands, (command) -> command.type == "fire")

  missile_born_area: () -> @view.missile_born_area()

  delete_missile: (missile) ->
    @missiles = _.without(@missiles, missile)

