--- Opt-in target point for Thunderbird yarder setup ropes.
-- Add this specialization to another vehicle/object type and set
-- <yarderRopeTarget node="i3dMappingName" radius="0.35" /> in its XML.
YarderRopeTarget = {}
YarderRopeTarget.MOD_NAME = g_currentModName
YarderRopeTarget.SPEC_NAME = g_currentModName .. ".yarderRopeTarget"

function YarderRopeTarget.prerequisitesPresent(specializations)
	return true
end

function YarderRopeTarget.initSpecialization()
	local schema = Vehicle.xmlSchema

	schema:setXMLSpecializationType("YarderRopeTarget")
	schema:register(XMLValueType.NODE_INDEX, "vehicle.yarderRopeTarget#node", "Node the yarder setup rope can connect to")
	schema:register(XMLValueType.NODE_INDEX, "vehicle.yarderRopeTarget#pushNode", "Node the first yarder push rope can connect to", "#node")
	schema:register(XMLValueType.NODE_INDEX, "vehicle.yarderRopeTarget#pushNode02", "Node the second yarder push rope can connect to", "#pushNode")
	schema:register(XMLValueType.FLOAT, "vehicle.yarderRopeTarget#radius", "Validation radius around the rope target node", 0.35)
	schema:register(XMLValueType.VECTOR_ROT, "vehicle.yarderRopeTarget#hookRotation", "Local rotation for hook visuals on this target", "0 0 0")
	schema:register(XMLValueType.VECTOR_TRANS, "vehicle.yarderRopeTarget#hookTranslation", "Local translation for hook visuals on this target", "0 0 0")
	schema:register(XMLValueType.VECTOR_ROT, "vehicle.yarderRopeTarget#blockRotation", "Local rotation for block hook visuals on this target", "#hookRotation")
	schema:register(XMLValueType.VECTOR_TRANS, "vehicle.yarderRopeTarget#blockTranslation", "Local translation for block hook visuals on this target", "#hookTranslation")
	schema:setXMLSpecializationType()
end

function YarderRopeTarget.registerFunctions(vehicleType)
	SpecializationUtil.registerFunction(vehicleType, "getYarderRopeTargetNode", YarderRopeTarget.getYarderRopeTargetNode)
	SpecializationUtil.registerFunction(vehicleType, "getYarderRopeTargetPushNode", YarderRopeTarget.getYarderRopeTargetPushNode)
	SpecializationUtil.registerFunction(vehicleType, "getYarderRopeTargetPushNode02", YarderRopeTarget.getYarderRopeTargetPushNode02)
	SpecializationUtil.registerFunction(vehicleType, "getYarderRopeTargetPosition", YarderRopeTarget.getYarderRopeTargetPosition)
	SpecializationUtil.registerFunction(vehicleType, "getYarderRopeTargetRadius", YarderRopeTarget.getYarderRopeTargetRadius)
	SpecializationUtil.registerFunction(vehicleType, "getYarderRopeTargetHookTransform", YarderRopeTarget.getYarderRopeTargetHookTransform)
	SpecializationUtil.registerFunction(vehicleType, "getYarderRopeTargetBlockTransform", YarderRopeTarget.getYarderRopeTargetBlockTransform)
end

function YarderRopeTarget.registerEventListeners(vehicleType)
	SpecializationUtil.registerEventListener(vehicleType, "onLoad", YarderRopeTarget)
end

function YarderRopeTarget:onLoad(savegame)
	self.spec_yarderRopeTarget = self["spec_" .. YarderRopeTarget.SPEC_NAME]
	local spec = self.spec_yarderRopeTarget

	spec.node = self.xmlFile:getValue("vehicle.yarderRopeTarget#node", nil, self.components, self.i3dMappings)
	spec.pushNode = self.xmlFile:getValue("vehicle.yarderRopeTarget#pushNode", spec.node, self.components, self.i3dMappings)
	spec.pushNode02 = self.xmlFile:getValue("vehicle.yarderRopeTarget#pushNode02", spec.pushNode, self.components, self.i3dMappings)
	spec.radius = self.xmlFile:getValue("vehicle.yarderRopeTarget#radius", 0.35)
	spec.hookTranslation = self.xmlFile:getValue("vehicle.yarderRopeTarget#hookTranslation", {
		0,
		0,
		0
	}, true)
	spec.hookRotation = self.xmlFile:getValue("vehicle.yarderRopeTarget#hookRotation", {
		0,
		0,
		0
	}, true)
	spec.blockTranslation = self.xmlFile:getValue("vehicle.yarderRopeTarget#blockTranslation", spec.hookTranslation, true)
	spec.blockRotation = self.xmlFile:getValue("vehicle.yarderRopeTarget#blockRotation", spec.hookRotation, true)

	if spec.node == nil then
		Logging.xmlWarning(self.xmlFile, "Missing yarderRopeTarget node for '%s'", self.configFileName)
	end
end

function YarderRopeTarget:getYarderRopeTargetNode()
	return self.spec_yarderRopeTarget.node
end

function YarderRopeTarget:getYarderRopeTargetPushNode()
	return self.spec_yarderRopeTarget.pushNode or self.spec_yarderRopeTarget.node
end

function YarderRopeTarget:getYarderRopeTargetPushNode02()
	return self.spec_yarderRopeTarget.pushNode02 or self.spec_yarderRopeTarget.pushNode or self.spec_yarderRopeTarget.node
end

function YarderRopeTarget:getYarderRopeTargetPosition()
	local node = self:getYarderRopeTargetNode()

	if node ~= nil and entityExists(node) then
		return getWorldTranslation(node)
	end

	return getWorldTranslation(self.rootNode)
end

function YarderRopeTarget:getYarderRopeTargetRadius()
	return self.spec_yarderRopeTarget.radius
end

function YarderRopeTarget:getYarderRopeTargetHookTransform()
	local spec = self.spec_yarderRopeTarget
	local translation = spec.hookTranslation or {
		0,
		0,
		0
	}
	local rotation = spec.hookRotation or {
		0,
		0,
		0
	}

	return translation[1], translation[2], translation[3], rotation[1], rotation[2], rotation[3]
end

function YarderRopeTarget:getYarderRopeTargetBlockTransform()
	local spec = self.spec_yarderRopeTarget
	local translation = spec.blockTranslation or spec.hookTranslation or {
		0,
		0,
		0
	}
	local rotation = spec.blockRotation or spec.hookRotation or {
		0,
		0,
		0
	}

	return translation[1], translation[2], translation[3], rotation[1], rotation[2], rotation[3]
end
