local Cursor = Object:extend()

local maputils = require "scenes.battlesystem.utils"
local TweenManager = require "game.modules.tweenmanager"

function Cursor:new(world)
  self.world  = world
  self.scene  = world.scene
  self.assets = world.assets

  self.tweens = TweenManager(self)

  self.x = 1
  self.y = 1
  self.isActive = false
  self.tx = 1
  self.ty = 1

  self.signal = ""

  self.grid = maputils.newEmptyMap()
end

function Cursor:set(x, y, signal, subSignal)
  self.x = math.max(math.min(x, 12), 1)
  self.y = math.max(math.min(y, 07), 1)
  self.initialx = self.x
  self.initialy = self.y
  self.tx = self.x
  self.ty = self.y

  self:placeInGrid()

  self.isActive   = true
  self.signal     = signal or ""
  self.subSignal  = subSignal or ""

  self.world:setActiveGridFromGrid(self.grid)
end

function Cursor:placeInGrid()
  while (self.grid[self.y][self.x] == 0) do
    core.debug:print("cursor", "testing position " .. self.x .. " " .. self.y)
    -- On teste d'abord les position > initialx
    if self.x >= self.initialx then
      if self.x >= 12 then
        -- cependant, si on est au maximum, on se place juste avant
        self.x = self.initialx - 1
      else
        self.x = self.x + 1
      end
    else
      if self.x <= 1 then
        -- cependant, si on est au minimum, on doit tester une autre ligne
        self.x = self.initialx
        if self.y >= self.initialy then
          -- on test d'abord les positions en dessous de la position initiales
          if self.y >= 7 then
            self.y = self.initialy - 1
          else
            self.y = self.y + 1
          end
        else
          if self.y <= 1 then
            core.debug:error("cursor", "map was empty")
          else
            self.y = self.y - 1
          end
        end
      else
        -- sinon, on test les positions avant
        self.x = self.x - 1
      end
    end
  end

  self.tx = self.x
  self.ty = self.y
end

function Cursor:setGrid(ox, oy, shape, size, direction, whitelistedEntity)
  self.grid = maputils.newEmptyMap()

  for y, line in ipairs(self.grid) do
    for x, case in ipairs(line) do
      if not maputils.isInMask(x, y, ox, oy, shape, size, direction) then
        self.grid[y][x] = 0
      else
        if (self:testPoint(x, y, whitelistedEntity)) then
          self.grid[y][x] = 1
        else
          self.grid[y][x] = 0
        end
      end
    end
  end

  self.world:setActiveGridFromGrid(self.grid)
end

function Cursor:setGridIgnoreActor(ox, oy, shape, size, direction)
  self.grid = maputils.newEmptyMap()

  for y, line in ipairs(self.grid) do
    for x, case in ipairs(line) do
      if maputils.isInMask(x, y, ox, oy, shape, size, direction) then
        self.grid[y][x] = 1
      end
    end
  end

  self.world:setActiveGridFromGrid(self.grid)
end

function Cursor:testPoint(x, y, whitelistedActor)
  if  ((self.world:getActorInCase(x, y) == nil) or
      (self.world:getActorInCase(x, y) == whitelistedActor) and (whitelistedActor ~= nil)) and
      (self.world.map:getTerrain(x, y) ~= 3) then
    return true
  else
    return false
  end
end

function Cursor:gridIsActive(x, y)
  if self.grid[y] ~= nil then
    return (self.grid[y][x] == 1)
  else
    return false
  end
end

function Cursor:getGrid()
  if (self.isActive) then
    return self.grid
  else
    return maputils.newFullMap()
  end
end

function Cursor:resetGrid()
  self.grid = EmptyGrid
end

function Cursor:unset()
  self.isActive = false
end

function Cursor:update(dt)
 if (self.isActive) then
   local keys = self.scene:getKeys(1)

   if (keys["up"].isDown and self.y == self.ty) then
     dy     = math.max(self.y - 1, 1)
     if (self.grid[dy][self.x] == 1) then
       self.y = dy
       self:addTween()
     end
   end
   if (keys["down"].isDown and self.y == self.ty) then
     dy     = math.min(self.y + 1, 7)
     if (self.grid[dy][self.x] == 1) then
       self.y = dy
       self:addTween()
     end
   end
   if (keys["left"].isDown and self.x == self.tx) then
     dx     = math.max(self.x - 1, 1)
     if (self.grid[self.y][dx] == 1) then
       self.x = dx
       self:addTween()
     end
   end
   if (keys["right"].isDown and self.x == self.tx) then
     dx     = math.min(self.x + 1, 12)
     if (self.grid[self.y][dx] == 1) then
       self.x = dx
       self:addTween()
     end
   end

   if (keys["A"].isPressed) then
     self.world:sendSignalToCurrentBattler(self.signal, self.subSignal)
   end

   self.tweens:update(dt)
 end
end

function Cursor:addTween()
  self.tweens:newTween(0, 0.2, {tx = self.x, ty = self.y}, 'linear')
end

function Cursor:drawBottom()

  if (self.isActive) then
    local x, y, frame
    x, y = maputils.gridToPixel(self.tx, self.ty, true)

    self.assets.sprites["cursorground"]:drawAnimation(x, y, 0, 1, 1, 14, 6)
  end

end

function Cursor:drawTop()

  if (self.isActive) then
    local x, y
    x, y = maputils.gridToPixel(self.tx, self.ty, true)

    self.assets.images["cursorpeak"]:draw(x, y - 24, 0, 1, 1, 7, 26)
  end

end

return Cursor
