WorldSelectState = class(Group, function(o, lastState)
	Group.init(o)
	o:setup(lastState)
end)
function WorldSelectState:setup(lastState)
	local o = self
	bludG.camera.scroll = Vec2(0,0)
	bludG.camera.scale = 1

	local groundRatio = 365/768
	local groundHeight = letterboxWidth*groundRatio+1

	o.sky = o:add(GradientObject(0,0,bludG.camera.w, bludG.camera.h-groundHeight, bludColor(69,219,196, 255), bludColor(255,172,46, 255)))
	o.sky.tintTop = {r=worlds[1].top_color[1], g=worlds[1].top_color[2], b=worlds[1].top_color[3], a=worlds[1].top_color[4]}
	o.sky.tintBottom = {r=worlds[1].bottom_color[1], g=worlds[1].bottom_color[2], b=worlds[1].bottom_color[3], a=worlds[1].bottom_color[4]}
	
	o.sky:setScrollFactor(Vec2(0,0))
	o.ground = o:add(GradientObject(0,bludG.camera.h-groundHeight,bludG.camera.w, groundHeight+1, bludColor(0,0,0, 255), bludColor(0,0,0, 255)))
	o.ground:setScrollFactor(Vec2(0,0))
	-- o:addBorder()

	local pbw = 114
	local pby = bludG.camera.h-groundHeight/2-pbw/2
	o.playButtonY = pby

	o.playButton = o:add(FancyButton(bludG.camera.w/2-pbw/2,pby,"Play"))
	o.playButton:setScrollFactor(Vec2(0,0))
	o.playButton.onPress = function()
		player.currentWorld = worlds[o.currentWorld+1]
		player.currentWorldCount = o.currentWorld
		mainState:changeState(LevelSelectState(o))
		pd:startList("fromOF")
		pd:addSymbol("worldSelect")
		pd:addFloat(player.currentWorldCount)
		pd:finish("fromOF")
	end
	o.playButton:setPosition(bludG.camera.w/2-o.playButton.svg:getMaxX()/2, o.ground.pos.y+o.ground.h/2-o.playButton.svg:getMaxY()/2)
	o.playButtonY = o.playButton.pos.y
	o:setupHotels(lastState)
	o.hotelW = sprites['tiles']['silhouette_' .. worlds[1].id .. '.png']:getWidth()
	o.currentWorld = player.currentWorldCount or 0
	o:placeButtons()
	WorldSelectState.addBackButton(o)
	o:scrollToWorld(true)
end
function WorldSelectState:setupHotels(lastState)
	self.hotels = Group()
	local scale = 0.8
	if r_scale == 4 then
		scale = scale * 2
	end
	for i,v in ipairs(worlds) do
		local hotelSpr = sprites['tiles']['silhouette_' .. v.id .. '.png']
		local leftPos = (i-1)*bludG.camera.w
		local hWidth = hotelSpr:getWidth()*scale*r_scale*0.5
		local hHeight = hotelSpr:getHeight()*scale*r_scale*0.5
		if lastState and lastState.hotel and v == player.currentWorld then
			hWidth = lastState.hotel.w
			hHeight = lastState.hotel.h
		end
		local hotel = self:add(Object(leftPos+bludG.camera.w/2-hWidth/2, self.ground.pos.y-hHeight, hWidth, hHeight))
		self.hotels:add(hotel)
		if lastState and lastState.hotel and v == player.currentWorld then
			-- tween to the proper position and target
			hWidth = hotelSpr:getWidth()*scale*r_scale*0.5
			hHeight = hotelSpr:getHeight()*scale*r_scale*0.5
			hotel.sizeTween = Tweener:addTween(hotel, {w=hWidth, h=hHeight})		
			hotel.posTween = Tweener:addTween(hotel.pos, {x=leftPos+bludG.camera.w/2-hWidth/2, y=self.ground.pos.y-hHeight})	
		end

		hotel.sprite = hotelSpr
		hotel.drawType = 'stretched'
		hotel:setLayer(1)
		local stringParts = Split(v.name, " ")

		for i,v in ipairs(stringParts) do
			if string.find(v, " ") then v = string.sub(v, -1) end
			local hotelText = self:add(StringObject(leftPos*2+bludG.camera.w/2-50*r_scale, self.ground.pos.y-hHeight, v, nil, 0.8))
			hotelText:setPosition((leftPos*2+bludG.camera.w/2-hotelText.w/2), -hotelText.h)
			hotelText.targetTween = Tweener:addTween(hotelText.pos, {y=self.ground.pos.y-hHeight-hotelText.h*(#stringParts-i+2)}, {func='outBounce'})
			-- hotelText:setPosition(-hotelText.w/20, -hotelText.h-10*r_scale)
			hotelText:setScrollFactor(Vec2(2, 1))
			hotelText:setColor(0,0,0)
		end
		-- check to see if the player has already unlocked this world
		if not player.unlocks['world_' .. v.id .. "_animation"] and not player.allLevelsUnlocked then
			local lock = self:add(Object(leftPos, 0, bludG.camera.w, bludG.camera.h))
			v.lock = lock
			lock.drawType = 'svg'
			lock.svg = SvgLoader(svg_root .. "interface/level_lock_large".. ipad ..".svg", true)
			lock:setColor(v.top_color[1], v.top_color[2], v.top_color[3])
		end
	end
	self.playButton.onPress = function()
		player.currentWorld = worlds[self.currentWorld+1]
		player.currentWorldCount = self.currentWorld
		self.hotel = self.hotels.members[self.currentWorld+1]
		mainState:changeState(LevelSelectState(self))
		pd:startList("fromOF")
		pd:addSymbol("worldSelect")
		pd:addFloat(player.currentWorldCount)
		pd:finish("fromOF")
	end
end
function WorldSelectState:addBorder(lastState)
	if lastState and lastState.border then
		self.border = self:add(lastState.border)
	else
		local borderPadding = Vec2(22, 26)
		borderPadding:mult(r_scale)
		self.border = self:add(RoundedRect(borderPadding.x, borderPadding.y, bludG.camera.w-borderPadding.x*2, bludG.camera.h-borderPadding.y*2))	
		self.border:setColor(255,172,46)
		self.border.scrollFactor = Vec2(0,0)
	end
end

function WorldSelectState:show(b)
	if b.postween then Tweener:removeTween(b.postween) end
	b.postween = Tweener:addTween(b.pos, {y=self.playButtonY})
end
function WorldSelectState:hide(b)
	if b.postween then Tweener:removeTween(b.postween) end
	b.postween = Tweener:addTween(b.pos, {y=bludG.camera.h+10*r_scale})
end

function WorldSelectState:placeButtons()
	-- get the distance between the border and the center of the screen (subtracting the hotel width)
	local leftSide = (bludG.camera.w/2-self.hotelW/2)/2
	local pb = self:add(FancyButton(leftSide, bludG.camera.h/2, "", "button_back"))
	pb.pos.x = pb.pos.x - pb.svg:getMaxX()/2
	pb.w = pb.svg:getMaxX()
	self.pb = pb
	local nb = self:add(FancyButton(bludG.camera.w-115, bludG.camera.h/2, "", "button_back"))
	nb.svg:translate(-nb.svg:getMaxX(), 0)
	nb.svg:scale(-1, 1)
	nb.svg:storeTransform()
	pb.onPress = function()
		self.currentWorld = math.max(0, self.currentWorld - 1)
		self:scrollToWorld()
		self:show(nb)
		pd:startList("fromOF")
		pd:addSymbol("worldView")
		pd:addFloat(self.currentWorld)
		pd:finish("fromOF")
		if self.currentWorld == 0 then
			self:hide(pb)
		end
		player.currentWorld = worlds[self.currentWorld+1]
		player.currentWorldCount = self.currentWorld
	end

	nb.onPress = function()
		self.currentWorld = math.min(#worlds-1, self.currentWorld + 1)
		self:scrollToWorld()
		self:show(pb)
		pd:startList("fromOF")
		pd:addSymbol("worldView")
		pd:addFloat(self.currentWorld)
		pd:finish("fromOF")
		if self.currentWorld == #worlds-1 then
			self:hide(nb)
		end
		player.currentWorld = worlds[self.currentWorld+1]
		player.currentWorldCount = self.currentWorld
	end
	self.nb = nb
	-- properly center the play button
	self.playButton:setPosition(bludG.camera.w/2-self.playButton.svg:getMaxX()/2, self.playButtonY)
	pb:setPosition(bludG.camera.w/5-pb.w/2, bludG.camera.h)
	nb:setPosition(bludG.camera.w/5*4-pb.w/2, bludG.camera.h)
	if self.currentWorld ~= 0 then
		self:show(pb)
	end
	if self.currentWorld < #worlds-1 then
		self:show(nb)
	end
end
function WorldSelectState:addBackButton(lastState)
	local cworld = player.currentWorld
	if lastState and lastState.backButton then
		self.backButton = self:add(lastState.backButton)
	else
		-- add the back button
		self.backButton = self:add(Object(0,0,bludG.camera.w, bludG.camera.h))
		self.backButton.svg = nil
		self.backButton.svg = SvgLoader(svg_root .. "interface/button_back.svg", true)
		self.backButton.drawType = 'svg'
		self.backButton.svg:setScrollFactor(0,0)
		if self.backButton.svg.id then
			-- should move this into the svg loader
			for key, rbd in pairs(self.backButton.svg.id) do
				self.backButton.button = CameraButton(rbd.minX, rbd.minY, rbd.maxX-rbd.minX, rbd.maxY-rbd.minY)
				self.backButton.button.scrollFactor = Vec2(0,0)
				self.backButton.button:setColor(0,0,0,0)
			end
		end
		self.backButton:setColor(cworld.bottom_color[1], cworld.bottom_color[2], cworld.bottom_color[3])
	end
	self:add(self.backButton.button)
	self.backButton.button.onPress = function()
		if self["buttonback_callback"] then self["buttonback_callback"](self) end
	end
end
function WorldSelectState:update()
	self.nb.tint = self.playButton.tint
	self.pb.tint = self.playButton.tint
	Group.update(self)
end
function WorldSelectState:draw()
	self.nb.tint = self.playButton.tint
	self.pb.tint = self.playButton.tint
	Group.draw(self)
end
function WorldSelectState:scrollToWorld(jump)
	if self.worldScroll then Tweener:removeTween(self.worldScroll) end
	if self.topTween then Tweener:removeTween(self.topTween) end
	if self.bottomTween then Tweener:removeTween(self.bottomTween) end
	if self.playbTween then Tweener:removeTween(self.playbTween) end
	if self.backButtonTween then Tweener:removeTween(self.backButtonTween) end
	local cworld = worlds[self.currentWorld+1]
	local time = nil
	if jump then
		time = 0
	end
	self.worldScroll = Tweener:addTween(bludG.camera.scroll, {x = self.currentWorld*bludG.camera.w}, {time=time})
	self.topTween = Tweener:addTween(self.sky.tintTop, {r=cworld.top_color[1], g=cworld.top_color[2], b=cworld.top_color[3], a=cworld.top_color[4]}, {func='easeNone', time=time})
	self.bottomTween = Tweener:addTween(self.sky.tintBottom, {r=cworld.bottom_color[1], g=cworld.bottom_color[2], b=cworld.bottom_color[3], a=cworld.bottom_color[4]}, {func="easeNone", time=time})
	self.playbTween = Tweener:addTween(self.playButton.tint, {r=cworld.bottom_color[1], g=cworld.bottom_color[2], b=cworld.bottom_color[3], a=cworld.bottom_color[4]}, {func="easeNone", time=time})
	self.backButtonTween = Tweener:addTween(self.backButton.tint, {r=cworld.bottom_color[1], g=cworld.bottom_color[2], b=cworld.bottom_color[3], a=cworld.bottom_color[4]}, {func="easeNone", time=time})
	-- show and hide the play button depending on level unlock state
	if not player.unlocks['world_' .. cworld.id .. "_animation"] and not player.allLevelsUnlocked then
		if not player.unlocks['world_' .. cworld.id] then
			self:hide(self.playButton)
		else
			if cworld.lock then
				-- tween then explode, then tween then fade
				-- calc the place to put some sparks
				minX, minY, maxX, maxY = cworld.lock.svg:getMinX(), cworld.lock.svg:getMinY(), cworld.lock.svg:getMaxX(), cworld.lock.svg:getMaxY()
				minX, maxX = minX+cworld.lock.pos.x, maxX+cworld.lock.pos.x
				local p = mainState.particles:addRecycle(ParticleHandler(0,0, "particle_data_bullet_explode_".. cworld.id ..".lua", sprites['tiles']['circle.png'], {lifetime=.3, cooldown=2}))
				Tweener:addTween(cworld.lock.tint, {}, {onComplete=function()
					for i=1,4 do
						p.pl.particles:setPosition(math.random(minX, maxX), math.random(minY, maxY))
						p.pl.particles:add(math.random(15, 25))			
					end
					Tweener:addTween(cworld.lock.tint, {r=cworld.lock.tint.r*0.9, g=cworld.lock.tint.g*0.9, b=cworld.lock.tint.b*0.9}, {time=0.5, onComplete=function()
						cworld.lock.svg:explode()
						Tweener:addTween(cworld.lock.tint, {a=230}, {onComplete=function()
							Tweener:addTween(cworld.lock.tint, {a=0})
						end})
						pd:startList("fromOF")
						pd:addSymbol("explosion")
						pd:addFloat(1)
						pd:finish("fromOF")
					end})
				end})
				self:show(self.playButton)
				player.unlocks['world_' .. cworld.id .. "_animation"] = true
			end
		end
	else
		self:show(self.playButton)
	end
end


function WorldSelectState:buttonback_callback()
	self.hotel = self.hotels.members[self.currentWorld+1]
	mainState:changeState(TitleScreenState(self))
end

-- mainState = WrapperState(Group());
-- mainState:changeState(TitleScreenState())
-- mainState.substate.playButton.onPress()
