 -- manages sending out enemies
local function shuffle(t)
    local rand = math.random 
    assert(t, "table.shuffle() expected a table, got nil")
    local iterations = #t
    local j
    
    for i = iterations, 2, -1 do
        j = rand(i)
        t[i], t[j] = t[j], t[i]
    end
end

WaveDisplay = class(Group, function(o, waveData, enemies, parent)
	Group.init(o)
	o.waveData = waveData
	o.enemies = enemies
	o.parent = parent
end)
function WaveDisplay:setup()

	-- eventually pull this positioning off of the svg info
	-- local lx, ly, lh, cw = 192, 70, 20, 170
	-- if ipad == '_ipad' then
	-- 	lx, ly, lh, cw = 253, 73, 20, 170
	-- end
	local wbg = self.parent.moneyController.waveBg
	-- lx, ly, lh, cw = lx*r_scale/2, ly*r_scale/2, lh*r_scale/2, cw*r_scale/2
	local lx, ly, lh, cw = wbg.pos.x, wbg.pos.y, wbg.h, wbg.w
	self.waveDisplayWidth = cw
	self:add(wbg)
	-- add the bellhop head that is going to slide along
	local bhs = sprites['tiles']['bellhop_1.png']
	
	local bmult = 1
	if r_scale == 4 then bmult = 2 end

	self.bellhop = self.parent.moneyController:add(Object(lx, ly, bhs:getWidth()*bmult, bhs:getHeight()*bmult))
	self.bellhop.sprite = bhs
	self.bellhop.bmult = bmult
	self.bellhop.scrollFactor = Vec2(0,0)
	self.bellhop.drawType = 'stretched'
	self.bellhop:setPosition(lx-self.bellhop.w/2, math.max(0, ly-self.bellhop.h))
	self.blockCam = Camera(lx, ly, lh, cw)
	
	self.blocks = self:add(Group())
	-- determine the wavescale based on the total time
	local totalTime = 0
	for i,v in ipairs(self.waveData) do
		totalTime = totalTime + v.time
	end
	self.totalTime = totalTime
	for i,v in ipairs(self.waveData) do
		-- build a slightly easier to parse spawnlist
		v.spawnlist = {}
		for j,enemy in ipairs(v.enemies) do
			if enemy.count > 0 then
				for i=1,enemy.count do
					table.insert(v.spawnlist, enemy.t)
					-- check to see if there is a preloader for this enemy type
					print()
					if _G[enemy.t .. "Preload"] then _G[enemy.t .. "Preload"]() end
				end
				-- shuffle the spawnlist
				shuffle(v.spawnlist)
			end
		end
		-- add a rect depending on the amount of time for this wave
		local block = self.blocks:add(Object(lx, ly, v.time/totalTime*cw, lh))
		block.sprite = sprites['tiles']['white.png']
		block.drawType = 'stretched'
		block.cameras = {self.blockCam}
		lx = block.pos.x+block.w
		if #v.spawnlist>0 then
			block:setColor(221,122,116)
		else
			-- block:setColor(205, 177, 207)
				block:setColor(255, 255, 255, 100)
		end
	end
	self.currentWave = 0
	self.started = false
end
function WaveDisplay:startWaves()
	self.running = true
	self.started = true
	self:setupNextWave(0)
	self.time = 0
end
function WaveDisplay:setOver()
	return self.started and self.running ~= true
end


function WaveDisplay:update()
	if self.running then
		self.time = self.time - bludG.elapsed
		self.nextWave = self.nextWave - bludG.elapsed
		if self.nextWave < 0 then
			if self.currentWave < #self.waveData then
				self:setupNextWave(-self.nextWave)
			else
				self.running = false
			end
		elseif #self.waveData[self.currentWave].spawnlist > 0 then
			self.nextSync = self.nextSync - bludG.elapsed
			while self.nextSync < 0 do
				-- pop the next enemy off the spawn list
				local nextSpawn = table.remove(self.waveData[self.currentWave].spawnlist, 1)
				pd:startList("fromOF")
				pd:addSymbol("enemyAdded")
				pd:addSymbol(nextSpawn) -- enemy type
				pd:finish("fromOF")
				nextSpawn = _G[nextSpawn]
				self.enemies:addRecycle(nextSpawn(0, bludG.camera.h/2, self.parent))
				self.nextSync = self.nextSync + self.syncRate
			end
		end
		for i,v in ipairs(self.blocks.members) do
			if v.pos.x < self.blockCam.scroll.x+self.blockCam.pos.x then
				local nx = self.blockCam.scroll.x+self.blockCam.pos.x
				v.w = v.w-(nx-v.pos.x)
				v.pos.x = nx
				if v.w <= 0 then
					self.blocks:remove(v)
				end
			end
		end
	end
	if self.time then
		if self.currentWave < #self.waveData then
			-- if the bellhop is not in the last wave, then take this code path
			self.bellhop.pos.x = (-1*self.time)/self.totalTime*self.waveDisplayWidth+self.blockCam.pos.x-self.bellhop.w/2
		else
			self.bellhop.sprite = sprites['tiles']['bellhop_' .. (math.floor(bludG.last_t*5)%2)+1 .. '.png']
			if not self.lastWaveEnemyCount then
				self.lastWaveEnemyCount = self.parent.enemies:countLiving() + #self.waveData[self.currentWave].spawnlist
				self.lastWaveXpos = (-1*self.time)/self.totalTime*self.waveDisplayWidth+self.blockCam.pos.x
				self.waveDisplayWidth = self.waveDisplayWidth-self.lastWaveXpos+self.blockCam.pos.x
			end
			local percent = (self.lastWaveEnemyCount - (self.parent.enemies:countLiving() + #self.waveData[self.currentWave].spawnlist))/self.lastWaveEnemyCount
			if self.bellhop.posTween then Tweener:removeTween(self.bellhop.posTween) end
			self.bellhop.posTween = Tweener:addTween(self.bellhop.pos, {x=self.waveDisplayWidth*percent+self.lastWaveXpos-self.bellhop.w/2}, {time=0.5})
		end
	end
end

function WaveDisplay:setupNextWave(remainder)
	self.currentWave = self.currentWave+1
	local cw = self.waveData[self.currentWave]
	if #cw.spawnlist > 0 then
		self.syncRate = cw.time/(#cw.spawnlist+1)
		self.nextSync = 0
	end
	self.nextWave = cw.time-remainder
end

function WaveDisplay:saveTo(data)
	data.waveData = self.waveData
	data.nextSync = self.nextSync
	data.currentWave = self.currentWave
	return data
end

function WaveDisplay:loadFrom(data)
	self.waveData = data.waveData
	self.nextSync = data.nextSync
	self.currentWave = data.currentWave
end