local PLAYER_PHYS_MASS				=	80.0
local PLAYER_PHYS_RADIUS			=	0.40
local PLAYER_PHYS_HEIGHT			=	1.79
local PLAYER_PHYS_JUMPDIST			=	PLAYER_PHYS_RADIUS
local PLAYER_PHYS_JUMPHEIGHT		=	2.0
local PLAYER_PHYS_JUMPSPEEDY 		=	5.0
local PLAYER_PHYS_WALK_SPEED		=	5.5
local PLAYER_PHYS_RUN_SPEED_MUL		=	1.4
local PLAYER_PHYS_MOVE_SPEED_EXP	=	1.0
local PLAYER_PHYS_FLY_SPEED_EXP		=	4.0
local AIR_CONTROL					=	0.2

-- игрок
actor_player = inherit_table(actor_base)

actor_player.m_camera_offset_y = 0.5

function actor_player:on_init()
	actor_base.on_init(self)
	
	g_player = self
	
	self:create_player_body(PLAYER_PHYS_RADIUS, PLAYER_PHYS_HEIGHT - PLAYER_PHYS_RADIUS * 2.0, 80.0, 0.0, 0.0)

	self:activate_camera()

	local ent = engine.create_entity("weapon_ump")
	engine.add_entity_to_world(ent)
	self.m_weapon_entity_id = ent:get_id()

	--engine.play_sound_3d("data/sounds/test/test_music_64Kbps.mp3", 0.0, 0.0, 0.0)
end

function actor_player:on_shutdown()
	actor_base.on_shutdown(self)
	
	g_player = nil
end

function actor_player:on_update(dt)
	actor_base.on_update(self, dt)
	
	self:update_camera_look() -- C++
	--self:update_camera() Lua (for perfomance should call from C++)
	
	--self:update_camera_movement(dt) -- C++ flying mode
	--self:update_body_movement(dt) -- C++
	
	self:update_player_movement(dt)

	local ent = engine.get_entity_from_id(self.m_weapon_entity_id)
	ent:set_relative_position_to_camera(self)

	self:action_update()
end

function actor_player:action_update()
	local action = self:get_action()
	
	local ent = engine.get_entity_from_id(self.m_weapon_entity_id)
	if ent then
		if action == ACTION_FIRE then
			ent:set_state(WEAPON_FSM_STATE_ATTACK)
		elseif action == ACTION_RELOAD then
			ent:set_state(WEAPON_FSM_STATE_RELOAD)
		end
	end
end

function actor_player:update_player_movement(dt)
	local movement = self:get_movement()
	local speed = 4.0
	
	local up_x, up_y, up_z = camera.get_up()
	local front_x, front_y, front_z = camera.get_front()
	
	if not self:is_noclip() then
		front_y = 0.0
	end
	
	local final_front_x, final_front_y, final_front_z = vec3_normalize(front_x, front_y, front_z)
	local cross_x, cross_y, cross_z = vec3_cross(final_front_x, final_front_y, final_front_z,
		up_x, up_y, up_z)
	
	local final_cross_x, final_cross_y, final_cross_z = vec3_normalize(cross_x, cross_y, cross_z)
	
	local dir_x, dir_y, dir_z = 0.0, 0.0, 0.0
	
	if (movement & EMovementDir_Forward) ~= 0 then
		dir_x = dir_x + final_front_x
		dir_y = dir_y + final_front_y
		dir_z = dir_z + final_front_z
	end
	
	if (movement & EMovementDir_Backward) ~= 0 then
		dir_x = dir_x - final_front_x
		dir_y = dir_y - final_front_y
		dir_z = dir_z - final_front_z
	end
	
	if (movement & EMovementDir_Left) ~= 0 then
		dir_x = dir_x - final_cross_x
		dir_y = dir_y - final_cross_y
		dir_z = dir_z - final_cross_z
	end
	
	if (movement & EMovementDir_Right) ~= 0 then
		dir_x = dir_x + final_cross_x
		dir_y = dir_y + final_cross_y
		dir_z = dir_z + final_cross_z
	end
	
	local current_vel_x, current_vel_y, current_vel_z = self:get_velocity()
	
	local vel_x = dir_x * speed
	local vel_y = dir_y * speed
	local vel_z = dir_z * speed

	if self:is_noclip() then
		if (movement & EMovementDir_None) ~= 0 then
			self:set_velocity(vel_x, vel_y, vel_z)
		else
			self:set_velocity(0, 0, 0)
		end
		
		return
	end
	
	if self:on_ground() then
		self:set_velocity(vel_x, current_vel_y, vel_z)
		
		if (movement & EMovementDir_Jump) ~= 0 then
			self:set_velocity(current_vel_x, PLAYER_PHYS_JUMPSPEEDY, current_vel_z)
			--console.print("!!! JUMP")
		end
	else
		local air_vel_x = current_vel_x + dir_x * speed * AIR_CONTROL * dt
		local air_vel_y = current_vel_y + dir_y * speed * AIR_CONTROL * dt
		local air_vel_z = current_vel_z + dir_z * speed * AIR_CONTROL * dt
		self:set_velocity(air_vel_x, current_vel_y, air_vel_z)
	end

	
end

local g_yaw = 0.0
local g_pitch = 0.0

function actor_player:update_camera()
	if not input.get_lock_mouse() then
		return
	end

	local mousePosX, mousePosY = input.get_mouse_pos()
	local sensitivity = 0.15 -- #TODO: input.get_mouse_sensitivity()
	
	g_yaw = g_yaw + (mousePosX * sensitivity)
	g_pitch = g_pitch - (mousePosY * sensitivity)
	
	-- lock axis
	if g_pitch > 89.0 then g_pitch = 89.0 end
	if g_pitch < -89.0 then g_pitch = -89.0 end
	
	camera.set_yaw_pitch(g_yaw, g_pitch)
end

function actor_player:on_collide(other)
	--console.print(string.format("actor_player:on_collide: %s", other:get_classname()))

--	put_debug_string_to_screen(string.format("actor_player:on_collide: %s", other:get_classname()), 4)

	-- FOR TEST
--	other:mark_for_delete()
end

function actor_player:get_health()
	return 100.0
end
