#include "script/include/common.lua"
#include "player_locomotion.lua"
#include "player_characters.lua"
#include "ui/debug.lua"

------------------------------------------------------------------------
DEFAULT_CHARACTER_ID = "sven_lagom"
character = {}
character.id = ""
character.animator = 0
character.shapes = {}
character.entities = {}
character.toolOffset = Vec(0, 0, 0)
gDeploy = nil


function spawnPlayer(character_id)
	for i=1, #character.entities do
		Delete(character.entities[i])
	end
    character.id = ""
    character.animator = 0
    character.shapes = {}
    character.entities = {}
    character.toolOffset = Vec(0, 0, 0)

    if gPlayerCharacters[character_id] ~= nil then
        local characterPath = gPlayerCharacters[character_id].path

	    local tm = GetPlayerTransform()
	    character.entities = Spawn(characterPath, tm)
	    --character.entities = SpawnLayer(characterPath, "default", tm)
	    character.shapes = {}
	    for e=1, #character.entities do
		    if GetEntityType(character.entities[e]) == "animator" then
			    character.animator = character.entities[e]
		    end
		    if GetEntityType(character.entities[e]) == "shape" and not HasTag(character.entities[e], "proxy") then
			    character.shapes[#character.shapes+1] = character.entities[e]
		    end
	    end
	    SetPlayerAnimator(character.animator)

        locomotion_params.animSpeed  = gPlayerCharacters[character_id].anim_speed
        locomotion_params.charHeight = gPlayerCharacters[character_id].height

        locomotion_init(character.animator)

        character.toolOffset = gPlayerCharacters[character_id].tool_offset
        character.id = character_id
    end
end


function checkPlayerModel()
    local character_id = GetString("game.player.character")
    if gPlayerCharacters[character_id] == nil then
        character_id = DEFAULT_CHARACTER_ID
    end

    if character_id ~= character.id then
        spawnPlayer(character_id)
    end
end


------------------------------------------------------------------------
function init()
    if GetString("game.levelid") == "menu" then
        return
    end

    validateAvailableCharacters()

    gDeploy = GetBool("game.deploy")

    checkPlayerModel()
end

function postUpdate(dt)
    if character.animator ~= 0 then
        locomotion_tick(character.animator, dt)
    end
end

function tick(dt)
    if GetString("game.levelid") == "menu" then
        return
    end

    if not gDeploy and changePlayerCharacter then
        changePlayerCharacter()
    end

    checkPlayerModel()

	--character_setVisibility()
	tick_events()
    SetToolOffset(character.toolOffset)

    if character.animator ~= 0 then
        locomotion_frame_tick(character.animator, dt)
    end
end

function character_setVisibility()
	local visible = (GetPlayerVehicle() ~= 0 or GetBool("game.thirdperson"))
	if (GetPlayerVehicle() ~= 0 and GetBool("game.camera.mode.drive")) then
        visible = false
    end

    local dead = not animState.alive
    for i=1,#character.shapes do
        local character_shape = character.shapes[i]

	    --if visible or dead or (HasTag(b, "neck")==false and HasTag(b, "head")==false) then
	    if visible or dead then
		    RemoveTag(character_shape, "invisible")
	    else
		    SetTag(character_shape, "invisible")
	    end
    end
end

function character_die()
	animState.alive = false
	MakeRagdoll(character.animator)
end

function character_live()
	animState.alive = true
	UnRagdoll(character.animator)
end

function character_hit(point, imp)
	QueryRequire("animator")
	local hit, _, _, closestShape = QueryClosestPoint(point, 1.0)
	if hit then
		local b = GetShapeBody(closestShape)
		ApplyBodyImpulse(b, point, imp)
	end
end

function tick_events()
	local c = GetEventCount("playerhurt")
	for i=1,c do
		local _victim, _before, after, _attacker = GetEvent("playerhurt", i)
		if after == 0 then
			character_die()
		end
	end

	c = GetEventCount("playerhit")
	for i=1,c do
		local _, point, imp, _ = GetEvent("playerhit", i)
		character_hit(point, imp)
	end

	if GetPlayerHealth() > 0 then
	    character_live()
	end
end
