#include "script/common.lua"
--constructors for main body and wings

function initBody(tailTable) --constructs the main body
	distance = 0 -- for distance between body units	
	--initialize tails
	for i=1, #tailTable, 1 do
	--great big table for tails, with bodyname, Transform, targetPos, targetRot, etc
		tailTable[i] = {body = tailTable[i]} --puts the handle in .body in a subtable
		tailTable[i].transform = GetBodyTransform(tailTable[i].body)
		tailTable[i].targetPos = VecAdd(tailTable[i].transform.pos, Vec(0,0,0)) --targetPos
		tailTable[i].targetRot = QuatEuler() --targetRot
		tailTable[i].vel = Vec()--tailVel if you will
		tailTable[i].armored = false --if any shape tagged "armor" is found set to true and run armor routine
		tailTable[i].armor = 0 --armor value
		tailTable[i].armorBroken = false --armor break state
		initArmor(tailTable[i])
		if HasTag(tailTable[i].body, "clavicle") then clavicleNum = i end --typically the first winged segment, to use for animation needs. only 1 can be tagged
	end
	
	return tailTable
end
function initArmor(unit)--initializes armor, use in initBody
	local armorList = GetBodyShapes(unit.body)
	local armorVox = 0
	local mainShapes = {}
	for i=#armorList,1,-1 do
		if HasTag(armorList[i],"statelight") or HasTag(armorList[i],"mainshape") then
			table.insert(mainShapes,armorList[i])
		end
		if not HasTag(armorList[i],"armor") then 
			table.remove(armorList,i) 
		elseif HasTag(armorList[i],"armor") then
			armorVox = armorVox + GetShapeVoxelCount(armorList[i]) --add voxels
		end
	end
	if armorVox > 0 then --has armor
		unit.armored = true
		unit.armor = armorVox
	end
	if unit.armored then
		for i,shape in ipairs(mainShapes) do
			SetTag(shape,"unbreakable") --armor protection
		end
	end
end

function initLeftWings(leftWingTable) --leaving open asymmetry as a possibility
	for w=1, #leftWingTable do
		leftWingTable[w] = {body = leftWingTable[w]}
		leftWingTable[w].tailNum = tonumber(GetTagValue(leftWingTable[w].body,"tailNum"))--the tail unit number the wing attaches to
		leftWingTable[w].transform = TransformToLocalTransform(tailTable[leftWingTable[w].tailNum].transform,GetBodyTransform(leftWingTable[w].body))
		--wing must be carefully aligned with intended tail unit
		--default offset (patrol) vec for wing placement
		leftWingTable[w].offset = VecCopy(leftWingTable[w].transform.pos)
		
		--default wingsweep (patrol) quat
		local leftSweep = GetTagValue(leftWingTable[w].body,"sweep") --offset tag in the wing body in editor
		leftWingTable[w].sweep = tagToVec(leftSweep)
		leftWingTable[w].sweep = QuatEuler(leftWingTable[w].sweep[1],leftWingTable[w].sweep[2],leftWingTable[w].sweep[3])
		leftWingTable[w].hoverpivot = tonumber(GetTagValue(leftWingTable[w].body,"hoverpivot"))
		leftWingTable[w].fasthedral = tonumber(GetTagValue(leftWingTable[w].body,"fasthedral")) or 0
		
		leftWingTable[w].targetPos = VecCopy(leftWingTable[w].transform.pos) --targetPos for anim
		leftWingTable[w].targetRot = QuatEuler(0,0,0) --targetRot for anim
	end
	return leftWingTable
end

function initRightWings(rightWingTable) --leaving open asymmetry as a possibility
	for w=1, #rightWingTable do
		rightWingTable[w] = {body = rightWingTable[w]}
		rightWingTable[w].tailNum = tonumber(GetTagValue(rightWingTable[w].body,"tailNum"))
		rightWingTable[w].transform = TransformToLocalTransform(tailTable[rightWingTable[w].tailNum].transform,GetBodyTransform(rightWingTable[w].body))
		--default offset (patrol) vec for wing placement
		rightWingTable[w].offset = VecCopy(rightWingTable[w].transform.pos)

		--default wingsweep (patrol) quat
		rightSweep = GetTagValue(rightWingTable[w].body,"sweep") --offset tag in the wing body in editor
		rightWingTable[w].sweep = tagToVec(rightSweep)
		rightWingTable[w].sweep = QuatEuler(rightWingTable[w].sweep[1],rightWingTable[w].sweep[2],rightWingTable[w].sweep[3]) --quat is just radians
		rightWingTable[w].hoverpivot = tonumber(GetTagValue(rightWingTable[w].body,"hoverpivot"))
		rightWingTable[w].fasthedral = tonumber(GetTagValue(rightWingTable[w].body,"fasthedral")) or 0
		
		rightWingTable[w].targetPos = VecCopy(rightWingTable[w].transform.pos) --targetPos for anim
		rightWingTable[w].targetRot = QuatEuler(0,0,0) --targetRot for anim
	end
	return rightWingTable
end

function initParticleColors() --for particles
	local cordium = GetTagValue(particleSettings,"engineparticles")
	cordium = tagToVec(cordium)
	cordiumR = cordium[1] or 1
	cordiumG = cordium[2] or 0.55
	cordiumB = cordium[3] or 0.3
	
	local railtrail = tagToVec(GetTagValue(particleSettings,"railparticles"))
	railtrailR = railtrail[1] or 1
	railtrailG = railtrail[2] or 0.55
	railtrailB = railtrail[3] or 0.3
	local shockring = tagToVec(GetTagValue(particleSettings,"shockring"))
	shockringR = shockring[1] or 0.3
	shockringG = shockring[2] or 0.4
	shockringB = shockring[3] or 1
	
	local nuketrail = tagToVec(GetTagValue(particleSettings,"nuketrail"))
	nuketrailR = nuketrail[1] or 1
	nuketrailG = nuketrail[2] or 0.66
	nuketrailB = nuketrail[3] or 0.1
end

function initSearchlightColors() --freely colorable searchlight
	--default idle light is blue
	local idlelight = tagToVec(GetTagValue(particleSettings,"idlelight"))
	idlelightR = idlelight[1] or 0.2 --hijacking particleSettings to avoid adding more location tags
	idlelightG = idlelight[2] or 0.83
	idlelightB = idlelight[3] or 1
	--default alert light is red
	local alertlight = tagToVec(GetTagValue(particleSettings,"alertlight"))
	alertlightR = alertlight[1] or 1 
	alertlightG = alertlight[2] or 0
	alertlightB = alertlight[3] or 0
end



function getStateLights() --proxy for health
	local stateLights = {}
	for i, body in ipairs(tailTable) do --get a body from the tail (body) table minus head
		local shapes = GetBodyShapes(body.body)
		for s, shape in ipairs(shapes) do
			if HasTag(shape,"statelight") and not IsShapeBroken(shape) then --looking for specific tag and unbroken
				table.insert(stateLights,shape)
			end
		end

	end
	return #stateLights
end

function getWingThrusters() --engine status for wings
	--get all thrusters
	local allThrusterCount = 0
	
	--wingtip light trigger
	for w, wing in ipairs(leftWingTable) do --for all left wings
		local thrustersLeft = {}
		local shapelist = GetBodyShapes(wing.body)
		for s, shape in ipairs(shapelist) do --to get the shapes tagged as thrustercore
			if HasTag(shape,"thrustercore") and not IsShapeBroken(shape) then
				table.insert(thrustersLeft,shape)
			end
		end
		allThrusterCount = allThrusterCount+#thrustersLeft
		if #thrustersLeft <=0 then
			for s, shape in ipairs(shapelist) do
				SetShapeEmissiveScale(shape,0.07)
			end
		end
	end
	for w, wing in ipairs(rightWingTable) do --for all right wings
		local thrustersLeft = {}
		local shapelist = GetBodyShapes(wing.body)
		for s, shape in ipairs(shapelist) do --to get the shapes tagged as thrustercore
			if HasTag(shape,"thrustercore") and not IsShapeBroken(shape) then
				table.insert(thrustersLeft,shape)
			end
		end 
		allThrusterCount = allThrusterCount+#thrustersLeft
		if #thrustersLeft <=0 then
			for s, shape in ipairs(shapelist) do
				SetShapeEmissiveScale(shape,0.07)
			end
		end
	end
	--DebugPrint(allThrusterCount)
	return allThrusterCount
end

function getArmorState(unit) --do not call on its own
	local unit = unit.body
	local count = 0
	local shapes = GetBodyShapes(unit)
	for s,t in ipairs(shapes) do
		if HasTag(t,"armor") then count = count + GetShapeVoxelCount(t) end
	end
	return count
end
function armorState() --function to run in main script
	for t,tail in ipairs(tailTable) do
		if tail.armored then
			tail.armor = getArmorState(tail)
			if tail.armor <= 300 and not tail.armorBroken then
				tail.armorBroken = true
				armorBroken(tail)
			end
		end
	end
end
function armorBroken(unit)-- armor break function
	unit = unit.body
	local shapes = GetBodyShapes(unit)
	for i=#shapes,1,-1 do
		local shape = shapes[i]
		if HasTag(shape,"mainshape") or HasTag(shape,"statelight") then
			RemoveTag(shape,"unbreakable") --render breakable
		end
	end
end

function makeBodyUnbreakable()
	for i, body in ipairs(tailTable) do
		if not HasTag(body.body, "unbreakable") then
			SetTag(body.body, "unbreakable")
		end
	end
end
function makeWingsUnbreakable()
	for w, wing in ipairs(leftWingTable) do
		if not HasTag(wing.body, "unbreakable") then
			SetTag(wing.body,"unbreakable")
		end
	end
	for w, wing in ipairs(rightWingTable) do
		if not HasTag(wing.body, "unbreakable") then
			SetTag(wing.body,"unbreakable")
		end
	end
end
function makeBodyBreakable()
	for i,body in ipairs(tailTable) do
		if HasTag(body.body,"unbreakable") then
			RemoveTag(body.body,"unbreakable")
		end
	end
end
function makeWingsBreakable()
	for w, wing in ipairs(leftWingTable) do
		if HasTag(wing.body, "unbreakable") then
			RemoveTag(wing.body,"unbreakable")
		end
	end
	for w, wing in ipairs(rightWingTable) do
		if HasTag(wing.body, "unbreakable") then
			RemoveTag(wing.body,"unbreakable")
		end
	end
end

function forceStaticBatch() --because ram attack kinda broke in i think 0.8.0
	local bodies = FindBodies("flyerfp")
	for b,body in ipairs(bodies) do
		SetBodyDynamic(body,false)
	end
end