-- $LastChangedDate: 2008-12-24 10:42:02 -0500 (Wed, 24 Dec 2008) $
-- Mission in OSSIM.
-- mission.lua defines an equivalent of a Mission base class which this extends.
-- See module.txt for documentation and pitfalls.

-- Specialize mission class.
assert( Mission )  -- mission.lua defines base methods
Mission.BaseReset  = Mission.Reset
Mission.placeNames = {
	["UserDefined"]     = Vec3(  0.0,    0.0, 8000.0 ),
	["Nepal"]           = Vec3( 27.0,   82.0, 6000.0 ),
	["Himalayas"]       = Vec3( 33.2,   78.1, 9000.0 ),
	["Oregon"]          = Vec3( 43.4, -121.7, 1700.0 ),
	["Sahara"]          = Vec3( 22.1,   15.3, 8000.0 ),
	["San Francisco"]   = Vec3( 37.5, -122.4, 3000.0 ),
	["New York"]        = Vec3( 40.3,  -74.0, 6000.0 ),
	["Chicago"]         = Vec3( 41.5,  -87.3, 6000.0 ),
	["Grand Canyon"]    = Vec3( 36.1, -112.1, 7000.0 ),
	["Florida"]         = Vec3( 25.0,  -82.0, 8000.0 ),
	["Antarctica"]      = Vec3( -88,    5.0,  6000.0 ),
}
Mission.initialPositionName = "Nepal"
Mission.light = {
	pos      = Vec3( 2.0, 2.0, -2.0 ),
	ambient  = RGBA(0.50, 0.50, 0.50, 1.00),
	diffuse  = RGBA(0.50, 0.50, 0.50, 1.00),
	specular = RGBA(0.30, 0.30, 0.30, 1.00),
}

-- Set user-defined position.
function Mission:SetUserDefinedPosition( lat, lon, alt )
	if ( lat and lon and alt ) then
		self.initialPositionName = "UserDefined"
		local pos = Vec3( tonumber(lat),
						  tonumber(lon),
						  tonumber(alt) )
		self.placeNames["UserDefined"] = pos
	end
end

-- Reset/init mission.
function Mission:Reset()
	-- Call base Reset().
	self:BaseReset()

	-- Using the GUI, the user can select the location by name or by entering lat,lon,alt.
	-- Normally, (lat,lon,alt) will be empty strings.
	local cmdFields = CommandQueue:GetCmdFields()
	if ( cmdFields and (cmdFields[CommandQueue.COMMAND_FIELD] == "RESTART") ) then
		local locationName = cmdFields[CommandQueue.RESTART_FIELD_LOCATION]
		local locationLat  = cmdFields[CommandQueue.RESTART_FIELD_LAT]
		local locationLon  = cmdFields[CommandQueue.RESTART_FIELD_LON]
		local locationAlt  = cmdFields[CommandQueue.RESTART_FIELD_ALT]
		-- Change location (OSSIM).
		if ( locationLat ~= "" and locationLon ~= "" and locationAlt ~= "" ) then
			self:SetUserDefinedPosition( locationLat, locationLon, locationAlt )
			print( "Changing location to (" .. locationLat .. "," .. locationLon .. "," .. locationAlt .. ")." )
		else
			-- Set by name.
			self.initialPositionName = locationName
			print( "Changing location to " .. tostring(locationName) .. "." )
		end
	end

	-- Set initial position of player.
	local initialPosSphere = self.placeNames[self.initialPositionName]
	self.initialPos = sim.World.SphereVertex2WorldVertex( initialPosSphere )

	sim.BeginPlacement( PlayerActor.aircraft )  -- disable collision
	PlayerActor.aircraft:SetPosition( self.initialPos )
	sim.EndPlacement( PlayerActor.aircraft )  -- enable collision

	-- Reset player's aircraft (throttle, speed, etc).
	PlayerActor.aircraft:SetThrottle( 0.3 )
	sim.World:RotateTangential( PlayerActor.aircraft, initialPosSphere )  -- align with surface of planet
	local physics = PlayerActor.aircraft:GetPhysics()
	physics:SetSpeed( sim.Physics.KPH2Speed( 125.0 ) )
	-- SUBTLE: SetLandingGear() becomes a NOP if speed is zero.
	PlayerActor.aircraft:SetLandingGear( sim.LANDING_GEAR_UP )

	-- Reset views.
	ChaseView.chaseViewpoint = ChaseView.chaseViewpointPlayer
	if ( not self.ifDoneResetView ) then
		self.ifDoneResetView = true
		ChaseView.chaseViewpoint:Save()
		sim.SuperView:MakeSecondView()
	end
	sim.SuperView:SetViewMode( sim.SuperView.eViewMode_OTW_FRONT )

	-- Initialize sky and lights.
	sim.Sky:SetLightColor( self.light.ambient, self.light.diffuse, self.light.specular )
	sim.Sky:SetLightPosition( self.light.pos )
end

-- Initialization/start mission (done once).
function Mission:Start()
	-- Parse -llh (lat/lon/height) arg.
	local llhIdx = sim.GetArgvIdx( "-llh" )
	if ( llhIdx ) then
		self:SetUserDefinedPosition( sim.argvArray[llhIdx + 1], sim.argvArray[llhIdx + 2], sim.argvArray[llhIdx + 3] )
	end

	-- Initial reset.
	self:Reset()
end

-- Mission-specific timer-tick handler.
function Mission:Tick()
	-- Process commands from the simulator's "command queue".
	local cmd = sim.Program:DequeueCommand()
	if ( cmd ) then
		if ( self.placeNames[cmd] ) then
			self.initialPositionName = cmd
			self:Reset()
		end
	end
end

Timer:Register( Mission, defs.MISSION_TICK_FREQ )

-- Let startup.lua continue...
