-- ----------------------------------------------------------------------------
layoutBasementFusebox.mExits =
{
}
layoutBasementFusebox.mPOIs = 
{
}
layoutBasementFusebox.mHOs = 
{
}
layoutBasementFusebox.mIOs =
{
	[objectBasementFuse1] = 
	{
		mirrors = {objectBasementFuse2, objectBasementFuse3, objectBasementFuse4}
	},
	[objectBasementFuseboxHitarea] =
	{
		cursor = kCursorDefault,
	},
	[objectIoFuseManual] = 
	{
	},
	[objectIoFuseManualWall] = 
	{
	}
}
layoutBasementFusebox.mLights 				= {objectBasementLight1, objectBasementLight2, objectBasementLight3, objectBasementLight4}
layoutBasementFusebox.mSlots  				= {objectBasementFuse1, objectBasementFuse2, objectBasementFuse3, objectBasementFuse4}
layoutBasementFusebox.mFuses				= {objectPorchFuse1, objectPorchFuse2, objectShedFuse3, objectShedFuse4, objectBasementFuse5, objectBasementFuse6}
layoutBasementFusebox.mObjectsLit			= {objectBasementBackgroundLit, objectBasementDarkcornerLit, objectBasementFuseboxLit, objectBasementSecretdoorLit, objectBasementDoorLit, objectBasementWrenchLit, objectBasementFuseboxBackgroundLit, objectBasementSecretdoorPeepLit, objectPoiBasementPaper, objectBasementPaper}
layoutBasementFusebox.mObjectsUnlit			= {objectBasementBackgroundUnlit, objectBasementDarkcornerUnlit, objectBasementFuseboxUnlit, objectBasementSecretdoorUnlit, objectBasementDoorUnlit, objectBasementWrenchUnlit, objectBasementFuseboxBackground, objectBasementFuseboxHitarea, objectBasementSecretdoorPeep}

layoutBasementFusebox.mSolution				= {}
layoutBasementFusebox.mLinks				= {}
layoutBasementFusebox.mObjectsUnlitAlpha	= {}

layoutBasementFusebox.kFrameLightBlack		= 0
layoutBasementFusebox.kFrameLightOrange		= 1
layoutBasementFusebox.kFrameLightGreen		= 2

layoutBasementFusebox.kFrameOrange  		= 0
layoutBasementFusebox.kFrameMixed		    = 1
layoutBasementFusebox.kFrameGreen		    = 2

layoutBasementFusebox.mPuzzle = true
layoutBasementFusebox.puzzleActive = false
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onConstruct()

	Layout.onConstruct(self)

	objectBasementFuseboxBackgroundLit:ss(kInactive)
	objectBasementFuseboxHitarea:ss(kActive)
	
	objectIoFuseManualWall:ss(kActive)
	objectIoFuseManual:ss(kInactive)
	
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onShow()

	Layout.onShow(self)
	
	if (not objectIoFuseManualWall:isDone()) then
		objectIoFuseManualWall:ss(kActive)
		objectIoFuseManual:ss(kInactive)
	end
	
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onClickIO(object, x, y)

	if (object == objectIoFuseManualWall) then	
		objectIoFuseManualWall:ss(kInactive)
		objectIoFuseManual:ss(kActive)
		playAudioTrack("MANUAL_PAGE")
		return true
	
	elseif (object == objectIoFuseManual) then
		objectIoFuseManualWall:ss(kActive)
		objectIoFuseManual:ss(kInactive)
		playAudioTrack("MANUAL_PAGE")
		return true
		
	end

	return Layout.onClickIO(self, object, x, y)

end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onInitialize()

	Layout.onInitialize(self)
	
	-- generate solution
	self:generateSolution()
	
	-- set slots inactive
	for i, slot in ipairs(self.mSlots) do
		slot:ss(kInactive)
	end
	
	for i, light in ipairs(self.mLights) do
		light:ss(kActive)
	end
	
	-- hide fuse shine
	objectBasementFuseboxShine:ss(kInactive)
	
	-- save the alpha of our unlit objects
	for i, unlit in  ipairs(self.mObjectsUnlit) do
		self.mObjectsUnlitAlpha[unlit] = unlit:alpha()
	end		
	
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onQuickPlay()

	Layout.onQuickPlay(self)

	for i, fuse in ipairs(self.mFuses) do
		fuse:ss(kFound)
	end

end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onSolve()

	Layout.onSolve(self)
		    
    for i, slot in ipairs(self.mSlots) do
        self:setFuse(slot, self.mSolution[i])
        slot:ss(kIdle)
    end
    
	self:updateLights()
    
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onSolveStart()

	Layout.onSolveStart(self)
	
	for i, obj in ipairs(self.mObjectsLit) do
		obj:ss(kIdle)
	end
	
	objectBasementFuseboxShine:ss(kIdle)
	objectBasementFuseboxShine:setAlpha(0)
	-- stop sparkling in the basement
	objectBasementFuseboxSpark01:ss(kDone)
	objectBasementFuseboxSpark02:ss(kDone)	

    self:animSolved()

end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onSolveFinish()

	Layout.onSolveFinish(self)
	
    for i, unlit in ipairs(self.mObjectsUnlit) do
    	-- we can set these to kDone, 'cause they're not used anymore?
    	-- saving rendering power and memory
    	unlit:ss(kDone)
        unlit:setAlpha(self.mObjectsUnlitAlpha[unlit])
    end	
    
    objectBasementFuseboxShine:setAlpha(1)
    
    for i, light in ipairs(self.mLights) do
        light:setAlpha(1)
    end
    
    for i, fuse in ipairs(self.mFuses) do
        fuse:ss(kDone)
    end	
    
    for i, fuse in ipairs(self.mSlots) do
    	fuse:ss(kIdle)
    end
    
	objectIoFuseManualWall:ss(kDone)
	objectIoFuseManual:ss(kDone)
    
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onMouseDown(x, y)

	local result = Layout.onMouseDown(self, x, y)

	if (self.puzzleActive == true or self:isQuickPlay()) then
		if (self:isPuzzling()) then
			if (gSelection ~= nil and self:isFuse(gSelection)) then
		    	local fuse = gSelection
	    		local slot = self:getSlot(x, y)
			
			    if (slot ~= nil) then
	    			self:placeFuse(slot, fuse)
	    			result = true
			    end
		    else
	    		local slot = self:getSlot(x, y)
			
			    if (slot ~= nil) then
	    			if (self:hasFuse(slot)) then
					    self:selectFuse(slot)
				    end
				    result = true
			    end
		    end
		
		    self:updateLights()
		
		    if (self:getNumGreen() == #self.mSlots) then
		    	self:solve()
		    end
		    return result
	    end
	end
	
	return result

end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onClickObject(object, x, y)

	if (self.puzzleActive == false and object ~= objectIoFuseManualWall and object ~= objectIoFuseManual) then
		think("MESSAGE_ALL_FUSES_FIRST")
	end

	return Layout.onClickObject(self, object, x, y)
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:hasFuse(slot)
	return (self.mLinks[slot] ~= nil)
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:getFuse(slot)
	assert(self:hasFuse(slot))

	return self.mLinks[slot]
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:setFuse(slot, fuse)
	
	self.mLinks[slot] = fuse
	
	if (fuse == nil) then
		slot:ss(kInactive)
	else
		slot:ss(kActive)
				
		local frameIdx = self:getSlotFrameIdx(fuse)
				
		if (frameIdx >= 0) then
			slot:setFrame(frameIdx)
		end	
				
		fuse:ss(kUsed)	
	end
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:selectFuse(slot)
	assert(self:hasFuse(slot))
	
	-- we already have a fuse in that slot
	local fuseSwitch = self:getFuse(slot)
		
	self:setFuse(slot, nil)
		
	fuseSwitch:ss(kFound)
	fuseSwitch:ss(kSelected)
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:placeFuse(slot, fuse)
	
	if (self:hasFuse(slot)) then
		self:selectFuse(slot)
	end
	
	self:setFuse(slot, fuse)
	playAudioTrack("ELECTRIC_SHOCK")
	animFusePlaced(slot)
	
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:generateSolution()

	-- clear solution
	self.mSolution = {}

	-- create pool
	local fusePool = {}
	
	for i, fuse in ipairs(self.mFuses) do
		fusePool[i] = fuse
	end
	
	for i=1,#self.mSlots do
		-- get index from pool
		local idx = math.random(#fusePool)
		
		-- set fuse solution
		self.mSolution[i] = fusePool[idx]
		
		-- remove used fuse
		table.remove(fusePool, idx)
	end
	
	-- print solution
--	print("generated fusebox solution:")
--	for i, fuse in ipairs(self.mSolution) do
--		print(fuse:name())
--	end

end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:getNumGreen()
	local num = 0
	
	for i, slot in ipairs(self.mSlots) do
		if (self:hasFuse(slot)) then
			if (self:getFuse(slot) == self.mSolution[i]) then
				num = num + 1
			end
		end
	end
	
	return num
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:getNumOrange()
	local num = 0
	
	for i, slot in ipairs(self.mSlots) do
	    if (self:hasFuse(slot)) then
		    for j, solution in ipairs(self.mSolution) do
			    if (self:getFuse(slot) == solution) then
    				num = num + 1
			    end
		    end
		end
	end
	
	return num
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:updateLights()
	
	local showLights = true

	for i, slot in ipairs(self.mSlots) do
		if (not self:hasFuse(slot)) then
			showLights = false
		end
	end
	
	if (not showLights) then
		-- animate lights off
		objectBasementFuseboxLight:ss(kInactive)
		
		for i, light in ipairs(self.mLights) do
			if (light:alpha() > 0) then
				light:animate("animLightsOut",
					{ alpha=0,		duration=300	}
				)
			end
		end		
	else
		-- animate lights on
		local numGreen  = self:getNumGreen()
		local numOrange = self:getNumOrange()
		
		objectBasementFuseboxLight:ss(kIdle)
		
		if (numGreen == #self.mSlots) then
		    objectBasementFuseboxLight:setFrame(self.kFrameGreen)
		elseif (numGreen > 0) then
			objectBasementFuseboxLight:setFrame(self.kFrameMixed)
		else
		    objectBasementFuseboxLight:setFrame(self.kFrameOrange)
		end
		
		for i, light in ipairs(self.mLights) do
			if (i <= numGreen) then
				light:setFrame(self.kFrameLightGreen)
			elseif (i <= numOrange) then
				light:setFrame(self.kFrameLightOrange)
			else
				light:setFrame(self.kFrameLightBlack)
			end			
			
			if (light:alpha() < 1) then
				light:animate("animLightsIn",
					{ alpha=1,		duration=300	}
				)
			end
		end
		
		-- set frame basement
		
	end
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:isFuse(object)

    local result = false
    
	for i, fuse in ipairs(self.mFuses) do
		if (fuse == object) then
			result = true
		end
	end
	
	return result
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:getSlotFrameIdx(fuse)

	local idx = -1

	for i, fuseCompare in ipairs(self.mFuses) do
		if (fuse == fuseCompare) then
			idx = i - 1
		end
	end
	
	assert(idx >= 0)
	
	return idx
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:getSlot(x, y)

	for i, slot in ipairs(self.mSlots) do
		if (slot:isInsideStrict(x, y)) then
			return slot			
		end
	end
	
	return nil
end

-- ----------------------------------------------------------------------------
function animFusePlaced(slot)
	slot:newChildParticle( { x=0, y=0, 			 	library="PARTICLE_BASEMENT_FUSEBOX_SPARKLE", section="particles", play=true, removeWhenFinished=true } )
	slot:newChildParticle( { x=0, y=slot:height(), 	library="PARTICLE_BASEMENT_FUSEBOX_SPARKLE", section="particles", play=true, removeWhenFinished=true } )
end

-- ----------------------------------------------------------------------------
function layoutBasementFusebox:animSolved()
	
	-- anim lit objects on and off
	self:animate(
        { delay=800                                           },
        { call=layoutBasementFusebox.onAnimObjectsLitOn       },
        { delay=200                                           },
        { call=layoutBasementFusebox.onAnimObjectsLitOff      },
        { delay=800                                           },
        { call=layoutBasementFusebox.onAnimObjectsLitOn       },
        { delay=200                                           },
        { call=layoutBasementFusebox.onAnimObjectsLitOff      },
        { delay=400                                           },
        { call=layoutBasementFusebox.onAnimObjectsLitOn       }
    )
    
    local delay		= 0
	
	for i, light in ipairs(self.mLights) do
		light:animate(
		    { delay=delay           },
			{ alpha=0, duration=200 } 
		)
		delay = delay + 200
	end
	
	-- set lights anim order
	local animOrder = {self.mLights[1], self.mLights[2], self.mLights[4], self.mLights[3]}
		
	-- circle animation, 5 circles that speed up every lap
	for i=1,3 do
		local duration = 150 / i
		
		for j, light in ipairs(animOrder) do
			light:animate(
				{ delay=delay						},
				{ alpha=1,		duration=duration	},
				{ alpha=0,		duration=duration	}
			)
			
			delay = delay + duration
		end
	end
	
	for i, light in ipairs(self.mLights) do
		light:animate(
			{ delay=delay			},
			{ alpha=1, duration=200 } 
		)
		delay=delay+200
	end
	
	delay=delay+400
	
	self:animate("CloseFusebox_blocking",
	    { delay=delay                   },
	    { command="playTrack track=SUPERSIZED_SCAREMOMENT", target=self },
		{ call=function() play(movieSettings[kMovieBasement]) end },
		{ call=layoutBasementFusebox.hide },		
		{ call=layoutBasementFusebox.solveFinish }
	)
	
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:animObjectsLit(lightsOn)

	local alpha = 0
	
	for i, unlit in ipairs(self.mObjectsUnlit) do
		alpha = self.mObjectsUnlitAlpha[unlit]
			
		if (lightsOn) then
			alpha = 0
		end
			
		unlit:animate(
			{ alpha=alpha,		duration=100	}
		)
	end
	
	alpha = 0
	
	if (lightsOn) then
		alpha = 1
	end
	
	objectBasementFuseboxShine:animate(
		{ alpha=alpha, 			duration=100	}
	)
		
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onAnimObjectsLitOn()
	self:animObjectsLit(true)
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:onAnimObjectsLitOff()
	self:animObjectsLit(false)
end
-- ----------------------------------------------------------------------------
function layoutBasementFusebox:isSkippable()
	return self.puzzleActive
end
