local system_constructor = require("love_src.wrapper.Concord.system")
local race = require("love_src.src.world.top_down_race.component.race")
local racing_phy = require("love_src.src.system.racing_phy")

local component = require("love_src.wrapper.Concord.component")

local vm = require("lib.vornmath")

local system = {}

system.__index = system

system.pool = {
  pool = {
    race.dict.accel,
    race.dict.brake,
    race.dict.grip,
    race.dict.max_speed,
    race.dict.steer,
    race.dict.velocity,
    race.dict.decel,
    race.dict.drag
  }
}

system.components = {
  [race.dict.accel] = race.accel,
  [race.dict.brake] = race.brake,
  [race.dict.grip] = race.grip,
  [race.dict.max_speed] = race.max_speed,
  [race.dict.steer] = race.steer,
  [race.dict.velocity] = race.velocity,
  [race.dict.decel] = race.decel,
  [race.dict.drag] = race.drag
}

function system.new()
  local new_system = system_constructor.new("velocity", system.pool)
  if (new_system) then
    for k, v in pairs(system) do
		  new_system[k] = v
	  end
    return new_system
  else
    return nil
  end
end

local function get(e)
  return
    e[race.dict.accel].data,
    e[race.dict.brake].data,
    e[race.dict.grip].data,
    e[race.dict.max_speed].data,
    e[race.dict.steer].data,
    e[race.dict.velocity].data,
    e[race.dict.drag].data,
    e[race.dict.decel].data
end

local function draw(text, x, y, sx, sy, angle, image, origin)
  love.graphics.push()
  love.graphics.scale(sx, sy)
  -- love.graphics.rotate(angle)
  love.graphics.draw(image, x, y, angle, 1, 1, origin[1], origin[2])
  love.graphics.print(text, x, y)
  love.graphics.pop()
end

function system:load()
  component.component("race.pos", function (c, x, y)
    c.data = vm.vec2(x, y)
  end)
  component.component("race.scale", function (c, x, y)
    c.data = vm.vec2(x, y)
  end)
  component.component("race.angle", function (c, x)
    c.data = x
  end)
  component.component("race.image", function (c, x)
    c.data = {
      image = love.graphics.newImage(x)
    }
    c.data.origin = vm.vec2(c.data.image:getWidth()/2, c.data.image:getHeight()/2)
  end)

  for _, e in ipairs(self.pool) do
    e:give("race.pos", 10, 10)
    e:give("race.scale", 1, 1)
    e:give("race.angle", 0)
    e:give("race.image", "love_src/asset/image/arrow_right.png")
  end
end

function system:update(dt)
  for _, e in ipairs(self.pool) do
    local accel, brake, grip, max_speed, steer, velocity, drag, decel = get(e)

    local up = love.keyboard.isDown("up")
    local down = love.keyboard.isDown("down")
    local left = love.keyboard.isDown("left")
    local right = love.keyboard.isDown("right")

    if (up) then
      e[race.dict.velocity].data = racing_phy.accelerate(dt, 1, velocity, max_speed, accel - drag)
    elseif(down) then
      e[race.dict.velocity].data = racing_phy.accelerate(dt, -1, velocity, max_speed, accel - drag, -max_speed)
    else
      e[race.dict.velocity].data = racing_phy.accelerate(dt, 1, velocity, max_speed, -drag -decel)
    end

    local angle = e["race.angle"].data
    if (left) then
      e["race.angle"].data = angle - 1 * dt
    end
    if (right) then
      e["race.angle"].data = angle + 1 * dt
    end

    angle = e["race.angle"].data
    cos = math.cos(angle)
    sin = math.sin(angle)

    velocity = e[race.dict.velocity].data

    e["race.pos"].data[1] = e["race.pos"].data[1] + velocity * cos
    e["race.pos"].data[2] = e["race.pos"].data[2] + velocity * sin
    -- print(racing_phy.drift(dt, 1, velocity, max_speed, 2, 10))
  end
end

function system:draw()
  for _, e in ipairs(self.pool) do
    local accel, brake, grip, max_speed, steer, velocity = get(e)
    local x, y, sx, sy, angle = e["race.pos"].data[1], e["race.pos"].data[2], e["race.scale"].data[1], e["race.scale"].data[2], e["race.angle"].data
    local image = e["race.image"].data.image
    local origin = e["race.image"].data.origin
    draw(velocity, x, y, sx, sy, angle, image, origin)
  end
end

return system
