-- LUALOCALS < ---------------------------------------------------------
local ipairs, math, minetest, piredo_api, vector
    = ipairs, math, minetest, piredo_api, vector
local math_abs, math_deg, math_pi
    = math.abs, math.deg, math.pi
-- LUALOCALS > ---------------------------------------------------------

local api = piredo_api.get_mod_api()
local modname = minetest.get_current_modname()

minetest.register_on_joinplayer(function(player)
		player:set_nametag_attributes({
				text = " ",
				color = {a = 0, r = 0, g = 0, b = 0}
			})
		player:set_properties({
				visual = "mesh",
				visual_size = {x = 0.9, y = 0.9, z = 0.9},
				mesh = modname .. "_model.b3d",
				textures = {modname .. "_skin.png"}
			})
	end)

local anims = {
	stand = {x = 0, y = 0},
	walk = {x = 3, y = 27},
	walk_mine = {x = 28, y = 52},
	mine = {x = 53, y = 77},
}

local pitch_mult = 2/3
local pitch_max = 60
local pitch_min = -15
local pitch_precision = 1

local getdata = api.create_player_data()

function api.player_hand_movement(player)
	getdata(player).handtime = 0.3
end

local function boneprop(vec)
	return {vec = vec, absolute = false, interpolation = 0.5}
end
local function setbonepos(player, bone, pos, rot)
	if player.set_bone_override then
		rot = vector.multiply(rot, math_pi / 180)
		return player:set_bone_override(bone, {
				position = boneprop(pos),
				rotation = boneprop(rot),
			})
	end
	return player:set_bone_position(bone, pos, rot)
end

local function step(player, data, dtime)
	local pitch = -math_deg(player:get_look_vertical()) * pitch_mult
	if pitch < pitch_min then pitch = pitch_min end
	if pitch > pitch_max then pitch = pitch_max end
	if not (data.headpitch and math_abs(data.headpitch - pitch)
		< pitch_precision) then
		data.headpitch = pitch
		setbonepos(player, "Head",
			{x = 0, y = 1/2, z = -pitch / 45},
			{x = pitch, y = 0, z = 0}
		)
	end

	local digging = data.handtime
	data.handtime = digging and (digging > dtime) and (digging - dtime) or nil

	local function setanim(anim)
		anim.speed = 48
		if data.anim and data.anim.x == anim.x
		and data.anim.y == anim.y
		and data.anim.speed == anim.speed then return end
		player:set_animation(anim, anim.speed, 0.1)
	end
	local control = player:get_player_control()
	local walking = player:get_physics_override().speed ~= 0
	and (control.up or control.down or control.left or control.right)
	if walking then
		if digging then
			return setanim(anims.walk_mine)
		else
			return setanim(anims.walk)
		end
	elseif digging then
		return setanim(anims.mine)
	end
	return setanim(anims.stand)
end

minetest.register_globalstep(function(dtime)
		for _, player in ipairs(minetest.get_connected_players()) do
			step(player, getdata(player), dtime)
		end
	end)
