--
-- CrabSteeringAttacher
-- Specialization to block crab steering animation if back attachment is not unfolded

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


CrabSteeringAttacher = {}
CrabSteeringAttacher.MOD_NAME = g_currentModName

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

function CrabSteeringAttacher.registerFunctions(vehicleType)
end

function CrabSteeringAttacher.registerOverwrittenFunctions(vehicleType)
end

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

---Called on loading
-- @param table savegame savegame
-- @includeCode
function CrabSteeringAttacher:onLoad(savegame)
    self.spec_crabSteeringAttacher = self[string.format("spec_%s.crabSteeringAttacher", CrabSteeringAttacher.MOD_NAME)]
    local spec = self.spec_crabSteeringAttacher
    local specCrabSteering = self.spec_crabSteering

    local baseKey = "vehicle.crabSteering"

    spec.blockedAnimations = {}
    spec.playWhileFoldingAnims = {}
    local i = 0
    while true do
        local key = string.format("%s.steeringMode(%d)", baseKey, i)
        if not hasXMLProperty(self.xmlFile, key) then
            break
        end

        local j = 0
        while true do
            local animKey = string.format("%s.animation(%d)", key, j)
            if not hasXMLProperty(self.xmlFile, animKey) then
                break
            end

            local steeringMode = specCrabSteering.steeringModes[i+1]
            if steeringMode ~= nil then
                local animation = steeringMode.animations[j+1]
                if animation ~= nil then
                    animation.allowWhileToolFolded = Utils.getNoNil(getXMLBool(self.xmlFile, animKey .. "#allowWhileToolFolded"), true)
                    if not animation.allowWhileToolFolded then
                        table.insert(spec.blockedAnimations, animation)
                    end

                    animation.playWhileToolFolding = Utils.getNoNil(getXMLBool(self.xmlFile, animKey .. "#playWhileToolFolding"), false)
                    if animation.playWhileToolFolding then
                        table.insert(spec.playWhileFoldingAnims, animation)
                    end
                end
            end

            j = j + 1
        end

        i = i + 1
    end
end


function CrabSteeringAttacher:onUpdateTick(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
    local implements = self:getAttachedImplements()
    for _, implement in ipairs(implements) do
        if implement.object ~= nil then
            if implement.object.spec_foldable ~= nil then
                local spec = self.spec_crabSteeringAttacher
                if not implement.object:getIsUnfolded() then
                    for _, blockAnimation in ipairs(spec.blockedAnimations) do
                        if blockAnimation.animNameBack == nil then
                            blockAnimation.animNameBack = blockAnimation.animName
                            blockAnimation.animName = nil
                        end
                    end

                    for _, anim in ipairs(spec.playWhileFoldingAnims) do
                        if not anim.played then
                            anim.played = true

                            self:setAnimationTime(anim.animName, 0.5, false)
                            local curTime = self:getAnimationTime(anim.animName)
                            if anim.stopTime ~= nil then
                                self:setAnimationStopTime(anim.animName, anim.stopTime)
                                local speed = 1.0
                                if curTime > anim.stopTime then
                                    speed = -1.0
                                end
                                self:playAnimation(anim.animName, speed, curTime, true)
                            else
                                self:playAnimation(anim.animName, anim.animSpeed, curTime, true)
                            end
                        end
                    end

                    local specCrabSteering = self.spec_crabSteering
                    local currentMode = specCrabSteering.steeringModes[specCrabSteering.state]
                    if currentMode.animations ~= nil then
                        for _, anim in ipairs(currentMode.animations) do
                            if anim.reversePlayed then
                                anim.reversePlayed = false
                            end
                        end
                    end
                else
                    for _, blockAnimation in ipairs(spec.blockedAnimations) do
                        if blockAnimation.animNameBack ~= nil then
                            blockAnimation.animName = blockAnimation.animNameBack
                            blockAnimation.animNameBack = nil
                        end
                    end

                    for _, anim in ipairs(spec.playWhileFoldingAnims) do
                        if anim.played then
                            anim.played = false
                        end
                    end

                    local specCrabSteering = self.spec_crabSteering
                    local currentMode = specCrabSteering.steeringModes[specCrabSteering.state]
                    if currentMode.animations ~= nil then
                        for _, anim in ipairs(currentMode.animations) do
                            if not anim.reversePlayed then
                                anim.reversePlayed = true

                                self:setAnimationTime(anim.animName, 0.5, false)
                                local curTime = self:getAnimationTime(anim.animName)
                                if anim.stopTime ~= nil then
                                    self:setAnimationStopTime(anim.animName, anim.stopTime)
                                    local speed = 1.0
                                    if curTime > anim.stopTime then
                                        speed = -1.0
                                    end
                                    self:playAnimation(anim.animName, speed, curTime, true)
                                else
                                    self:playAnimation(anim.animName, anim.animSpeed, curTime, true)
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end
