#Conditional Hooks

$Application: FS2_Open
$On Game Init:
[
debrisGravity = {}

function debrisGravity:init()
	self.gravity = 9.81
	self.enabled = false

	self.ignoredObjects = {}
	self.groundShip = nil
end

function debrisGravity:setGravityValue(val)
	if (type(val) ~= "number") then
		ba.warning("Invalid gravity value type '" .. type(val) .. "'!")
		return
	end

	self.gravity = val
end

function debrisGravity:setEnabled(bool)
	if (type(bool) ~= "boolean") then
		ba.warning("Invalid enabled state variable type '" .. type(val) .. "'!")
		return
	end

	self.enabled = bool
end

function debrisGravity:setGroundShip(ship)
	if (not ship:isValid()) then
		ba.warning("Specified ground ship is not valid!")
		return
	end

	self.groundShip = ship
end

function debrisGravity:isEnabled()
	if (not self.enabled) then
		return false
	end

	return self.gravity ~= 0
end

function debrisGravity:isDisabled(ship)
		-- This needs a special function added to the FSO code but is certainly the better way to do it
		-- return ship.Disabled

		local disabled = true

	local pos = ship.Position

		for i=1, #ship do
				local subsys = ship[i]

				if (subsys:isValid()) then
						local engineIndex = subsys.Name:lower():find("engine")
						if (engineIndex and engineIndex == 1) then -- This is most likely a hack!
								if (subsys.HitpointsLeft > 0) then
										disabled = false
										break
								end
						end
				end
		end

		return disabled
end

function debrisGravity:setIgnored(obj, bool)
	if (not obj or not obj:isValid()) then
		return
	end

	if (bool) then
		self.ignoredObjects[obj:getSignature()] = obj
	else
		self.ignoredObjects[obj:getSignature()] = nil
	end
end

function debrisGravity:isIgnored(obj)
	if (not obj:isValid()) then
		return false
	end

	return self.ignoredObjects[obj:getSignature()] ~= nil
end

function debrisGravity:applyGravity(obj, time)
	if (not obj:isValid()) then
		return
	end

	if (self:isIgnored(obj)) then
		return
	end

		local vec = ba.createVector(0, -1, 0)
		vec = vec * self.gravity * time
		local newVec = obj.Physics.Velocity + vec

		obj.Physics.Velocity = newVec
end

function debrisGravity:onFrame(time)
	if (not self:isEnabled()) then
		return
	end

	for i=1, #mn.Debris do
		local debris = mn.Debris[i]

		self:applyGravity(debris, time)
	end
	
	for i=1, #mn.Weapons do
		local weapon = mn.Weapons[i]
		
		if (weapon.Class.Name == "Angel Flare") or (weapon.Class.Name == "Angel Flare#single") then
			self:applyGravity(weapon, time)
		end
	end

	for i=1, #mn.Ships do
		local ship = mn.Ships[i]

		if (ship.FlagAffectedByGravity) then
			if (ship:hasShipExploded() ~= 0 or self:isDisabled(ship)) then
						self:applyGravity(ship, time)
			end
		end
	end
end

function debrisGravity:onDebrisCollision()
	if (not self.groundShip or not self.groundShip:isValid()) then
		return
	end

	if (hv.Self == self.groundShip) then
		hv.Debris.Physics.Velocity = ba.createVector(0,0,0)
		hv.Debris.Physics.RotationalVelocity = ba.createVector(0,0,0)
		hv.Debris.HitpointsLeft = 0

		self:setIgnored(hv.Debris, true)

		--ba.error("Added debris id " .. tostring(hv.Debris:getSignature()) .. " to ignored objects...")
	end
end

debrisGravity:init()

function g_setG(value)
		if type(value) ~= "number" then
				ba.warning("Invalid type given to g_setG!")
				return
	end

		debrisGravity:setGravityValue(value)
end

function g_enable()
	debrisGravity:setEnabled(true)
end

function g_disable()
	debrisGravity:setEnabled(false)
end

function g_sGr(value)
		local ship = mn.Ships[value]

		if ship == nil or not ship:isValid() then
				ba.warning("Invalid value given to g_sGr! '" .. tostring(value) .. "' is not a valid to identify a ship!")
				return
	end

		debrisGravity:setGroundShip(ship)
end

function g_ign(ship)
		local ship = mn.Ships[value]

		if ship == nil or not ship:isValid() then
				ba.warning("Invalid value given to g_ign! '" .. tostring(value) .. "' is not a valid to identify a ship!")
				return
	end

	debrisGravity:setIgnored(ship, true)
end

function g_nign(ship)
		local ship = mn.Ships[value]

		if ship == nil or not ship:isValid() then
				ba.warning("Invalid value given to g_nign! '" .. tostring(value) .. "' is not a valid to identify a ship!")
				return
	end

	debrisGravity:setIgnored(ship, false)
end
]

$On Debris Collision:
[
debrisGravity:onDebrisCollision()
]

$State: GS_STATE_GAME_PLAY
$On Frame:
[
debrisGravity:onFrame(ba.getFrametime())
]

#End