--
-- ExtendedDynamicMountAttacher
--
-- @author  Stefan Maurus
-- @date  18/07/2019
--
-- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.

---Specialization to set the position of the cutter correctly on the cutter trailer
-- @category Specializations
ExtendedDynamicMountAttacher = {}

---Checks if all prerequisite specializations are loaded
-- @param table specializations specializations
-- @return boolean hasPrerequisite true if all prerequisite specializations are loaded
-- @includeCode
function ExtendedDynamicMountAttacher.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(DynamicMountAttacher, specializations)
end

function ExtendedDynamicMountAttacher.registerFunctions(vehicleType)
end

function ExtendedDynamicMountAttacher.registerOverwrittenFunctions(vehicleType)
    SpecializationUtil.registerOverwrittenFunction(vehicleType, "addDynamicMountedObject",     ExtendedDynamicMountAttacher.addDynamicMountedObject)
end

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

---
-- @includeCode
function ExtendedDynamicMountAttacher:onLoad(savegame)
    local spec = self.spec_dynamicMountAttacher

    spec.fixedPositions = {}

    local i = 0
    while true do
        local posKey = string.format("vehicle.dynamicMountAttacher.fixedPosition(%d)", i)
        if not hasXMLProperty(self.xmlFile, posKey) then
            break
        end

        local entry = {}
        entry.xmlFilename = getXMLString(self.xmlFile, posKey .. "#xmlFilename")
        entry.jointNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, posKey .. "#jointNode"), self.i3dMappings)

        if entry.xmlFilename ~= nil and entry.jointNode ~= nil then
            table.insert(spec.fixedPositions, entry)
        else
            g_logManager:xmlWarning(self.configFileName, "Could not load fixed position from '%s'", posKey)
        end

        i = i + 1
    end
end

---
-- @includeCode
function ExtendedDynamicMountAttacher:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
    if self.isServer then
        if self:getAllowDynamicMountObjects() then
            local spec = self.spec_dynamicMountAttacher
            if next(spec.pendingDynamicMountObjects) ~= nil then
                self:raiseActive()
            end
        end
    end
end

---
-- @includeCode
function ExtendedDynamicMountAttacher:addDynamicMountedObject(superFunc, object)
    local spec = self.spec_dynamicMountAttacher

    if spec.dynamicMountedObjects[object] == nil then
        superFunc(self, object)

        for i=1, #spec.fixedPositions do
            local position = spec.fixedPositions[i]
            if StringUtil.endsWith(object.configFileName, position.xmlFilename) then
                if object.dynamicMountJointIndex ~= nil then
                    removeJoint(object.dynamicMountJointIndex)
                    object.dynamicMountJointIndex = nil
                    object.dynamicMountObjectActorId = nil
                    object.dynamicMountObject = nil
                end

                local x, y, z = getWorldTranslation(position.jointNode)
                local rx, ry, rz = getWorldRotation(position.jointNode)

                object:removeFromPhysics()
                spec.pendingDynamicMountObjects[object] = nil -- will be readded on addToPhysics

                object:setWorldPosition(x, y, z, rx, ry, rz, 1, true)
                object:addToPhysics()

                local trigger = spec.dynamicMountAttacherTrigger

                local couldMount = object:mountDynamic(self, trigger.rootNode, trigger.jointNode, trigger.mountType, trigger.forceAcceleration)
                if not couldMount then
                    self:removeDynamicMountedObject(object, false)
                end
            end
        end
    else
        superFunc(self, object)
    end
end
