local function rot_to_dir(rot)
	local x = -math.cos(rot.x) * math.sin(rot.y)
	local y = math.sin(rot.x)
	local z = math.cos(rot.x) * math.cos(rot.y)
	return {x = x, y = y, z = z}
end

local on_step = function(self, dtime, moveresult)
	local vel = self.object:get_velocity()
	local speed = math.min(vector.length(vel), 20)
	local rot = self.object:get_rotation()
	local driver = minetest.get_player_by_name(self.driver)
	local pos = self.object:get_pos()
	
	--Check Surroundings
	local land = false
	local crash_speed = 0
	if moveresult and moveresult.collisions and moveresult.collides then
		for _,collision in pairs(moveresult.collisions) do
			land = true
			crash_speed = crash_speed+
						  math.abs(collision.old_velocity.x-collision.new_velocity.x)+
						  math.abs(collision.old_velocity.y-collision.new_velocity.y)+
						  math.abs(collision.old_velocity.z-collision.new_velocity.z)
		end
	end
	if minetest.get_node(pos).name~="air" then
		land=true
		crash_speed=6 -- just to trigger crash_damage below
	end
	
	if land then
		driver:set_detach()
		driver:set_eye_offset({x=0,y=0,z=0},{x=0,y=0,z=0})
		driver:add_player_velocity(vel)
		local crash_dammage = math.floor(math.max(crash_speed-5, 0))
		if crash_dammage > 0 then
			local node = minetest.get_node(pos)
			if minetest.registered_nodes[node.name].liquidtype == "none" then
				local hp = driver:get_hp()
				driver:set_hp(hp-crash_dammage, {type = "fall"})
			end
		end
		self.object:remove()
	end
	
	-- Mouse controls not supported here.
	rot.x = rot.x + (-driver:get_look_vertical()-rot.x)*(dtime*2)
	local hor = driver:get_look_horizontal()
	local angle = hor-rot.y
	if angle < -math.pi then angle = angle + math.pi*2 end
	if angle > math.pi then angle = angle - math.pi*2 end
	rot.y = rot.y + angle*(dtime*2)
	speed = speed - math.abs(angle*dtime)
	rot.z = -angle
	
	speed = math.max(speed - (rot.x^3)*4 * dtime, 0.1) -- max to avoid div by zero below
	self.object:set_rotation(rot)
	local dir = rot_to_dir(rot)
	dir = {x = dir.x*speed, y = dir.y*speed-20/speed, z = dir.z*speed}
	self.object:set_velocity(dir)
	--[[
	local ctrl=driver:get_player_control_bits()%32
	if (ctrl>=16) and mfplayers[driver:get_player_name()].energy>0.1 then
		gravity=0
	end
	]]
end




minetest.register_entity("glider:hangglider", {
	physical = true,
	pointable = false,
	visual = "mesh",
	mesh = "glider_hangglider.obj",
	textures = {"glider_hangglider.png"},
	static_save = false,
	--Functions
	on_step = on_step,
	driver = "",
	free_fall = false,
	speed = 0,
})

minetest.register_tool("glider:glider", {
	description = "Glider\nHow to use: run, jump, deploy. Mouse controlled.",
	inventory_image = "glider_glider.png",
	on_use = function(itemstack, user, pt)
		local name = user:get_player_name()
		local pos = user:get_pos()
		if not user:get_attach() then
			pos.y = pos.y + 1.5
			local ent = minetest.add_entity(pos, "glider:hangglider")
			local luaent = ent:get_luaentity()
			luaent.driver = name
			ent:set_rotation{y = user:get_look_horizontal(), x = -user:get_look_vertical(), z = 0}
			local vel = user:get_player_velocity()
			-- For the initial speed we consider vertical speed vel.y is 0, because it is easy to
			-- get a high value.
			vel.y=0
			ent:set_velocity(vel)
			user:set_attach(ent, "", {x=0,y=0,z=-10}, {x=90,y=0,z=0})
			user:set_eye_offset({x=0,y=-16.25,z=0},{x=0,y=-15,z=0})
			itemstack:take_item()
			return itemstack
		end
	end,
})

minetest.register_craftitem("glider:rocket", {
	description = "Rocket (Use while gliding to boost glider speed)",
	inventory_image = "glider_rocket.png",
	on_use = function(itemstack, user, pt)
		local attach = user:get_attach()
		if attach then
			local luaent = attach:get_luaentity()
			if luaent.name == "glider:hangglider" then
				luaent.speed = luaent.speed + 10
				itemstack:take_item()
				minetest.add_particlespawner({
					amount = 1000,
					time = 2,
					minpos = {x = -0.125, y = -0.125, z = -0.125},
					maxpos = {x = 0.125, y = 0.125, z = 0.125},
					minexptime = 0.5,
					maxexptime = 1.5,
					attached = attach,
					texture = "glider_rocket_particle.png",
				})
				return itemstack
			end
		end
	end
})

--[[
minetest.register_craft({
	output = "glider:glider",
	recipe = {
		{"cloth:white_block", "cloth:white_block", "cloth:white_block" },
		{"group:stick","",           "group:stick"},
		{"",           "group:stick",""           },
	}
})

minetest.register_craft({
	output = "glider:rocket 33",
	recipe = {
		{"group:wood","tnt:gunpowder","group:wood"},
		{"group:wood","tnt:gunpowder","group:wood"},
		{"group:wood","tnt:gunpowder","group:wood"},
	}
})
]]
