Room = class("Room")

require "player"
require "box"
require "wall"

function Room:initialize(t)
	self.exits = t.exits
	self.name = t.name
	self.player = {}
	self.collideables = {
		red = {},
		green = {},
		blue = {}
	}

	self.activeColors = {
		red = false, green = false, blue = false
	}

	for color, coords in pairs(t.player) do
		self.player[color] = Player:new(coords.x, coords.y, color)
		self.activeColors[color] = true
	end

	for i=0, 20 do
		local c = randomColor()
		local x, y = math.random(1, gridWidth), math.random(1, gridHeight)
		self.collideables[c]["b: " .. x .. ", " .. y] = Box:new(x, y, c)
	end


	for i=0, 20 do
		local c = randomColor()
		local x, y = math.random(1, gridWidth), math.random(1, gridHeight)
		self.collideables[c]["w: " .. x .. ", " .. y] = Wall:new(x, y, c)
	end
end


function Room:update(dt)
	for color, player in pairs(self.player) do
		player:update(dt)
	end
end

function Room:draw()
	for color, player in pairs(self.player) do
		player:draw()
	end
	for color, entityArray in pairs(self.collideables) do
		for _, entity in pairs(entityArray) do
			entity:draw()
		end
	end
end

function Room:movePlayer(key)

	local moveAxis
	local direction

	if key == "up" then
		moveAxis, direction = "y", -1
	elseif key == "down" then
		moveAxis, direction = "y", 1
	elseif key == "left" then
		moveAxis, direction = "x", -1
	elseif key == "right" then
		moveAxis, direction = "x", 1
	else
		error("wtf did u do")
	end

	for color, active in pairs(self.activeColors) do
		if active then
			local playerPos = self.player[color]:getGridPos()
			local entities = self:getAdjacentEntities(self.collideables[color], playerPos, moveAxis, direction)
			local canMove = self:tryPlayerMove(entities, playerPos, moveAxis, direction)
			if canMove then
				self:checkAndPull(self.collideables[color], playerPos, moveAxis, direction)
				self.player[color]:move(moveAxis, direction)
				self:tick()
			end
		end
	end
end

function Room:switchPlayer(colorToActivate)
	for color, active in pairs(self.activeColors) do
		if color == colorToActivate then
			self:setActiveColor(color, true)
		else
			self:setActiveColor(color, false)
		end
	end
end

function Room:setActiveColor(color, bool)
	self.activeColors[color] = bool
end

function Room:getAdjacentEntities(entities, pos, axis, direction)
	local t = {}

	--first we gather all entities in direction of movement
	for _, entity in pairs(entities) do
		if axis == "x" then
			if entity:isAlignedWithPlayerMovement("y", pos.y) then
				if direction > 0 and entity:getGridPos()[axis] > pos[axis] then
					table.insert(t, entity)
				elseif direction < 0 and entity:getGridPos()[axis] < pos[axis] then
					table.insert(t, entity)
				end
			end
		elseif axis == "y" then
			if entity:isAlignedWithPlayerMovement("x", pos.x) then
				if direction > 0 and entity:getGridPos()[axis] > pos[axis] then
					table.insert(t, entity)
				elseif direction < 0 and entity:getGridPos()[axis] < pos[axis] then
					table.insert(t, entity)
				end
			end
		end
	end

	--then we put them in order
	table.sort(t, function(a, b)
		if direction > 0 then
			return a:getGridPos()[axis] < b:getGridPos()[axis]
		else 
			return a:getGridPos()[axis] > b:getGridPos()[axis]			
		end
	end)

	return t
end

function Room:checkAndPull(entities, pos, axis, direction)

	for _, entity in pairs(entities) do
		local entPos = entity:getGridPos()
		print(pos.x, pos.y, entPos.x, entPos.y)
		if axis == "x" and entPos.x == pos.x - direction and entPos.y == pos.y then
			if entity:canMove() then
				entity:move(axis, direction)
				return
			end
		elseif axis == "y" and entPos.x == pos.x and entPos.y == pos.y - direction then
			if entity:canMove() then
				entity:move(axis, direction)
				return
			end
		end
	end
end

function Room:tryPlayerMove(entities, pos, axis, direction)
	local counter = direction
	local entitiesToMove = {}

	for _, entity in ipairs(entities) do
		if entity:getGridPos()[axis] == pos[axis] + counter then
			if entity:canMove() then
				table.insert(entitiesToMove, entity)
			else
				return false
			end 
		else
			break
		end
		counter = counter + direction
	end

	for  _, entity in ipairs(entitiesToMove) do
		entity:move(axis, direction)
	end

	return true
end

function Room:tick()
	for color, entityArray in pairs(self.collideables) do
		for _, entity in pairs(entityArray) do
			entity:tick()
		end
	end
	self:nextRoomCheck()
end

function Room:nextRoomCheck()

end

function nextRoom()

end