local BipedalSystem = inherited("BipedalSystem", SystemMap)

function BipedalSystem:new()
	local ms = instance(self)
	return ms
end

function BipedalSystem:wants(ent)
	return (ent.aspects.player_input or ent.aspects.ai_input) and ent.aspects.bipedal_thrust and ent.aspects.movement
end

function BipedalSystem:ent_added(ent)

end

function BipedalSystem:ent_removed(ent)
end

local action_delta = {
	left = {x = -1, y = 0},
	right = {x = 1, y = 0},
	up = {x = 0, y = -1},
	down = {x = 0, y = 1},
}

function BipedalSystem:step(dt)
	for ent, _ in pairs(self.ents) do
		local dx,dy,dz = ent.dx,ent.dy,ent.dz
		local tf = ent.thrust_factor
		local thrust_amount = ent.thrust_amount
		local look_amount = 1

		local knockout_delay = ent.knockout_delay
		if knockout_delay > 0 then
			knockout_delay = knockout_delay - dt - knockout_delay*dt
			ent.knockout_delay = knockout_delay
			local anim = knockout_delay^2*2
			if knockout_delay > 0 then
				ent.angle_override = math.approach(0, ent.knockout_angle, anim*math.pi)
				ent.render_offset_z_factor = math.approach(1, 0.1, anim)
			else
				ent.angle_override = 0
				ent.render_offset_z_factor = 1
			end
			tf = ent.ground_friction or 0
			thrust_amount = 0
			look_amount = 0
			--if ent.aspects.stamina and ent.stamina_recovery then
			--	ent:set_stamina_recovery(false)
			--end
		end
		
		if ent.z <= 0 then
			ent.thrust_target = ent.control_ground
		else
			ent.thrust_target = ent.control_air
		end
		
		local thurst_target = ent.thrust_target
		if tf ~= thurst_target then
			tf = math.approach(math.min(tf,thurst_target), thurst_target, ent.control_recovery_speed*dt)
			look_amount = look_amount*tf
		elseif knockout_delay <= 0 then
			--if ent.aspects.stamina and not ent.stamina_recovery then
			--ent:set_stamina_recovery(true)
			--end
		end


		if thrust_amount ~= 0 or dx ~= 0 or dy ~= 0 then
			local amount = thrust_amount*ent.thrust_max_speed
			local tx = math.cos(ent.thrust_angle)*amount
			local ty = math.sin(ent.thrust_angle)*amount
			local acc = ent.thrust_acceleration
			dx = math.approach(dx, tx, dt*math.abs(dx-tx)*acc*tf + tf*dt*acc)
			dy = math.approach(dy, ty, dt*math.abs(dy-ty)*acc*tf + tf*dt*acc)
			ent:set_speed_2d(dx, dy)
		end

		if ent.angle ~= ent.look_angle and look_amount ~= 0 then
			assert(ent.angle)
			assert(ent.look_angle)
			local new_angle = math.approachAngle(ent.angle, ent.look_angle, math.pi*look_amount*ent.look_speed*dt)
			ent:set_angle(new_angle)
		end

		if ent.any_impact then
			local impact_amount = math.distance(0,0,ent.dx_impact or 0, ent.dy_impact or 0)
			local impact_effect = impact_amount/ent.impact_resistance
			if impact_effect > 0 then
				tf = tf/(1+impact_effect)
				local was = knockout_delay
				if was <= 0 then
					if ent.aspects.stamina then
						local stamina = ent.stamina
						ent:modify_stamina(-impact_effect)
						impact_effect = math.max(0,impact_effect-stamina)
					end
				end
				if impact_effect > 0 then
					ent.knockout_delay = math.max(knockout_delay, impact_effect)
					if was <= 0 and ent.knockout_delay > 0 then
						ent.knockout_angle = math.randomGaussian()*math.pi*0.1 + ((math.random() > 0.5) and math.pi*0.5 or -math.pi*0.5)
					end				
				end
			end
		end
		
		ent.thrust_factor = tf
	end
end

return BipedalSystem