local object = require '../engine/object'
local animator = require '../engine/animator'

Gridwalker = class()

Gridwalker.speed = 2
Gridwalker.collisionTestSize = 12
Gridwalker.neighbourOffsetX = (object.width - Gridwalker.collisionTestSize) / 2
Gridwalker.neighbourOffsetY = object.width - Gridwalker.collisionTestSize * 1.5
Gridwalker.testShape = nil
Gridwalker.objectinfo = nil
Gridwalker.animation = nil

function Gridwalker:sendKey(key)
  if key == "w" or key == "up" then
    self:up()
  end

  if key == "s" or key == "down" then
    self:down()
  end

  if key == "d" or key == "right" then
    self:right()
  end

  if key == "a" or key == "left" then
    self:left()
  end
end

function Gridwalker:stopAnimation()
  self.animation:pauseAtStart()
end

function Gridwalker:up()
  local newX = self.objectinfo.x
  local newY = self.objectinfo.y - self.speed

  self.animation = self.animator.walk_up

  self:move(newX, newY)
end

function Gridwalker:down()
  local newX = self.objectinfo.x
  local newY = self.objectinfo.y + self.speed

  self.animation = self.animator.walk_down

  self:move(newX, newY)
end

function Gridwalker:right()
  local newX = self.objectinfo.x + self.speed
  local newY = self.objectinfo.y

  self.animation = self.animator.walk_right

  self:move(newX, newY)
end

function Gridwalker:left()
  local newX = self.objectinfo.x - self.speed
  local newY = self.objectinfo.y

  self.animation = self.animator.walk_left

  self:move(newX, newY)
end

function Gridwalker:init()
  self.testShape = collider:addRectangle(self.objectinfo.x + self.neighbourOffsetX, self.objectinfo.y + self.neighbourOffsetY, self.collisionTestSize, self.collisionTestSize)
  collider:setPassive(self.testShape)

  self.animator = Animator:new(self.objectinfo.image:getWidth(), self.objectinfo.image:getHeight())
  self.animation = self.animator.walk_up
  self.animation:pauseAtStart()
end

function Gridwalker:setTestShape(x, y)
  local testX = x + self.neighbourOffsetX + self.collisionTestSize / 2
  local testY = y + self.neighbourOffsetY + self.collisionTestSize / 2

  self.testShape:moveTo(testX, testY)

  return testX, testY
end

function Gridwalker:move(x, y)
  local noCollision = true

  local testX, testY = self:setTestShape(x, y)

  for other in pairs(collider:shapesInRange(testX, testY, testX + self.collisionTestSize, testY + self.collisionTestSize)) do
    if self.testShape:collidesWith(other) then
      noCollision = false
      break
    end
  end

  if noCollision then
    self.animation:resume()
    self.objectinfo.x = x
    self.objectinfo.y = y
  else
    self:setTestShape(self.objectinfo.x, self.objectinfo.y)
  end
end