speech_duration = 4;

game_manager = FistGameManager:getSharedFistGameManager()
bot_manager = game_manager.BotManager
camera_manager = game_manager.CameraManager
hud = game_manager.HUD
level_manager = game_manager.LevelManager
player = game_manager.Player
arena_manager = game_manager.ArenaManager
arena_helper = game_manager:getArenaModeHelper()


bear_fight_hud_duration = 1.5

function init_arena(backdrop_name, start_pos, is_restart)

	if (is_restart == false) then
		-- Load background
		game_manager:setBackdropFile(backdrop_name)

		-- Run first trigger
		game_manager:startTimer(0, onArenaLoad);

	end

	local backdrop = game_manager.Background
	
	if (backdrop ~= nil) then
		CCLuaLog("FOUND BACKDROP")
	else
		CCLuaLog("ERROR: Could not open backdrop '" .. backdrop_name .. "'")
	end

	-- No triggers in arena mode
	game_manager:disableTriggers()
	
	-- Starting position
    game_manager.Player:setBasePosition(start_pos)

    -- ensure screen is whited out
	hud:doScreenFade(ccc4(255,255,255,255), 0)
	
	-- Allow health regen in arenas
	game_manager.Player.HealthRegenActive = true;

	-- Play music for arena
	game_manager.MusicManager:play(arena_helper:getCurrentMusicTrackName())


end

function onArenaLoad()

	-- Use full controls...
	player:connectInputSignals();

	-- Fade in from white
	hud:doScreenFade(ccc4(0,0,0,0), 0.5)

	game_manager:startTimer(0.5, showArenaTimeAndLocation);

	-- Restart from here
	game_manager:setRestartCheckpoint("onArenaLoad");

end



function showArenaTimeAndLocation()

	local arena_index = arena_helper:getCurrentArenaIndex()
	location_name = arena_helper:getArenaTimePeriod(arena_index)
	time_period = arena_helper:getArenaLocationName(arena_index)
	showTimeAndLocation(location_name, time_period, 2)
   
    -- Show the arena timer display
    game_manager:startTimer(3, beginArena)

	-- Tell Arena Manager to start doing its thing
	arena_manager:initArena()
    hud:showArenaTasks()


	-- start the arena mode
	game_manager:startTimer(1, nextWave)

end

function beginArena()

	-- Start timer
	arena_manager:beginArena()

	-- Show the arena timer display
    hud:showArenaTimer()

end


function init_level(backdrop_name, start_pos, is_restart, no_cinemascope)

	if (is_restart ~= true) then
		
		-- Load background
		game_manager:setBackdropFile(backdrop_name)

	end

	local backdrop = game_manager.Background
	
	if (backdrop ~= nil) then
		CCLuaLog("FOUND BACKDROP")
	else
		CCLuaLog("ERROR: Could not open backdrop '" .. backdrop_name .. "'")
	end
	
	-- Starting position
    game_manager.Player:setBasePosition(start_pos)
	
	-- Enable health regen in levels
	game_manager.Player.HealthRegenActive = true;

	local player_desc = game_manager:actorDescWithFile("lumberjack.plist")
	game_manager:setPlayerDesc(player_desc)

	-- Use full controls...
	player:connectInputSignals();

	-- Fade in from white
	hud:doScreenFade(ccc4(255,255,255,255), 0)
	hud:doScreenFade(ccc4(0,0,0,0), 0.5)

	-- Bit hacky
	game_manager.CameraManager.ShakeScale = 0

	level_manager:setLevelName(backdrop_name)

	if (no_cinemascope ~= true) then
		game_manager:startTimer(0.2, showLevelTimeAndLocation)
	end

	game_manager.MusicManager:play(level_manager:getMusicTrackName())
--	showLevelTimeAndLocation()

	-- Start the level intro if required
	if (is_restart ~= true) then
		startLevelIntro(is_restart, no_cinemascope)
	end

end

--[[ Kick off the level intro
  ]]
function startLevelIntro(is_restart, no_cinemascope)

	-- Restart from here
	if (is_restart ~= true) then
		game_manager:setCheckpoint("startLevelIntro")
	end


	if (no_cinemascope == nil) then
		no_cinemascope = false
	end

	if (no_cinemascope == false) then
		-- BUCKLE UP IT'S CINEMASCOPE TIME!!
		game_manager:startTimer(0.1, function() hud:enableCinemascope() end)
	end

	player:setFacingDir(kFacingDir_Right)

	-- if (is_restart == true) then
	-- 	-- Skip intro when restarting
	-- 	connectControls()
	-- else
		-- Wait a little bit then start level intro
		disconnectControls(false)
		game_manager:startTimer(2, onLevelIntro)
	-- end
end

--[[ Called when level intro completed
  ]]
function onLevelIntroEnd()

	connectControls()
	hud:disableCinemascope()

end

-- Display the current time and location to player
function showTimeAndLocation(time, location, duration)

	if (duration == nil) then
		duration = 3
	end

	--CCLuaLog("SHOW "..time.." - "..location)
    hud:showTimeAndLocation(time, location, duration)

end

function showLevelTimeAndLocation()

	showTimeAndLocation(level_manager:getTimePeriod(), level_manager:getLocationName())

end

function showBearFight(bear_actor)

    local player = game_manager.Player

	hud:showBearFight();
	game_manager:startTimer(bear_fight_hud_duration, function() hud:hideBearFight() end);

--	hud:showFightHealth(player, bear_actor);	
end

function showActorHealth(actor)

    local player = game_manager.Player
	hud:showFightHealth(player, actor);

end

function startCameraBlock(trigger_node)
	CCLuaLog("startCameraBlock")
	if (bot_manager:getNumActiveBots() > 0 or bot_manager:getNumQueuedBots() > 0) then
		--camera_manager:setRightEdgeCollisionToCameraBounds(true);
		local bounds = boundingBox(trigger_node)
		camera_manager:setRightEdgeCollision(bounds:getMaxX())
	end

	return true
end

function startCameraBlockNoCheck(trigger_node)
	CCLuaLog("startCameraBlock")
	--camera_manager:setRightEdgeCollisionToCameraBounds(true);
	local bounds = boundingBox(trigger_node)
	camera_manager:setRightEdgeCollision(bounds:getMaxX())

	return true
end

function checkStopCameraBlock()

--	CCLuaLog("checkStopBlock - ActiveBots "..bot_manager:getNumActiveBots() .." QueuedBots" ..bot_manager:getNumQueuedBots())

	if (bot_manager:getNumActiveBots() == 0 and bot_manager:getNumQueuedBots() == 0) then
		stopCameraBlock()
	end

	return true
end

function checkStopCameraBlockNoGo()

--	CCLuaLog("checkStopBlockNoGo - ActiveBots "..bot_manager:getNumActiveBots() .." QueuedBots" ..bot_manager:getNumQueuedBots())

	if (bot_manager:getNumActiveBots() == 0 and bot_manager:getNumQueuedBots() == 0) then
		stopCameraBlockNoGo()
	end

	return true
end

function stopCameraBlock(show_go)

	CCLuaLog("STOPCameraBlock")

	if (show_go ~= false) then
		CCLuaLog("stopCameraBlock - GO!")
		show_go = true
	end

	camera_manager:setRightEdgeCollisionToCameraBounds(false);
	bot_manager:killAllBots()

	-- Hide the player's health now
	hud:hidePlayerHealth()

    if (game_manager:getGameMode() == kFistGameMode_Story) then
    	
        if (show_go == true) then
            showGO();
        end

        -- Restart from this location
        genericCheckpoint()
        
    end

	return true
end

function genericCheckpoint(is_restart)

	-- Restart from here
	if (is_restart ~= true) then
		game_manager:setCheckpoint("genericCheckpoint")
	else
		showGO();
	end

end

function stopCameraBlockNoGo()
	CCLuaLog("stopCameraBlockNoGo")
	stopCameraBlock(false)
end

function showGO()

	hud:showGO();
	game_manager:startTimer(4, function() hud:hideGO() end);
end

function say(character, text, startTrigger, endTrigger)
	hud:playSpeech(character, text, speech_duration, startTrigger, endTrigger);
end


-- Spawn an end of level boss bear
function spawn_bigbear(bear_type)

	-- BEAR!
	local bot_desc = game_manager:actorDescWithFile(bear_type .. ".plist")
	local bear_id = bot_manager:addBotToSpawnQueue(bot_desc, kSpawnDir_Right)
	bot_manager.BossID = bear_id

	-- BEAR FIGHT HUD
--	bot_manager:triggerOnBotEvent(bear_id, kBotTrigger_Spawned, showBearFight)
	bot_manager:triggerOnBotEvent(bear_id, kBotTrigger_Killed, function() hud:hideFightHealth() end)

	return bear_id;
end


-- Start a new wave of enemies for an arena stage
function startBossAmbush(bot_descs, bigbear_type)
        
    -- Make space for our new bots
    bot_manager:clearSpawnQueue()

	-- Spawn end of level boss bear
	local bear_id = spawn_bigbear(bigbear_type)
	bot_manager:triggerOnBotEvent(bear_id, kBotTrigger_Spawned, onArenaBossSpawned)

	-- Check after death if we can release screen lock
	bot_manager:triggerOnBotEvent(bear_id, kBotTrigger_Killed, stopCameraBlock)
	
	if (game_manager:getGameMode() == kFistGameMode_Story) then
		if (game_manager:isDemo()) then
			if (level_manager:isLastLevel() == true) then
--				bot_manager:triggerOnBotEvent(bear_id, kBotTrigger_Died, onDemoEnd)
			end
		end
	end

	-- Spawn regular enemies
	local num_bots = 100
	if (table.getn(bot_descs) > 0) then
		startAmbush(bot_descs, num_bots)
	end

	return bear_id	
end

function onArenaBossSpawned(bot)

	hud:showBossHealth(bot)

end

-- Start a new wave of enemies for a level showdown
function startLevelBossFight(bigbear_type, bot_descs, bIsRestart, show_go)
        
    CCLuaLog("startLevelBossFight!")

   	if (show_go == nil) then
   		CCLuaLog("startLevelBossFight - GO!")
    	show_go = true
    end

    -- Make space for our new bots
    bot_manager:clearSpawnQueue()

	-- Spawn end of level boss bear
	level_boss_restart = bIsRestart
	level_boss_type = bigbear_type
	local boss_id = spawn_bigbear(bigbear_type)

	-- Check after death if we can release screen lock
	if (show_go == true) then
		bot_manager:triggerOnBotEvent(boss_id, kBotTrigger_Killed, stopCameraBlock)
	else
		bot_manager:triggerOnBotEvent(boss_id, kBotTrigger_Killed, stopCameraBlockNoGo)
	end

	-- Keep track of who the gang members are
	level_boss_dudes = bot_descs
	level_boss_show_go = show_go

	CCLuaLog("level_boss_show_go is " .. tostring(level_boss_show_go))

	-- Depending if this is a restart or not skip intro text
	-- if (bIsRestart ~= true) then
		bot_manager:triggerOnBotEvent(boss_id, kBotTrigger_Spawned, onLevelBossSpawned)
	-- else
	-- 	bot_manager:triggerOnBotEvent(boss_id, kBotTrigger_Spawned, onLevelBossSpawnedRestart)
	-- end

	return boss_id	
end

--[[ Level boss has spawned. 
     Tell him to walk to near the player and start talking 
  ]]
function onLevelBossSpawned(boss)

	-- keep track of boss actor
	level_boss = boss

	-- Pause player movement
	disconnectControls()

	-- Tell bear to go to start location
	local screenBounds = camera_manager:getGameScreenBounds()
	local target_pos = player:getBasePosition()
	target_pos = CCPoint(target_pos.x + screenBounds.size.width * 0.5, target_pos.y)
	boss:setTargetPosition(target_pos)
	boss:setTargetPositionLocked(true)

	-- When bear gets to the start location, start talking
	boss_id = bot_manager:getBotID(boss);
	bot_manager:triggerOnBotEvent(boss_id, kBotTrigger_ReachedTarget, onLevelBossSpeech)

	-- BUCKLE UP IT'S CINEMASCOPE TIME!!
	hud:enableCinemascope()

	local screenBounds = camera_manager:getGameScreenBounds()
 	camera_manager:setLeftEdgeCollision(screenBounds:getMinX() + screenBounds.size.width * 0.25)

end

--[[ Level boss has spawned. 
      As this is a restart skip all the intro speech stuff 
  ]]
function onLevelBossSpawnedRestart(boss)

	-- keep track of boss actor
	level_boss = boss

	-- Tell bear to go to start location
--	local target_pos = player:getBasePosition()
--	target_pos = CCPoint(target_pos.x + 40, target_pos.y)

	local screenBounds = camera_manager:getGameScreenBounds()
	local target_pos = player:getBasePosition()
	target_pos = CCPoint(target_pos.x + screenBounds.size.width * 0.5, target_pos.y)
	boss:setTargetPosition(target_pos)
	boss:setBasePosition(target_pos)
	boss:setPosition(target_pos)

	-- Connect controls, show HUD & spawn gang
	onLevelBossSpeechEnd()

end


function onLevelBossSpeechEnd()

	-- Well that's the end of that CINEMASCOPE TIME!!
	hud:disableCinemascope()

	connectControls(false, false)

	-- BEAR FIGHT!
	showBearFight(level_boss)

	-- Allow a little leeway in screen movment
	local screenBounds = camera_manager:getGameScreenBounds()
 	camera_manager:setRightEdgeCollision(screenBounds:getMaxX() + screenBounds.size.width * 0.1)


	game_manager:startTimer(bear_fight_hud_duration, 
		function() 

			connectControlsAndResumeBots(false)

			hud:showBossHealth(level_boss)

			startAmbush(level_boss_dudes, 200, nil, level_boss_show_go)

		end)

end

--[[ Spawn a new enemy of a specific type ]]
function spawnEnemy(enemy_type, spawn_dir, check_block)

    if (spawn_dir == nil) then
    	spawn_dir = kSpawnDir_Random
    end

    if (check_block == nil) then
    	check_block = true
    end

	-- Get descriptor for enemy
	local bot_desc = game_manager:actorDescWithFile(enemy_type .. ".plist")

	-- Tell Bot Manager to spawn enemy
	local bot_id = bot_manager:addBotToSpawnQueue(bot_desc, spawn_dir, 1)
	bot_manager:triggerOnBotEvent(bot_id, kBotTrigger_Spawned, onEnemySpawned)

	if (check_block == true) then
		-- Check after death if we can release screen lock
		bot_manager:triggerOnBotEvent(bot_id, kBotTrigger_Killed, checkStopCameraBlock)
	end

	return bot_id

end

-- Start a new wave of enemies for an arena stage
function startAmbush(bot_descs, num_bots, spawn_dir, show_go)
        	
    if (spawn_dir == nil) then
    	spawn_dir = kSpawnDir_Random
    end

	if (show_go == nil) then
    	show_go = true
    end
	-- Spawn regular enemies
	local bot_index = 1
	for i = 1, num_bots, 1 do

		bot_index = (bot_index + 1) % table.getn(bot_descs)
		local bot_desc = bot_descs[bot_index + 1];

		-- EASY MODE
		--bot_desc:setHealth(1);

		local bot_id = bot_manager:addBotToSpawnQueue(bot_desc, spawn_dir, 1)
		bot_manager:triggerOnBotEvent(bot_id, kBotTrigger_Spawned, onEnemySpawned)

		if (show_go == true) then
			-- Check after death if we can release screen lock
			bot_manager:triggerOnBotEvent(bot_id, kBotTrigger_Killed, checkStopCameraBlock)
		else
			-- Check after death if we can release screen lock
			bot_manager:triggerOnBotEvent(bot_id, kBotTrigger_Killed, checkStopCameraBlockNoGo)
		end
		
	end
end

function onEnemySpawned(bot)

	-- We're probably about to fight so make sure player can see health
	-- Show the player's health after a small delay
	game_manager:startTimer(0.5, tryToShowPlayerHealth)

end

function nextLevel()

	-- Fade out to white
	hud:doScreenFade(ccc4(255,255,255,255), 0.5)

	if (level_manager:isLastLevel() == false) then

		-- Then go to next level
--		game_manager:startTimer(0.6, function() level_manager:nextLevel() end)

		-- Stage complete!
		game_manager:onStageComplete()

	else

		game_manager:startTimer(0.6, function() onDemoEnd() end)

	end

	return true

end

function onDemoEnd()

	if (player:isAlive()) then
		disconnectControls()
		game_manager:setDemoCompleted()	
	end

	return true
end

function talkToFist() player:doActionByName("TalkToFist") end
function talkToFistScared() player:doActionByName("TalkToFistScared") end
function talkToFistAngry() player:doActionByName("TalkToFistAngry") end
function fistTalk() player:doActionByName("FistTalk") end
function fistGoesAway() player:doActionByName("FistGoesAway") end
function eatHand() player:doActionByName("EatHand") end
function eatHandReverse() player:doActionByName("EatHandReverse") end
function concerned() player:doActionByName("Concerned") end
function relaxedWithFist() player:doActionByName("RelaxedWithFist") end

function disconnectControls(enable_cinemascope)

	if (enable_cinemascope == nil) then
		enable_cinemascope = true
	end

	player:disconnectInputSignals() 
	player:doActionByName("Relaxed")

	if (enable_cinemascope == true) then
		hud:enableCinemascope()
	end

	-- Hide the player's health now
	hud:hidePlayerHealth()

	-- Hide the enemy health now
	hud:hideEnemyHealth()

end

function connectControls(showGo, showHealth)

	if (showHealth == nil) then
		showHealth = true
	end

	player:connectInputSignals()

	-- Remove any cutscene animations
	player:resetAnimation()

	-- Never want to be in CINEMASCOPE when player can move
	hud:disableCinemascope()

	if (showHealth) then
		-- Show the player's health after a small delay
		game_manager:startTimer(0.5, tryToShowPlayerHealth)
	end

	if (showGo ~= false) then
		showGO();
	end
end

function tryToShowPlayerHealth()

	if (player:isAlive() and 
		hud:isCinemascopeActive() == false and
		bot_manager:getNumActiveBots() > 0) then
		hud:showPlayerHealth(player)
	end
end

function disconnectControlsAndPauseBots()

	disconnectControls()
	bot_manager:pause()

end

function connectControlsAndResumeBots(bShowGo)

	if (bShowGo == nil) then
		bShowGo = false
	end

	connectControls(bShowGo)
	bot_manager:resume()

end

function boundingBox(node)

	local content_size = node:getContentSize()
	local rect = CCRectMake(0, 0, content_size.width, content_size.height)

	local nodeToWorld = node:nodeToWorldTransform()

	local backdrop = game_manager.Background
	local worldToMain = backdrop:getMainLayer():worldToNodeTransform()

	rect = CCRectApplyAffineTransform(rect, nodeToWorld)
	rect = CCRectApplyAffineTransform(rect, worldToMain)

	return rect

end

function localize(stringID)
	return LocaleManager:sharedLocaleManager():localize(stringID)
end

-- Common handling of arena-based FistTrigger events
function common_arena_onTrigger(name, args)

    local player = game_manager.Player
    local backdrop = game_manager.Background
	local handled = true

	if (name == "onLoad") then

		-- Use full controls...
		player:connectInputSignals();

		-- Fade in from white
		hud:doScreenFade(ccc4(255,255,255,255), 0)
		hud:doScreenFade(ccc4(0,0,0,0), 0.5)

		game_manager:startTimer(1, "doDisplayLocation", false);
		game_manager:startTimer(4, "ambush", false);

		bot_manager.MaxBotsOnScreen = 1;

		-- Restart from here
		game_manager:setCheckpoint("onLoad");

	else

		handled = false

	end

	return handled
end

-- Common handling of FistTrigger events
function common_onTrigger(name, args)

    local player = game_manager.Player
    local backdrop = game_manager.Background
	
	local handled = true
	
	-- BEAR FIGHT! Stuff
    if (name == "showBearFight") then
		showBearFight(args);
	elseif (name == "hideBearFight") then
		hud:hideBearFight();

	-- Camera block stuff
	elseif (name == "startCameraBlock") then
		startCameraBlock();
	elseif (name == "stopCameraBlock") then
		stopCameraBlock();

	-- GO! Hud thing
	elseif (name == "showGO") then
		showGO();
	elseif (name == "hideGO") then
		hud:hideGO();

	-- Talking stuff
    elseif (name == "doFistTalk") then
    	if (player.InputConnected == false) then
			player:doActionByName("FistTalk");
		end
    elseif (name == "doTalkToFist") then
    	if (player.InputConnected == false) then
			player:doActionByName("TalkToFist");
		end

	elseif (name =="blockTillAllBotDeaths") then
		-- Is this the last active bot?
		if (bot_manager:getNumActiveBots() == 1 and bot_manager:getNumQueuedBots() == 0) then
			stopCameraBlock();
		end

	elseif (name == "startPlayerControls") then
		startPlayerControls();
	elseif (name == "stopPlayerControls") then
		player:disconnectInputSignals();

	elseif (name == "onQuitToTitleScreen") then

		game_manager:quitToTitleScreen();

    else

        handled = false

	end
	
	return handled
	
end
