-- $LastChangedDate: 2009-04-29 11:08:15 -0500 (Wed, 29 Apr 2009) $
-- Scene class.
-- See module.txt for documentation and pitfalls.

--------------
-- NodeSort --
--------------

-- This is a Lua table, created on the Lua side, that the C++ binding understands.
-- Used with sim.SceneGraph:AttachObject( object, nodeSort )
--
-- Usage:
-- Pass a table to the ctor.
-- Example:
-- nodeSort = NodeSort:new( { shader="metallic", transparent=true } )
-- Arg table corresponds to C++ NodeSort:
-- { shader="name", no_shader=true, transparent=true, no_depth_test=true }

NodeSort = { }

function NodeSort:new( attribTable )
	-- The arg table IS the object (idiom).
	return attribTable
end

-----------
-- Scene --
-----------

Scene = { }

-- Map location names to scene scripts.
Scene.scriptLocationMap = {
	["GoldenGate"] = "scene_GoldenGate.lua",
}

-- (private)
function Scene:CopyObject( t )
	local t2      = {}
	t2.pos        = t.pos
	t2.file       = t.file
	t2.collidable = t.collidable
	t2.scale      = t.scale
	t2.Rotate     = t.Rotate
	return t2
end

-- Load Object as defined by table in Scene.objects.
function Scene:LoadObject( t )
	-- Default.
	if ( not t.scale ) then
		t.scale = 1.0
	end

	-- In case of reloading.
	sim.ZombifyObject( t, "object" )

	t.object = sim.Object:new( t.pos, t.file, t.scale, t.load )
	t.Rotate( t.object )
	t.object:SetCollidable( t.collidable )
	if ( t.nodeSort ) then
		sim.SceneGraph:AttachObjectSpecial( t.object, t.nodeSort )
	else
		sim.SceneGraph:AttachObject( t.object )
	end
end

-- (private)
function Scene:LoadObjects()
	for k,t in pairs(self.objects) do
		self:LoadObject( t )
	end
end

-- Load scene according to location name.
function Scene:Load( locationName )
	self.locationName = locationName  -- remember for Reload()
	local script = self.scriptLocationMap[locationName]
	if ( script ) then
		dofile( sim.Program:GetScriptDir() .. "/" .. script )
		self:LoadObjects()

		-- Optional hook function.
		if ( self.PostLoad ) then
			self:PostLoad()
		end

		return true
	else
		return false
	end

end

-- The ability to dynamically reload a scene is useful
-- for placing objects while editing a scene script.
function Scene:Reload()
	Log( "Reloading scene." )

	-- If this is a reload, detach old Objects.
	if ( self.objects ) then
		for k,t in pairs(self.objects) do
			sim.SceneGraph:DetachObject( t.object )
		end
	end

	-- Reload scene using saved location name.
	self:Load( self.locationName )
end
