:NAME game_hud

:BADGE c_object*	object
:BADGE c_object*	runtime_object
:BADGE c_object*	perfect_shield
:BADGE int16		type
:BADGE int16		touch_index
:BADGE boolean		time_badge
:BADGE boolean		enabled

:GLOBAL badge		badge0
:GLOBAL badge		badge1
:GLOBAL badge		badge2
:GLOBAL float32		badge_update_delay
:GLOBAL c_object*	player
:GLOBAL c_object*	health_bar
:GLOBAL c_object*	health_bar_frame
:GLOBAL c_object*	badge_shim
:GLOBAL c_object*	pause_scrim
:GLOBAL c_object*	pause_highlight
:GLOBAL c_object*	reset
:GLOBAL c_object*	gear
:GLOBAL c_object*	win_timer
:GLOBAL c_object*	goal_timer
:GLOBAL c_object*	skip
:GLOBAL c_object*	fast_forward_object
:GLOBAL c_object*	badge_name
:GLOBAL c_object*	badge_description
:GLOBAL c_object*	badge_arrow
:GLOBAL c_object_placement* blind_placement
:GLOBAL boolean		win_pending
:GLOBAL boolean		win_screen_display
:GLOBAL boolean		win_screen_on
:GLOBAL boolean		load_pending
:GLOBAL boolean		load_handled
:GLOBAL boolean		won
:GLOBAL boolean		lost
:GLOBAL boolean		loss_pending
:GLOBAL boolean		loss_disable
:GLOBAL boolean		paused
:GLOBAL boolean		reset_pending
:GLOBAL boolean		alerted
:GLOBAL boolean		fast_forwarding
:GLOBAL boolean		skipping
:GLOBAL boolean		options_are_up

:GLOBAL boolean		reward_display
:GLOBAL s_campaign_reward*	reward
:GLOBAL float32		reward_delay

:GLOBAL int32		loot_pending_count
:GLOBAL int32		loot_remaining_count
:GLOBAL int32		loot_count
:GLOBAL int32		required_loot_counter
:GLOBAL c_object*	loot_counter
:GLOBAL int32		key_count
:GLOBAL c_object*	key_counter
:GLOBAL int32		load_pending_type
:GLOBAL int32		load_pending_blind_index
:GLOBAL int16		badge_description_index
:GlOBAL float32		lost_time
:GLOBAL float32		won_time
:GLOBAL float32		won_time_counter
:GLOBAL float32		goal_time
:GLOBAL float32		load_pending_time
:GLOBAL float32		first_move_time
:GLOBAL c_sound*	sound_forward
:GLOBAL c_sound*	sound_back
:GLOBAL int32		music_id
:GLOBAL boolean		music_play
:GLOBAL boolean		music_sneaking_play
:GLOBAL uint16		player_sighted_count
:GLOBAL uint16		player_path_start_count





k_primary_player= e_value("e_player", "_player_primary")
k_escape_key= e_value("e_key", "_key_escape")

--k_loot_names= { "loot1", "loot2", "loot3" }
k_hud_loot_offset= 0.075
--k_look_max_count= 3

k_lost_reset_delay= 2

-- pause screen buttons
k_resume= "resume"
k_restart= "restart"
k_options= "options"
k_main_menu= "exit"
k_skip= "skip"

k_pause_plate= "pause"
k_win2_plate="win2"
k_reward_plate= "player_reward"
k_reward_plate2= "player_reward2"

k_win_timer_increments= 0.6

k_load_pending_main_menu= 0
k_load_pending_next_level= 1
k_load_pending_reset= 2
k_load_pending_delay= 3

k_load_pending_time= 3	-- was 1.2
k_blind_time= 2
k_load_pending_blind_count= 21
k_load_pending_blind_animation_duration= 0.6
k_load_pending_blind_spacing= 0.2
k_load_pending_blind_delay= (k_blind_time-k_load_pending_blind_animation_duration)/(k_load_pending_blind_count-1)
k_blind_rotation= -30*math.pi/180
k_blind_offset= {}
k_blind_offset.x= k_load_pending_blind_spacing*math.cos(k_blind_rotation)
k_blind_offset.y= k_load_pending_blind_spacing*math.sin(k_blind_rotation)

k_skip_message_time= 2.5

k_game_time_mode= e_value("e_time_mode", "_time_mode_game")
k_ui_time_mode= e_value("e_time_mode", "_time_mode_ui")

k_fast_forward_scale= 2

k_badge_scale_runtime= 0.75

-- badges

k_badge_placement_names= {"badge0", "badge1", "badge2"}
k_runtime_badge_placement_names= {"runtime_badge0", "runtime_badge1", "runtime_badge2"}
k_badge_appearance_delay= 0.5
k_perfect_appearance_delay= 1.5
k_max_badge_count= 32
k_badge_status_update_delay= 0.25		-- check every 0.25 secs

g_badge_tag_to_type_map={}

k_outcome_won= e_value("e_level_outcome", "_level_outcome_won")
k_outcome_won_reset= e_value("e_level_outcome", "_level_outcome_won_reset")
k_outcome_failed= e_value("e_level_outcome", "_level_outcome_failed")
k_outcome_reset= e_value("e_level_outcome", "_level_outcome_reset")
k_outcome_skipped= e_value("e_level_outcome", "_level_outcome_skipped")
k_outcome_main_menu= e_value("e_level_outcome", "_level_outcome_main_menu")

k_analytics= analytics_get()

-- ------------------- initialization ------------------- 

function badge_initialize(badge)
	badge.object= nil
	badge.runtime_object= nil
	badge.perfect_shield= nil
	badge.type= -1
	badge.touch_index= -1
	badge.enabled= false
	badge.time_badge= false
end

function global_initialize(g)

	badge_initialize(g.badge0)
	badge_initialize(g.badge1)
	badge_initialize(g.badge2)
	g.badge_update_delay= 0

	g.player= nil
	g.health_bar= nil
	g.reset= nil
	g.gear= nil
	g.win_timer= nil
	g.goal_timer= nil
	g.skip= nil
	g.fast_forward_object= nil
	g.badge_name= nil
	g.badge_description= nil
	g.badge_arrow= nil

	g.pause_scrim= nil
	g.pause_highlight= nil
	g.badge_shim= nil
	g.win_pending= false
	g.win_screen_on= false
	g.win_screen_display= false
	g.won= false
	g.lost= false
	g.loss_pending= false
	g.loss_disable= false
	g.lost_time= 0
	g.won_time= 0
	g.won_time_counter= 0
	g.goal_time= 5
	g.reset_pending= false
	g.paused= false
	g.fast_forwarding= false
	g.options_are_up= false
	
	g.reward_display= false
	g.reward= nil
	g.reward_delay= 0
	
	g.alerted= false
	
	g.loot_pending_count= 0
	g.loot_remaining_count= 0
	g.loot_count= 0
	g.loot_counter= nil
	
	g.key_count= 0
	g.key_counter= nil

	g.required_loot_counter= 0

	g.badge_description_index= -1

	g.load_pending= false
	g.load_handled= false
	g.load_pending_time= 0
	g.load_pending_type= -1
	g.load_pending_blind_index= -1
	g.blind_placement= nil
	
	g.sound_forward= nil
	g.sound_back= nil
	g.music_id= -1
	g.music_play= true
	g.music_sneaking_play= false

	-- some gameplay stats
	g.player_sighted_count= 0
	g.player_path_start_count= 0

	g.first_move_time= -1.0
end


-- ------------------- utilitites ------------------- 


function place_plate(plate_name, animation_name)
	local plate= world_get().get_plate(plate_name)
	if (plate) then
		local plate_state= plate.plate_state_get()
		
		plate_state.delete_all()					-- get rid of anything there might still be there!
		world_state_get().place_plate(plate)
		
		if (animation_name) then
			local object= plate_state.objects
			while true do
				if (object) then
					object.tween_animation_play(animation_name)
					object= object.plate_object_next
				else
					break
				end
			end
		end
		
	else
		print("ERROR: could not find plate named "..plate_name)
	end
	
	return plate
end

-- call an animation on every object on the plate, or, if the animation doesn't exist, just delete it straight up
function end_plate2(plate_name, animation_name)
	local plate= world_get().get_plate(plate_name)
	if (plate) then
		local plate_state= plate.plate_state_get()
		local object= plate_state.objects
		while true do
			if (object) then
				if ((not animation_name) or (not object.tween_animation_play_direction(animation_name, false, false))) then
					object_delete(object)
				end
				object= object.plate_object_next
			else
				break
			end
		end
	else
		print("ERROR: could not find plate named "..plate_name)
	end
end


-- call an animation on every object on the plate, or, if the animation doesn't exist, just delete it straight up
function end_plate(plate_name, animation_name)
	local plate= world_get().get_plate(plate_name)
	if (plate) then
		local plate_state= plate.plate_state_get()
		local object= plate_state.objects
		while true do
			if (object) then
				if ((not animation_name) or (not object.tween_animation_play(animation_name))) then
					object_delete(object)
				end
				object= object.plate_object_next
			else
				break
			end
		end
	else
		print("ERROR: could not find plate named "..plate_name)
	end
end




-- ------------------- load pending ------------------- 

function place_loading_message(delay)
	local loading_obj= object_place("loading")
	local loading_tween= loading_obj.tween_get()
	if (loading_tween) then
		loading_tween.play_animation_after_delay("loading", delay)
	end
end

function load_pending_start(type)

	local ws= world_state_get()
	global.load_pending= true
	global.load_pending_time= world_state_get().master_time.time
	global.load_pending_type= type
	
	object_place("bloom")
	if (type ~= k_load_pending_delay) then
		place_loading_message(1.0)
	end
	
	music_fadeout()
	
end

function load_pending_update()

	local master_time= world_state_get().master_time.time
	local delta_t= master_time - global.load_pending_time
	
	if (delta_t > k_load_pending_time) then
	
		if (not global.load_handled) then
			-- okay we're ready to go
			if (global.load_pending_type == k_load_pending_main_menu) then
				go_to_main_menu()
			elseif (global.load_pending_type == k_load_pending_next_level) then
				local campaign= campaign_get()
				if (campaign and campaign.current_level_valid()) then
					campaign.load_next_level()
				else
					-- just reset
					world_state_get().reset()
				end
			elseif (global.load_pending_type == k_load_pending_reset) then
				world_state_get().reset()
			end
			
			if (not global.load_pending_type == k_load_pending_delay) then
				global.load_handled= true
			end
		end
	
	elseif (global.load_pending_blind_index < (k_load_pending_blind_count-1)) then
		local desired_index= math.floor(delta_t / k_load_pending_blind_delay)
		if (desired_index > global.load_pending_blind_index) then
		
			global.load_pending_blind_index= desired_index
			
			if (global.blind_placement) then
				
				local blind= world_state_get().place(global.blind_placement)
				if (blind) then
				
					local position= blind.world_position_get()
		
					-- offset to the correct place
					local x= desired_index*k_blind_offset.x + position.x
					local y= desired_index*k_blind_offset.y + position.y
					
					blind.position_set(x, y)
				end
				
			end
		end
	end
	
	if (global.won) then
		won_update()
	end
	
end


-- ------------------- PAUSED ------------------- 

function shim_animate(shim, intro)
	shim.tween_animation_play_direction("start", intro, false)
end


function pause_start()
	local ws= world_state_get()
	if (not global.paused) then
		local w= world_get()

		place_plate(k_pause_plate, "start")
		
		game_pause_pending_clear()

		ws.game_time_pause()
		global.paused= true
		if (global.pause_scrim) then
			shim_animate(global.pause_scrim, true)
		end
		if (global.pause_highlight) then
			shim_animate(global.pause_highlight, true)
		end
		
		if (global.sound_forward) then
			global.sound_forward.play(k_ui_time_mode)
		end
		
		if (global.fast_forwarding) then
			ws.game_updates_per_frame_set(1)
		end
	end
end

function pause_end()
	local ws= world_state_get()
	--if (ws.game_is_paused() and global.paused) then
	if (global.paused) then
		ws.game_time_play()
		global.paused= false
		
		--end_plate(k_pause_plate, "end")
		end_plate2(k_pause_plate, "start")		-- this play the "start" animation backwards

		if (global.pause_scrim) then
			shim_animate(global.pause_scrim, false)
		end
		if (global.pause_highlight) then
			shim_animate(global.pause_highlight, false)
		end
		
		if (global.sound_back) then
			global.sound_back.play(k_ui_time_mode)
		end
		
		if (global.fast_forwarding) then
			ws.game_updates_per_frame_set(k_fast_forward_scale)
		end
	
	end
end

function go_to_main_menu()
	local campaign= campaign_get()
	if (campaign) then
		campaign.main_menu_load()
	end	
end

function options_load()
	if (world_get().zone_load_from_file("ui/options/options.zone")) then
		global.options_are_up= true
	end
end

function options_update()
	if (not world_get().zone_is_loaded("options")) then
		global.options_are_up= false
	end
end



function pause_update()

	game_pause_pending_clear()
	
	if (global.options_are_up) then
		options_update()
	else
		-- strange, somehow we unpaused ourselves along the way	
		local ws= world_state_get()
		if (not ws.game_is_paused()) then
			ws.game_time_pause()
		end
		
		local handled= false
		local resume= false

		local touch_interface= touch_get()
		if (touch_interface and touch_interface.touch_started()) then
		
			local touch_index= touch_interface.touch_start_index()
			local touch= touch_interface.touch[touch_index]
			
			local object= touch.touch_handler_object
			if (object) then
					
				local placement= object.placement
				if (placement) then
				
					local name= placement.name
					
					if ((name == k_resume) or (name == "pause_scrim")) then
						resume= true
						handled= true
					elseif (name == k_restart) then
						load_pending_start(k_load_pending_reset)
						resume= true
						handled= true
						k_analytics.level_ended(k_outcome_reset)
						campaign_get().level_was_reset()
					elseif (name == k_options) then
						handled= true
						options_load()
					elseif (name == k_main_menu) then
						--go_to_main_menu()
						load_pending_start(k_load_pending_main_menu)
						resume= true
						handled= true
						k_analytics.level_ended(k_outcome_main_menu)
					elseif (name == k_skip) then
						local app_settings= app_settings_get()
						if (app_settings) then
							-- make sure this level is considered unlocked
							app_settings.unlock_next()
						end
						load_pending_start(k_load_pending_next_level)
						k_analytics.level_ended(k_outcome_skipped)
						resume= true
						handled= true
					end
				end

				if (handled) then
					--object.tween_animation_play("pressed")
					object.button_press()
				end			
			end
		end
		
		if (not handled) then
			local keyboard= keyboard_get()
			if (keyboard) then
				if (keyboard.pressed[k_escape_key]) then
					resume= true
				end
			end
		end
		
		if (resume) then
			pause_end()
		end
	end
	
end


-- ------------------ FAST FORWARD ------------------

function fast_forward_pressed()

	local ws= world_state_get()
	local button= nil
	local tween= nil

	if (global.fast_forward_object) then
		button= global.fast_forward_object.button_get()
		tween= global.fast_forward_object.tween_get()
	end
	
	if (global.fast_forwarding) then
		ws.game_updates_per_frame_set(1)
		global.fast_forwarding= false
		
		if (tween) then
			tween.stop_all()
		end
		if (button) then
			button.disable_color(false)
			button.press()
		end
	else
		ws.game_updates_per_frame_set(k_fast_forward_scale)
		global.fast_forwarding= true

		if (button) then
			button.disable_color(true)
			button.press()
		end
		if (tween) then
			tween.play_animation("cycle")
		end
	end
end

-- ------------------- WON ------------------- 

function time_to_string(time)
	local mins= math.modf(time/60)
	local seconds= time - (mins*60)
	
	seconds= math.modf(seconds)
	
	local text= ""..mins..":"

	if (seconds < 10) then
		text= text.."0"
	end
	text= text..seconds
	
	return text
end

function set_win_timer(object, time, prepend)

	local text= time_to_string(time)
	if (prepend) then
		text= prepend..text
	end
	
	local text_component= object.text_get()
	if (text_component) then
		text_component.text_set(text)
	end
	
end


function won_start()

	local ws= world_state_get()
	local app_settings= app_settings_get()
	local profile= player_profile_get()
	global.won= true
	global.won_time= ws.time.time - global.first_move_time
	
	--print("WON: "..global.won_time)

	if (global.player) then
		local player_config= global.player._config.player_control
		if (player_config and player_config.skip_win_screen) then
		--if (true) then
			load_pending_start(k_load_pending_next_level)
			global.win_screen_display= false
		else
			load_pending_start(k_load_pending_delay)
			global.win_screen_display= true
		end
	end
	
	-- place some initial stuff
	if (global.win_screen_display) then
		place_plate(k_win2_plate)
		local replay= object_place("replay")
		local next= object_place("next")
		play_animation_after_delay(next, "start", 1.75)
		play_animation_after_delay(replay, "start", 1.5)
		local replay_pos= replay.world_position_get()
		local next_pos= next.world_position_get()
		replay.position_set(-3, replay_pos.y)
		next.position_set(3, next_pos.y)
	end

	if (app_settings) then
		app_settings.unlock_next()
	end

	if (not ws.game_is_paused()) then
		ws.game_time_pause()
	end
	
	if (global.fast_forwarding) then
		fast_forward_pressed()
	end
	
	-- play the success stinger
	ws.sound_manager.play_sound_by_name("success", k_ui_time_mode)

	
	-- if no player is immediate, award the clean getaway badge
	local target_iterator= ws.targets.iterator_get()
	local clean= true
	while (true) do
		local target= target_iterator.next()
		if (target) then
			if (target.is_immediate() and target.is_targetable()) then
				local target_object= target.target_object
				local player_control= target_object._p.player_control
				if ((player_control==nil) or (player_control.causes_general_alert)) then
					clean= false
				end
			end
		else
			break
		end
	end

	if (clean) then
		badge_award("clean")
	end

	badges_runtime_update()

	if (profile) then
		profile.won_current_level()
	end
	
	-- now, figure out if we were rewarded anything
	
	-- XXX DEBUGGING!!!
	--[[
	local campaign_state= campaign_get()
	if (campaign_state.loaded_campaigns.count>0) then
		local campaign= campaign_state.loaded_campaigns[0].campaign
		if (campaign.rewards.count>0) then
			global.reward= campaign.rewards[0]
		end
	end
	--]]
	
	if (global.reward) then
		global.reward_delay= 2
		global.reward_display= true
	end
	
end


function play_animation_after_delay(object, animation_name, delay)
	local tween= object.tween_get()
	if (tween) then
		if (delay > 0) then
			tween.play_animation_after_delay(animation_name, delay)
		else
			tween.play_animation(animation_name)
		end
	end
end

function badge_map_initialize()
	local globals= globals_get()
	if (globals) then
		local badge_settings= globals.badge_settings
		local iterator= badge_settings.badges.iterator_get()
		local count= 0;

		while true do
			local badge= iterator.next()
			if (badge) then
				g_badge_tag_to_type_map[badge.tag]= count
				count = count+1
			else
				break
			end
		end

	end
end

function badge_award(tag)
	local ws= world_state_get()
	local type= g_badge_tag_to_type_map[tag]
	local badge_index= ws.badge_local_index_get(type)
	if (badge_index~=-1) then
		local badge= global["badge"..badge_index]
		
		if (badge and not badge.enabled) then
			badge.enabled= true
			badge_status_change(badge.runtime_object, true, false)
			world_state_get().badge_award(badge.type)
		end
	end
end

function badge_revoke(tag)
	local ws= world_state_get()
	local type= g_badge_tag_to_type_map[tag]
	local badge_index= ws.badge_local_index_get(type)
	if (badge_index~=-1) then
		local badge= global["badge"..badge_index]
		
		if (badge and badge.enabled) then
			badge.enabled= false
			badge_status_change(badge.runtime_object, false, false)
			world_state_get().badge_revoke(badge.type)
		end
	end
end


function badges_runtime_update()

	-- onehit badge
	if (global.player_sighted_count > 1) then
		badge_revoke("onehit")
	end
	
	-- golden path badge
	if (global.player_path_start_count > 1) then
		badge_revoke("path")
	end
	
	if (global.loot_remaining_count==0 and global.required_loot_counter==0) then
		badge_award("master")
	end
	
	local time= 0
	if (global.first_move_time >= 0) then
		time= world_state_get().time.time - global.first_move_time
	end
	if (math.floor(time) > global.goal_time) then
		badge_revoke("time")
	end

end


function badge_status_change(badge, enable, immediate)

	local tint= badge.tint_get()
	local tween= badge.tween_get()

	if (not enable) then
		if (immediate) then
			if tint then
				tint.brightness= 0.75
				tint.contrast= 0.8
				tint.saturation= 0
			end
		else
			if (tween) then
				tween.play_animation("fadeout")
			end
		end
	else
		if (immediate) then
			if tint then
				tint.brightness= 1
				tint.contrast= 1
				tint.saturation= 1
			end
		else
			if (tween) then
				tween.play_animation("fadein")
			end
		end
	end
end

function win_screen_place()

	local ws= world_state_get()
	local w= world_get()
	
	-- place timers, if appropriate

	local globals= globals_get()
	if (globals) then
		local badge_settings= globals.badge_settings
		local time_badge_index= badge_settings.index_from_tag("time")
		if ((time_badge_index ~= -1) and ws.badge_available(time_badge_index)) then
		
			global.win_timer= object_place("time")
			if (global.win_timer) then
			
				local time_msg= ws.place_by_plate("win", "time_msg")
				local goal_time_msg= ws.place_by_plate("win", "goal_time_msg")

				global.goal_timer= object_place("time_goal")
				if (global.goal_timer) then
					play_animation_after_delay(global.goal_timer, "start", 0.25)			
					set_win_timer(global.goal_timer, global.goal_time, nil)
				end
				
				if (goal_time_msg) then
					play_animation_after_delay(goal_time_msg, "start", 0.4)			
				end
				
				play_animation_after_delay(global.win_timer, "start", 0.55)

				if (time_msg) then
					play_animation_after_delay(time_msg, "start", 0.7)
				end
				
			end		
		end
	end
	
	if (global.badge_arrow) then
		object_delete(global.badge_arrow)
	end
	if (global.badge_name) then
		object_delete(global.badge_name)
	end
	if (global.badge_description) then
		object_delete(global.badge_description)
	end
	
	-- place the win screen version of the badge arrow
	global.badge_arrow= object_place("badge_arrow")
	if (global.badge_arrow) then
		global.badge_arrow.hide(true)
	end
	global.badge_name= object_place("badge_name")
	if (global.badge_name) then
		global.badge_name.hide(true)
	end
	global.badge_description= object_place("badge_description")
	if (global.badge_description) then
		global.badge_description.hide(true)
	end


	-- calculate whether this was a perfect run or not
	
	local perfect= true
	local found_badges= false
	local badge_count= 0
	local badge_marker_offset= 0
	local i
	for i=0, 31 do
		if (ws.badge_available(i)) then
			badge_count= badge_count+1
			found_badges= true
			if (not ws.badge_was_awarded(i)) then
				perfect= false
			end
		end
	end
	perfect= (perfect and found_badges)
	if (badge_count==1) then
		badge_marker_offset= 1
	end

	-- now place the shields and position them correctly

	local plate= w.get_plate("win")	
	local perfect_shield_placement= nil
	if (perfect) then
		perfect_shield_placement= plate.placement_get("perfect_shield");
	end
	
	local last_perfect_badge= nil
	for i= 0, 2 do
		local badge_struct= global["badge"..i]
		local badge_definition= ws.badge_definition_get(badge_struct.type)
		if (badge_definition) then

			local placement_name= "badge_"..badge_definition.tag

			local badge= object_place(placement_name)
			badge_struct.object= badge
			
			if (not ws.badge_was_awarded(badge_struct.type)) then
				badge_status_change(badge, false, true)
			end

			-- play start animation with delay
			local delay= i*k_badge_appearance_delay/4
			play_animation_after_delay(badge, "start", delay)

			-- place the badge in the right place				
			local badge_marker= object_place(k_badge_placement_names[i+1+badge_marker_offset])
			if (badge_marker) then
				local position= badge_marker.world_position_get()
				badge.position_set(position.x, position.y)
				
				if (perfect_shield_placement) then
					local perfect_shield= ws.place(perfect_shield_placement)
					if (perfect_shield) then
						perfect_shield.position_set(position.x, position.y)
						
						-- play an animation with delay?
						perfect_shield.tween_animation_play_after_delay("start", (i*0.25)+k_badge_appearance_delay)
						badge_struct.perfect_shield= perfect_shield
						last_perfect_badge= perfect_shield
					end
				end
			end
		end
	end
	
	-- place star and perfection message
	if (perfect and last_perfect_badge) then
		local marker= last_perfect_badge.marker_get("star")
		if (marker) then
			local position= marker.world_position_get(last_perfect_badge)
			
			local star= ws.place_by_plate("win", "perfect_star")
			if (star) then
				star.position_set(position.x, position.y)
				star.tween_animation_play_after_delay("start", k_perfect_appearance_delay)
			end

			if (last_perfect_badge) then
				local perfect_msg= ws.place_by_plate("win", "perfection_message")
				if (perfect_msg) then
					perfect_msg.position_set(position.x, position.y)
					perfect_msg.tween_animation_play_after_delay("start", k_perfect_appearance_delay+0.3)
					--perfect_msg.position_set(last_marker_position.x+0.17, last_marker_position.y+0.19)
				end
			end
			
		end
	end
end

function badge_touch_update(badge, badge_index)
	if (badge) then
		local input= badge.input_get()

		if (input) then
			local touch_started_index= input.get_touch_started()
			local badge_struct= global["badge"..badge_index]
			local active_touch_index= badge_struct.touch_index

			if (touch_started_index ~= -1) then
			
				if (active_touch_index==-1) then
					
					-- play animation to turn on highlight
					--[[
					local press_state= badge.tween_state_get("press_hold")
					if (press_state) then
						press_state.reverse(false)
					
						if (not press_state.is_playing()) then
							badge.tween_animation_play("press_hold")
						end
					end
					-]]
				end

				badge_struct.touch_index= touch_started_index

			elseif (active_touch_index ~= -1) then
				-- potentially turn off highlight

				local touch_interface= touch_get()
				local touch= touch_interface.touch[active_touch_index]
				
				if ((not touch.is_active()) or (not input.touch_still_valid(active_touch_index))) then
					-- turn off highlight
					
					--[[
					local press_state= badge.tween_state_get("press_hold")
					if (press_state) then
						press_state.reverse(true)

						if (not press_state.is_playing()) then
							badge.tween_animation_play("press_hold")
						end
					end
					--]]

					badge_struct.touch_index= -1
				end
				
			end			
		end
	end
end

function badge_description_animate(anim, object, on)
	local tween_state= object.tween_state_get(anim)
	if (tween_state) then
		if (on) then
			tween_state.reverse(false)
			object.tween_animation_play(anim)
		elseif (not object.is_hidden()) then
			tween_state.reverse(true)
			
			if (not tween_state.is_playing()) then
				object.tween_animation_play(anim)
			end
		end
	end
end

function badge_description_update(runtime)

	local badge_to_describe_index= -1
	local min_touch_index= 100
	
	for i= 0, 2 do
		local badge_struct= global["badge"..i]
		local badge_touch_index= badge_struct.touch_index
		if (badge_touch_index ~= -1 and badge_touch_index < min_touch_index) then
			min_touch_index= badge_touch_index
			badge_to_describe_index= i
		end		
	end
	
	local badge_name= global.badge_name
	local badge_description= global.badge_description
	local badge_arrow= global.badge_arrow

	if (badge_name and badge_description) then
	
		local all_hidden= badge_name.is_hidden() and badge_description.is_hidden()
		if (badge_arrow) then
			all_hidden= all_hidden and badge_arrow.is_hidden()
		end
	
		if (all_hidden) then
			global.badge_description_index= -1
		end

		if (badge_to_describe_index ~= global.badge_description_index) then
			-- we're showing the wrong badge description!

			if (all_hidden) then
				-- we can change it!
				global.badge_description_index= badge_to_describe_index
				
				if (badge_to_describe_index ~= -1) then
					-- set the text appropriately
					local globals= globals_get()
					if (globals) then
						local badge_settings= globals.badge_settings
						local badge_struct= global["badge"..badge_to_describe_index]

						local type_index= badge_struct.type
						if (type_index >= 0 and type_index < badge_settings.badges.count) then
							local badge_definition= badge_settings.badges[type_index]
							
							local badge_name_text= badge_name.text_get()
							if (badge_name_text) then
								badge_name_text.text_set(badge_definition.name)
							end
							
							local badge_description_text= badge_description.text_get()
							if (badge_description_text) then
								
								-- if I'm a goal time
								if (badge_struct.time_badge and runtime) then
									local desc= badge_definition.description .. " (" .. time_to_string(global.goal_time) .. ")"
									badge_description_text.text_set_long(desc)
								else
									badge_description_text.text_set_long(badge_definition.description)
								end
							end
						end
					end
					
					badge_name.hide(false)
					badge_description.hide(false)
					if (badge_arrow) then
						badge_arrow.hide(false)
					end
					
					if (global.badge_shim) then
						global.badge_shim.tween_animation_play_direction("fadein", true, false)
					end
					
					local anim_name= "start"
					if (runtime) then
						anim_name = anim_name.."_runtime"
					end
					
					-- animate them in

					badge_description_animate(anim_name, badge_name, true)
					badge_description_animate(anim_name, badge_description, true)
					if (badge_arrow) then
						badge_description_animate("start", badge_arrow, true)					
					
						-- also set the position/rotation of the arrow

						local badge= global["badge"..badge_to_describe_index]
						local position= badge_arrow.world_position_get()
						local rotation= 0
						
						if (runtime) then
							position.x= badge.runtime_object.world_position_get().x
						else
							position.x= badge.object.world_position_get().x
						end
						badge_arrow.position_set(position.x, position.y)
					end
				end
			else
			
				local anim_name= "start"
				if (runtime) then
					anim_name = anim_name.."_runtime"
				end
				
				badge_description_animate(anim_name, badge_name, false)
				badge_description_animate(anim_name, badge_description, false)
				if (badge_arrow) then
					badge_description_animate("start", badge_arrow, false)
				end
				
				if (global.badge_shim and not global.badge_shim.is_hidden()) then
					global.badge_shim.tween_animation_play_direction("fadein", false, false)
				end
			end
		end
	end
end

function play_animation_with_delay(object, animation, delay)
	if (delay<=0) then
		object.tween_animation_play(animation)
	else
		local tween= object.tween_get()
		if (tween) then
			tween.play_animation_after_delay(animation, delay)
		end
	end
end

function object_set_text(obj, s, append)
	if (obj) then
		local text= obj.text_get()
		if (text) then
			if (append) then
				text.append(s)
			else
				text.text_set(s)
			end
		end
	end
end

function place_reward(reward)
	local p= place_plate(k_reward_plate, "start")
	local ps= p.plate_state_get()
	
	local reward_item= reward.items[0]
	local reward_count= reward_item.count
	local item_name= "<invalid>"
	local item_description= "<invalid desc>"
	
	local store= store_get()
	if (store) then
		local store_item= store.item_get_by_id(reward_item.item_name)
		if (store_item) then
			item_name= store_item.name
			item_description= store_item.description
		end
	end

	object_set_text(ps.object_get("perfection_count"), ""..reward.perfection_count, true)
	object_set_text(ps.object_get("reward_name"), item_name, false)
	object_set_text(ps.object_get("reward_count"), ""..reward_count, true)
	object_set_text(ps.object_get("reward_description"), item_description, false)
	
	-- finally place the proper icon
	local marker= ps.object_get("reward_marker")
	if (marker) then
		local ws= world_state_get()
		local marker_position= marker.world_position_get()
		local icon_object= ws.place_by_plate(k_reward_plate2, reward_item.item_name);
		if (icon_object) then
			
			icon_object.position_set(marker_position.x, marker_position.y)

			-- set its location
			icon_object.tween_animation_play("start")
		end
	end
end

function reward_update()

	local dismiss= false
	if (global.reward_delay > 0) then
	
		local ws= world_state_get()
		local dt= ws.master_time.delta_t()
		global.reward_delay = global.reward_delay-dt
		
		if (global.reward_delay <= 0) then
			if (global.reward) then
				place_reward(global.reward)
			end
		end
	end
	
	local touch_interface= touch_get()
	local handled= false
	if (touch_interface and touch_interface.touch_started()) then
		local touch_index= touch_interface.touch_start_index()
		local touch= touch_interface.touch[touch_index]
		local object= touch.touch_handler_object
		if (object) then
			local placement= object.placement
			if (placement) then
				local name= placement.name

				if (name=="reward_continue") then
					object.button_press()
					dismiss= true
					handled= true
				end
			end
		end
	end
	
	if (not handled) then
		local keyboard= keyboard_get()
		if (keyboard) then
			if (keyboard.pressed[k_escape_key]) then
				dismiss= true
				handled= true
			end
		end
	end

	if (dismiss) then
		end_plate2(k_reward_plate, "start")
		end_plate2(k_reward_plate2, "start")
		global.reward_display= false
	end
end

function won_update()

	if (global.win_screen_display) then

		local ws= world_state_get()
		local master_time= ws.master_time.time
		local delta_t= master_time - global.load_pending_time
		
		if (delta_t > 0.5*k_blind_time) then

			-- create the win screen
			if (not global.win_screen_on) then
			
				local w= world_get()
				local ws= world_state_get()
				
				win_screen_place()				
				
				if (global.win_timer) then
					set_win_timer(global.win_timer, 0, nil)
				end
				global.won_time_counter= 0
				global.win_screen_on= true
			end


			if (global.won_time_counter < global.won_time) then
				global.won_time_counter = global.won_time_counter + k_win_timer_increments
				if (global.won_time_counter > global.won_time) then
					global.won_time_counter = global.won_time
				end
			
				if (global.win_timer) then
					set_win_timer(global.win_timer, global.won_time_counter, nil)
				end
			end
			
			if (global.reward_display) then
				reward_update()
			else
				local touch_interface= touch_get()
				local handled= false
				if (touch_interface and touch_interface.touch_started()) then
					local touch_index= touch_interface.touch_start_index()
					local touch= touch_interface.touch[touch_index]
					local object= touch.touch_handler_object
					
					if (object) then
					
						local plate_state= ws.plate_state_get("win")
						local placement= object.placement
						if (placement and plate_state) then
							local name= placement.name
							local highlight= nil
							
							local k_load_delay= 1
							
							if (name=="replay" or name=="reset_button") then
								global.win_screen_display= false
								
								global.load_pending_time= world_state_get().master_time.time - k_load_pending_time + k_load_delay	-- was 0.5
								global.load_pending_type= k_load_pending_reset
								global.load_handled= false
								k_analytics.level_ended(k_outcome_won_reset)
								campaign_get().level_was_reset()
								
								handled= true
							elseif (name=="next") then
								
								-- crazy shit ... setting up the load pending state but NOT calling load pending start
								-- it was a madman who wrote this.
								global.load_pending_time= world_state_get().master_time.time - k_load_pending_time + k_load_delay	-- was 0.6
								global.load_pending_type= k_load_pending_next_level
								global.load_handled= false
								k_analytics.level_ended(k_outcome_won)

								global.win_screen_display= false
								place_loading_message(0.5)
								handled= true
							end
							
							if (handled) then

								local badge0= global.badge0
								local badge1= global.badge1
								local badge2= global.badge2

								if (badge0.object) then
									badge0.object.tween_animation_play("end")
									if (badge0.perfect_shield) then
										badge0.perfect_shield.tween_animation_play_direction("start", false, false)
									end
								end
								if (badge1.object) then
									badge1.object.tween_animation_play("end")
									if (badge1.perfect_shield) then
										badge1.perfect_shield.tween_animation_play_direction("start", false, false)
									end
								end
								if (badge2.object) then
									badge2.object.tween_animation_play("end")
									if (badge2.perfect_shield) then
										badge2.perfect_shield.tween_animation_play_direction("start", false, false)
									end
								end

								if (global.goal_timer) then
									global.goal_timer.tween_animation_play("end")
								end
								if (global.win_timer) then
									play_animation_after_delay(global.win_timer, "end", 0.2)
								end
								local win_plate_state= ws.plate_state_get("win")
								if (win_plate_state) then
									local time_msg= win_plate_state.object_get("time_msg")
									local goal_time_msg= win_plate_state.object_get("goal_time_msg")
									
									if (goal_time_msg) then
										goal_time_msg.tween_animation_play_after_delay("end", 0.1)
									end
									
									if (time_msg) then
										time_msg.tween_animation_play_after_delay("end", 0.3)
									end
								end

								end_plate(k_win2_plate, "end")

								-- "next", "replay" and "reset_button"
								local next_object= plate_state.object_get("next")
								local replay_object= plate_state.object_get("replay")
								
								next_object.tween_animation_play_direction("start", false, false)
								replay_object.tween_animation_play_direction("start", false, false)

								-- finally, press the button that got hit
								object.button_press()
								
								local perfect_star= plate_state.object_get("perfect_star")
								local perfect_msg= plate_state.object_get("perfection_message")

								if (perfect_star) then
									perfect_star.tween_animation_play_direction("start", false, false)
								end
								if (perfect_msg) then
									perfect_msg.tween_animation_play_direction("start", false, false)
								end
								
							end
						end
					end
				end

				if (not handled) then
					badge_touch_update(global.badge0.object, 0)
					badge_touch_update(global.badge1.object, 1)
					badge_touch_update(global.badge2.object, 2)
				end
				
				badge_description_update(false)
			end
		end
	end
end


-- ------------------- LOST ------------------- 


function lost_start(object)
	local w= world_get()
	local ws= world_state_get()

	--[[
	local placement= w.placement_get("death_shim");
	if (placement) then
		global.shim= ws.place(placement)
	else
		print("error: game_hud was looking for a placement named death_shim")
	end
	--]]
	object_place("death_shim")

	global.lost= true
	global.lost_time= ws.time.time
	
	ws.sound_manager.play_sound_by_name("death", k_ui_time_mode)
	
	local campaign= campaign_get()
	if (campaign) then
		campaign.level_failed()
	end
	
	if (global.fast_forwarding) then
		fast_forward_pressed()
	end
	
	music_fadeout()

	k_analytics.level_ended(k_outcome_failed)

end

function lost_update(object)
	local ws= world_state_get()
	if ((ws.time.time - global.lost_time) > k_lost_reset_delay) then
		world_state_get().reset()
	end
end



-- ------------------- system ------------------- 

function start()
	local w= world_get()
	local ws= world_state_get()

	-- note this is the player at the START of the levels
	global.player= ws.primary_player_get()
	global.reset= object_get("reset_button")
	global.gear= object_get("gear")
	
	global.reset.hide(false)
	
	global.pause_scrim= object_place("pause_scrim")
	if (global.pause_scrim) then
		global.pause_scrim.hide(true)
	end
	global.pause_highlight= object_place("pause_highlight")
	if (global.pause_highlight) then
		global.pause_highlight.hide(true)
	end
	global.badge_shim= object_place("badge_shim")
	if (global.badge_shim) then
		global.badge_shim.hide(true)
	end
	
	
	global.blind_placement= w.placement_get("blind")
	
	global.fast_forward_object= object_get("fast_forward")
	
	global.sound_forward= ws.sound_manager.get_sound_by_name("forward");
	global.sound_back= ws.sound_manager.get_sound_by_name("back");
	
	local campaign= campaign_get()
	if (campaign) then
		local fail_count= campaign.fail_count_get()
		if (fail_count> 1) then
			global.skip= object_place("skip")
		end
		
		if (fail_count >= 4) then
			-- don't play music if we've failed a couple times
			global.music_play= false
		end
	end
	
	-- find goal time
	local cs= campaign_get()
	if (cs) then
		local level= cs.get_current_level()
		if (level) then
			global.goal_time= math.floor(level.goal_time)
		end
	end

	-- badge descriptions
	
	global.badge_name= object_place("badge_name_runtime")
	global.badge_description= object_place("badge_description_runtime")
	global.badge_arrow= object_place("badge_arrow_runtime")

	if (global.badge_name) then
		global.badge_name.hide(true)
	end
	if (global.badge_description) then
		global.badge_description.hide(true)
	end
	if (global.badge_arrow) then
		global.badge_arrow.hide(true)
	end
	
	
	-- determine what badges we have available to us
	local i
	local badge_count= 0
	for i= 0, k_max_badge_count-1 do
		if (ws.badge_available(i)) then
		
			local badge_struct= global["badge"..badge_count]
		
			badge_struct.type= i
			badge_count= badge_count+1
			
			local badge_definition= ws.badge_definition_get(i)
			if (badge_definition) then
			
				local placement_name= "badge_"..badge_definition.tag.."_runtime"
				local badge= object_place(placement_name)
				badge_struct.runtime_object= badge

				if (badge_definition.tag=="time") then
					badge_struct.time_badge= true
				end

				--badge.scale_set_uniform(k_badge_scale_runtime)
				badge.hide(false)

				if (badge_definition.initially_awarded()) then
					badge_struct.enabled= true
				else
					badge_status_change(badge, false, true)				
					badge_struct.enabled= false
				end
				
				-- place the badge in the right place				
				local badge_marker= object_place(k_runtime_badge_placement_names[badge_count])
				if (badge_marker) then

					-- move badge to the target plate
					ws.object_move_to_plate(badge, badge_marker.plate)
				
					local position= badge_marker.world_position_get()
					badge.position_set(position.x, position.y)
				end
			end

			if (badge_count >= 3) then
				break
			end
		end
	end
	
	if (badge_count==0) then
		local badge_shelf= object_get("badge_shelf")
		if (badge_shelf) then
			badge_shelf.hide(true)
		end
	end
end

function music_play_campaign(index, loop)
	local campaign= campaign_get()
	local current_campaign= campaign.current_campaign
	local level= campaign.get_current_level()
	
	local music_index= -1
	if (level) then
		music_index= level.music[index]
	end

	if (current_campaign and (music_index >= 0) and (music_index < current_campaign.music_refs.count)) then
		local filename= current_campaign.music_refs[music_index].music_filename
		local sm= world_state_get().sound_manager
		
		--print ("MUSIC INDEX: "..index.. "   MUSIC FILE: "..filename)
		
		local mid= sm.get_playing_music_id(filename)
		if (mid ~= -1) then
			-- already playing it!
		else

			if (global.music_id ~= -1) then
				sm.fadeout_music(global.music_id, 0.25, true)
				global.music_id= -1
			end
			
			global.music_id= sm.play_music(filename, loop)
		end
		
	end
end

function music_fadeout()
	if (global.music_id  ~= -1) then
		local ws= world_state_get()
		local sound= ws.sound_manager
		sound.fadeout_music(global.music_id, 1, true)
		global.music_id= -1
	end
end


function game_sound_update()

	if (global.music_play and global.music_sneaking_play) then
		global.music_sneaking_play= false
		music_play_campaign(0, false)
	end

	if (not global.alerted) then
		local ws= world_state_get()
		local i= ws.targets.iterator_get()
		while (true) do
			local target= i.next()
			if (target) then
				if (target.is_immediate() and target.is_targetable()) then
					local target_object= target.target_object
					local player_control= target_object._p.player_control
					if ((player_control==nil) or (player_control.causes_general_alert)) then
						global.alerted= true
						break
					end
				end
			else
				break
			end
		end
		
		
		if (global.alerted) then

			if (global.music_play) then
				local sm= ws.sound_manager
				sm.play_sound_by_name("alerted", k_ui_time_mode)
			
				global.music_sneaking_play= false
				music_play_campaign(1, true)
			end
			
			-- note: also remove the "ghost" badge
			badge_revoke("ghost")
		end
	end
end

function update_loot_counter()
	local counter= global.loot_counter
	if (counter) then
		local text_component= counter.text_get()
		if (text_component) then
		
			--print(global.loot_count)
			--print(global.loot_remaining_count)
		
			local total_possible= global.loot_count + global.loot_remaining_count
			local text= " "..global.loot_count.."/"..total_possible

			text_component.text_set(text)
			
			counter.tween_animation_play("increment")
		end
	end
end

function update_key_counter(num)

	local counter= global.key_counter
	if (counter) then
		local text_component= counter.text_get()
		if (text_component) then
		
			--print(global.loot_count)
			--print(global.loot_remaining_count)
		
			local total_possible= global.loot_count + global.loot_remaining_count
			local text= "  x"..num.." "

			text_component.text_set(text)
			
			counter.tween_animation_play("increment")
		end
	end

	global.key_count= num
end

function play_flash(object)
	local tween= object.tween_get()
	local tween_state= tween.tween_state_get("flash")
	if (tween_state) then
		tween_state.stop()
	end
	tween.play_animation("flash")
end

function store_load()

	-- ask the gear manager to refresh its iap counts
	local gear_manager_script= world_state_get().global_script("gear_manager")
	if (gear_manager_script) then
		gear_manager_script.refresh_iap_counts= true
	end

	-- and load the zone
	world_get().zone_load_from_file("ui/store/store.zone")
end

function change_shelf(icon_object, mode)
	local ws= world_state_get()
	local button= icon_object.button_get()
	if (mode==0) then						-- k_mode_standard
		if (button) then
			button.disable_color(false)
			button.press()
		end

		-- play a sound
		ws.sound_manager.play_sound_by_name("back", k_ui_time_mode)
	else
		if (button) then
			button.disable_color(true)
			button.press()
		end
		icon_object.tween_animation_play("press_hold")
		
		-- play a sound
		ws.sound_manager.play_sound_by_name("forward", k_ui_time_mode)
		
		-- we turned on the iap shelf ... potentially load the tutorial?
		local player_profile= player_profile_get()
		if (player_profile) then
		
			-- IAP tutorial is a one time message (per player profile)
			local campaign_record= player_profile.current_campaign_record_get()
			if (campaign_record and not campaign_record.onetime_message_is_complete(0)) then
				local w= world_get()
				local game_hud_zone_ref= w.zone_reference_get("game_hud", false)
				if (game_hud_zone_ref) then
					local game_hud_zone= game_hud_zone_ref.zone
					if (game_hud_zone) then
						local external_ref= game_hud_zone.zone_ref_get("iap_tutorial")
						if (external_ref) then
							external_ref.load_as_runtime()

							campaign_record.onetime_message_set_complete(0)
							player_profile.save()
						end
					end
				end
			end
		end
	end	
end

function skip_start(skip_button)
	local w= world_get()
	local skip_plate= w.get_plate("skip")
	if (skip_plate) then
		local ws= world_state_get()
		ws.game_time_pause()
		ws.place_plate(skip_plate)
		global.skipping= true
	end	
end

function skip_update()
	local touch_interface= touch_get()
	if (touch_interface and touch_interface.touch_started()) then
		local touch_index= touch_interface.touch_start_index()
		local touch= touch_interface.touch[touch_index]
		local object= touch.touch_handler_object
		if (object) then
			local placement= object.placement
			if (placement) then
				local name= placement.name
				local finished= false
				
				if (name == "skip_confirm") then
					finished= true
					skip_execute()
				elseif (name == "skip_cancel") then
					finished= true
				end
				
				if (finished) then
					object.button_press()
					skip_end()
				end
			end
		end
	end
end

function skip_execute()
	local app_settings= app_settings_get()
	if (app_settings) then
		-- make sure this level is considered unlocked
		app_settings.unlock_next()
	end
	load_pending_start(k_load_pending_next_level)
	k_analytics.level_ended(k_outcome_skipped)
end

function skip_end()
	local ws= world_state_get()
	ws.game_time_play()
	
	local ps= ws.plate_state_get("skip")
	if (ps) then
		ps.delete_all()
	end
	global.skipping= false
end


function update()

	local ws= world_state_get()
		
	if (global.load_pending) then
		load_pending_update()
	elseif (global.skipping) then
		skip_update()
	elseif (global.paused) then
		pause_update()
	elseif (global.lost) then
		lost_update()
	elseif (game_pause_is_pending()) then
		if (not world_state_get().game_is_paused()) then
			pause_start()
		else
			-- we're ALREADY paused for some reason
			-- maybe the store is up, or maybe we're already paused
			-- note we miss an update here. But c'est la vie.
			game_pause_pending_clear()
		end
	else

		if (global.player) then

			local vitality= global.player._c.vitality
			local vitality_definition= global.player._p.vitality

			if (vitality_definition.max_vitality > 0) then
				local fraction= vitality.vitality/vitality_definition.max_vitality
				
				-- spawn the health bar if necessary
				if ((fraction < 1) and (fraction > 0) and not global.health_bar) then

					if (not global.health_bar_frame) then
						local healthbar_frame_placement= world_get().placement_get("health_bar_frame")
						if (healthbar_frame_placement) then
							global.health_bar_frame= ws.place(healthbar_frame_placement)
						end
					end

					local healthbar_placement= world_get().placement_get("health_bar")
					if (healthbar_placement) then
						global.health_bar= ws.place(healthbar_placement)
					end
					
					if (global.health_bar_frame and global.health_bar) then
						local marker= global.health_bar_frame.marker_get("bar")
						object_attach(global.health_bar_frame, marker, global.health_bar, nil)
					end
				end
				
				if (fraction < 1) then
					badge_revoke("bulletproof")
				end
				
				local frame= global.health_bar_frame
				local bar= global.health_bar

				if (bar) then
					bar.scale_set(fraction, 1)
				end
				
				if (vitality.last_damage_time == ws.time.time) then

					if (frame) then
						play_flash(frame)
					end
					
					if (bar) then
						play_flash(bar)
					end
					
					--frame.tween_animation_play("flash")
				
					--if (frame.attachment.child_count < 5) then		-- we allow the health bar and two highlights
					--	local spawner= frame.spawn_get("highlight")
					--	if (spawner) then
					--		spawner.spawn()
					--	end
					--end
				end
			end

			if (not global.loss_disable and (vitality.dead or global.loss_pending)) then
				lost_start()
			end
		end

		if (global.win_pending and (not global.won) and not global.lost) then
			won_start()
		end

		game_sound_update()

		if (global.loot_pending_count > 0) then
			local w= world_get()
			
			--local placement_name= k_loot_names[global.loot_count+1]
			--local placement= w.placement_get(placement_name)
			
			if (global.loot_count==0) then
				local placement= w.placement_get("hud_loot")
				if (placement) then
					local hud_loot= ws.place(placement)
					
					--local pos= hud_loot.world_position_get()
					--pos.x = pos.x + global.loot_count*k_hud_loot_offset
					--hud_loot.position_set(pos.x, pos.y)
				end
				
				global.loot_counter= object_place("loot_counter")
			end
			
			global.loot_count= global.loot_count+1
			global.loot_pending_count= global.loot_pending_count-1
			global.loot_remaining_count = global.loot_remaining_count-1
			
			update_loot_counter()
		end
		
		local gear_manager= ws.global_script("gear_manager")
		if (gear_manager) then
			local current_key_num= gear_manager.key_count
			
			if (current_key_num ~= global.key_count) then
				if (global.key_count==0 and global.key_counter==nil) then
					global.key_counter= object_place("key_counter")
					object_place("hud_key")
				end
				
				update_key_counter(current_key_num)
			end
		end
		
		if ((not global.won) and (not global.lost)) then
			local touch_interface= touch_get()
			local handled= false

			if (touch_interface and touch_interface.touch_started()) then
				local touch_index= touch_interface.touch_start_index()
				local touch= touch_interface.touch[touch_index]
				local object= touch.touch_handler_object
				if (object) then
					local placement= object.placement
					if (placement) then
						local name= placement.name
						if (name == "reset_button") then
							music_fadeout()
							ws.reset()
							k_analytics.level_ended(k_outcome_reset)
							campaign_get().level_was_reset()
							handled= true
						elseif (name == "gear") then
							pause_start()
							handled= true
						elseif (name == "fast_forward") then
							fast_forward_pressed()
							handled= true
						elseif (name == "skip") then
						
							skip_start(object)
							object.button_press()
							handled= true
						
						elseif (name == "iap_icon") then
							local gear_manager= ws.global_script("gear_manager")
							if (gear_manager) then
								gear_manager.desired_mode = (1 - gear_manager.desired_mode)
								change_shelf(object, gear_manager.desired_mode)
								handled= true
							end
						elseif (name == "store_icon") then
							object.tween_animation_play("pressed")
							object.tween_animation_play("pop")
							store_load()
							handled= true
						end
					end
				end
			end

			if (not handled) then
				local keyboard= keyboard_get()
				if (keyboard) then
					if (keyboard.pressed[k_escape_key]) then
						pause_start()
					end
				end
			end
		end
		
		badge_touch_update(global.badge0.runtime_object, 0)
		badge_touch_update(global.badge1.runtime_object, 1)
		badge_touch_update(global.badge2.runtime_object, 2)
		
		badge_description_update(true)		
		
	end
	
	if (global.skip and ws.time.time > k_skip_message_time) then
		if (not global.skip.tween_animation_play("end")) then
			object_delete(global.skip)
		end
		global.skip= nil
	end
	
	if (global.loss_disable and global.fast_forwarding) then
		fast_forward_pressed()
	end

	if (not global.won) then
		global.badge_update_delay= global.badge_update_delay-ws.time.delta_t()
		if (global.badge_update_delay <= 0) then
			badges_runtime_update()
			global.badge_update_delay= k_badge_status_update_delay
		end
	end
	
end

badge_map_initialize()

system_register(start, update, nil, nil)

