PulseWait = class(function(o, f, c)
	o.fn = f
	o.count = c
	o.alive = true
end)
-- the base room type
Room = class(Object, function(o, x, y, world, ...)
	local arg = {...}
	if arg[1] == nil then
		options = {}
	else
		options = arg[1]
	end
	local noHealth = options.noHealth or false

	local size = 60* r_scale
	Object.init(o, x, y, size, size)
	o.drawType = "stretched"
	o.sprite = sprites['tiles']['room_basic.png']
	o.world = world
	o.shootRate = math.random()+0.5
	o.shootCounter = o.shootRate
	o.range = 150
	o.health = 12
	o.note = math.random()
	o.children = Group()
	o.typecount = 1
	o.healthSize = 6* r_scale
	if not noHealth then
		o.healthDisplay = HealthBar(x, y+size-o.healthSize, o.w, o.healthSize)
	end
end)
Room.cost = 100
local gravAccel = Vec2(0,0.6)
function Room:addChild(child)
	self.children:add(child)
end
function Room:addBox2d()
	if box2d then
		self.b2d = BludBox2dRect(box2d, self.pos.x+self.w/2, self.pos.y+self.h/2, self.w/2, self.h/2, 0, 0.4, 0.4, true)
		self.b2d:setData(self)
	end
end
function Room:handleCollision(other)
	-- the rooms just let the other half deal with the collision, they don't do anything
end
function Room:sync()
	if self.pulseWaits then
		for i,v in ipairs(self.pulseWaits.members) do
			if v.alive then
				v.count = v.count - 1
				if v.count <= 0 then
					v.fn()
					v.alive = false
				end
			end
		end
	end
end
function Room:pulse()
	self:playSound(self.note, self.typecount)
	self.world.pulsers:addPulse(self)
	self.waitingToFinish = false
	if self.children:countLiving() > 0 then
		self.waitingToFinish = true
		if not self.pulseWaits then self.pulseWaits = Group() end
		self.pulseWaits:addRecycle(PulseWait(function()
			for i,v in ipairs(self.children.members) do
				if v.alive then
					v:pulse()
				end
			end
			self.waitingToFinish = false
		end, 2))
	end
end

function Room:update()
	if self.b2d and self.killb2d then self.b2d:destroy(); self.killb2d = false end
	self.shootCounter = self.shootCounter - bludG.elapsed
end
function Room:draw()
	if self.exists then
		-- local shake = nil
		-- if self.shake and self.shake > 0 then
		-- 	self.shake = self.shake - bludG.elapsed
		-- 	shake = Vec2(math.sin(bludG.last_t*100)*6*self.shake, math.cos(bludG.last_t*100)*6*self.shake)
		-- 	self.pos:add(shake)
		-- 	self:setPosition(self.pos.x, self.pos.y)
		-- end
		Object.draw(self)
		-- if shake then self.pos:sub(shake) end
		-- self:setPosition(self.pos.x, self.pos.y)
		-- draw the remaining amount of health in the upper left
		if self.alive and self.healthDisplay then
			self.healthDisplay:draw()
		end
	end
end
function Room:setPosition(x, y)
	Object.setPosition(self, x, y)
	if self.svg then self.svg:setPosition(x, y) end
end
function Room:setCenter(x, y)
	self:setPosition(x-self.w/2, y-self.h/2)
end
function Room:setHealth(health, maxHealth)
	if self.healthDisplay then
		self.health = health
		if maxHealth then
			self.maxHealth = maxHealth
			self.healthDisplay.max = maxHealth
		end
		self.healthDisplay:setValue(self.health)
	end
end
function Room:setScale(s)
	if self.svg then
		self.svg:scale(s, s)
	end
	self.w = self.w*s
	self.h = self.h*s
end
function Room:setColor(r, g, b, a)
	Object.setColor(self, r, g, b, a)
	if self.svg then
		self.svg:setColor(self.tint.r, self.tint.g, self.tint.b, self.tint.a)
	end
end
function Room:setScrollFactor(x, y)
	if self.svg then
		self.svg:setScrollFactor(x, y)
	end
end
function Room:hit(amt)
	amt = amt or 1
	self.shake = 1
	self:setHealth(self.health - amt)
	if self.health <= 0 then
		self:kill()
	end
end
function Room:kill(deathWait)
	local deathWait = deathWait or 0
	self.killb2d = true
	self.shootCounter = 0
	pd:startList("fromOF")
	pd:addSymbol("explosion")
	pd:addFloat(self.note)
	pd:finish("fromOF")
	bludG.camera:shake()
	player:addDestroy()
	for i,v in ipairs(self.children.members) do
		v:kill(deathWait+0.2)
	end
	self.alive = false
	self.world.refreshLimits = true
	-- if self.svg then self.svg:explode() end
	-- outer tween is just a placeholder to slow down all the children from exploding at once
	Tweener:addTween(self.tint, {a=255}, {time=deathWait, onComplete=function()
		if self.svg then self.svg:explode() end
	-- 	if self.colorTween then Tweener:removeTween(self.colorTween) end
	-- 	-- if not self.originalColor then self.originalColor = {r=self.tint.r, g=self.tint.g, b=self.tint.b, a=self.tint.a} end
	-- 	-- self:setColor(self.originalColor.r, self.originalColor.g, self.originalColor.b)
	-- 	-- self.colorTween = Tweener:addTween(self.tint, {a=0}, {time=2})
		Tweener:addTween(self.pos, {y=self.pos.y+200}, {time=1.3, func='inExpo', onComplete=function()
			self.exists = false
		end})
	end})
	if self.greeble then
		self.greeble:kill()
	end
end
function Room:playSound(note, typecount)
	-- ok, apparently the old way of doing this was too slow.
	-- so I am going to try packing these up and just sending across the first x amount.
	self.world:addRoomSound(typecount, note)
	-- 	pd:startList("fromOF")
	-- pd:addSymbol("monoMode")
	-- pd:addFloat(typecount)
	-- pd:addFloat(note)
	-- pd:finish("fromOF")

end
-- mainState = WrapperState(Group());
-- ps = PlayState()
-- mainState:changeState(ps)
