-- by modelleicher
-- www.schwabenmodding.de
-- date: 22.07.2017
-- logSplitter animation 

-- animationName -> name of the animation
-- speed -> speed the animation will be played at
-- sharedAnimation -> set to true if animation will also be played from other scripts. That way the script will check position of animation first so you don't have to press key twice
-- l10nName -> optional, if left out l10n Text name is "togglelogSplitter" 

-- <logSplitter animationName="" speed="" startState="" triggerIndex="" sharedAnimation="" l10nName="" />

-- FS19 conversion, 17.12.2018
-- final fixes, 16.06.2019

logSplitter = {}

function logSplitter.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations)
end

function logSplitter.registerEventListeners(vehicleType)
	SpecializationUtil.registerEventListener(vehicleType, "onLoad", logSplitter)
	SpecializationUtil.registerEventListener(vehicleType, "onUpdate", logSplitter)
	SpecializationUtil.registerEventListener(vehicleType, "onDelete", logSplitter)
end

function logSplitter:TOGGLE_SPLITTING()
	self.spec_logSplitter.isPressed = true
end

function logSplitter:onLoad(savegame)
	self.spec_logSplitter = {}
	local spec = self.spec_logSplitter


    self.setlogSplitter = logSplitter.setlogSplitter
    self.turnOnLogSplitter = logSplitter.turnOnLogSplitter
    self.playSplitSound = logSplitter.playSplitSound
    self.logSplitterTrigger = logSplitter.logSplitterTrigger
    self.logSplitterSplitShapesTrigger = logSplitter.logSplitterSplitShapesTrigger
    self.logSplitterSplitShapeCallback = logSplitter.logSplitterSplitShapeCallback
    
    spec.animationName = getXMLString(self.xmlFile.handle, "vehicle.logSplitter#animationName")
    spec.animationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile.handle, "vehicle.logSplitter#speed"), 1)
    spec.trigger = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile.handle, "vehicle.logSplitter#triggerIndex"))
    spec.sharedAnimation = Utils.getNoNil(getXMLBool(self.xmlFile.handle, "vehicle.logSplitter#sharedAnimation"), false)
    
    spec.l10nName = Utils.getNoNil(getXMLString(self.xmlFile.handle, "vehicle.logSplitter#l10nName"),"TOGGLE_logSplitter" )

    spec.currentState = false -- always use currentState of the animation not wanted state for less confusion
    
    -- reset animation during load
    if spec.sharedAnimation == false then
        self:playAnimation(spec.animationName, -spec.animationSpeed, self:getAnimationTime(spec.animationName), true)
    end
    
    spec.playerInTrigger = false
    
    addTrigger(spec.trigger, "logSplitterTrigger", self)    
    
    
    -- log splitter splitting stuff
    spec.splitShapesTrigger = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile.handle, "vehicle.logSplitter.splitter#splitShapesTrigger"))
    addTrigger(spec.splitShapesTrigger, "logSplitterSplitShapesTrigger", self)    
    
    spec.cutNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile.handle, "vehicle.logSplitter.splitter#cutNode"))
    spec.cutNodeRef1 = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile.handle, "vehicle.logSplitter.splitter#cutNodeRef1"))
    spec.cutNodeRef2 = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile.handle, "vehicle.logSplitter.splitter#cutNodeRef2"))
    
    spec.lastSplitShape = nil
    
    spec.lastSplitShapeSplitted = nil
    
    spec.isTurnedOn = false
    spec.isKeyPressedState = false
    spec.hasSplit = false
    spec.lastTime = 0
	
	spec.actionEvents = {}
    
	spec.isPressed = false
	
	spec.debug = false
	
	if self.isClient then
		spec.samples = {}
		spec.samples.work = g_soundManager:loadSampleFromXML(self.xmlFile.handle, "vehicle.logSplitter.sounds", "work", self.baseDirectory, self.components, 0, AudioGroup.VEHICLE, self.i3dMappings, self)
		spec.isWorkSamplePlaying = false
		
		spec.samples.split1 = g_soundManager:loadSampleFromXML(self.xmlFile.handle, "vehicle.logSplitter.sounds", "split1", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self)
		spec.samples.split2 = g_soundManager:loadSampleFromXML(self.xmlFile.handle, "vehicle.logSplitter.sounds", "split2", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self)
		spec.samples.split3 = g_soundManager:loadSampleFromXML(self.xmlFile.handle, "vehicle.logSplitter.sounds", "split3", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self)
		spec.samples.split4 = g_soundManager:loadSampleFromXML(self.xmlFile.handle, "vehicle.logSplitter.sounds", "split4", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self)
		spec.samples.split5 = g_soundManager:loadSampleFromXML(self.xmlFile.handle, "vehicle.logSplitter.sounds", "split5", self.baseDirectory, self.components, 1, AudioGroup.VEHICLE, self.i3dMappings, self)
	end	
  
end


function logSplitter:logSplitterSplitShapesTrigger(triggerId, otherId, onEnter, onLeave, onStay)
    local spec = self.spec_logSplitter
    if onEnter and otherId ~= 0 and g_currentMission.player ~= nil and otherId ~= g_currentMission.player.rootNode and getName(otherId) ~= "PlayerCCT" then
        local splitType = getSplitType(otherId)
        if splitType ~= nil then
            -- found split shape..
            spec.lastSplitShape = otherId
			if spec.debug then
				print("Logsplitter Debug: found splitShape with ID: "..tostring(otherId).." and splitType: "..tostring(splitType))
			end
    
        end
    end
    
end

function logSplitter:logSplitterTrigger(triggerId, otherId, onEnter, onLeave, onStay)
    -- basic player in trigger code
	local spec = self.spec_logSplitter
    if onEnter and g_currentMission.controlPlayer and g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode then
        spec.playerInTrigger = true
		local _, actionEventId = self:addActionEvent(spec.actionEvents, InputAction.TOGGLE_SPLITTING, self, logSplitter.TOGGLE_SPLITTING, false, false, true, true, nil)
    elseif onLeave and g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode then
        spec.playerInTrigger = false
		self:removeActionEvent(spec.actionEvents, InputAction.TOGGLE_SPLITTING)
    end
    
end
function logSplitter:logSplitterSplitShapeCallback(shape, isBelow, isAbove, minY, maxY, minZ, maxZ)

    local spec = self.spec_logSplitter
	
	if spec.debug then	
		print("Logsplitter Debug: SplitShape Callback - SplitShape Attributes: ")
	    print("-shape: "..tostring(shape))
		print("-isBelow, isAbove: "..tostring(isBelow).." - "..tostring(isAbove))
		print("-minY, maxY: "..tostring(minY).." - "..tostring(maxY))
		print("-minZ, maxZ: "..tostring(minZ).." - "..tostring(maxZ))	
	end
	
    spec.lastSplitShapeSplitted = shape
    
    self:playSplitSound()
    
    spec.hasSplit = true
end

function logSplitter:playSplitSound(noEventSend)
	playSplitSoundEvent.sendEvent(self, noEventSend)
	local spec = self.spec_logSplitter
	local random1 = math.random(1, 5)
	if random1 == 1 then
		g_soundManager:playSample(spec.samples.split1, 1)
	elseif random1 == 2 then
		g_soundManager:playSample(spec.samples.split2, 1)
	elseif random1 == 3 then
		g_soundManager:playSample(spec.samples.split3, 1)		
	elseif random1 == 4 then
		g_soundManager:playSample(spec.samples.split4, 1)				
	else
		g_soundManager:playSample(spec.samples.split5, 1)
	end
end

function logSplitter:onUpdate(dt)   

    if self.spec_turnOnVehicle.isTurnedOn then -- check if log splitter is active
		local spec = self.spec_logSplitter
		
        if self.isServer then
            local newTime = self:getAnimationTime(spec.animationName)
            if newTime > 0.5 and newTime > spec.lastTime then -- going forward
                if spec.lastSplitShape ~= nil and entityExists(spec.lastSplitShape) and not spec.hasSplit then
                    
					if spec.debug then
						print("Logsplitter Debug: last Splitshape returned true, start splitting")
					end
                    
                    local x, y, z = getWorldTranslation(spec.cutNode)
                    local nx,ny,nz = localDirectionToWorld(spec.cutNode, 1,0,0)
                    local yx,yy,yz = localDirectionToWorld(spec.cutNode, 0,1.3,0)                    
                    splitShape(spec.lastSplitShape, x,y,z, nx,ny,nz, yx,yy,yz, 1.5, 1.5, "logSplitterSplitShapeCallback", self)    
                    
                end
            else
               spec.hasSplit = false
            end
            spec.lastTime = newTime
        end
		
		if self.isClient then
			if self:getIsAnimationPlaying(spec.animationName) then
				g_soundManager:playSample(spec.samples.work)
			else
				g_soundManager:stopSample(spec.samples.work)
			end
		end
    
        if spec.playerInTrigger then -- check if player is in the trigger
    
            if spec.animationName ~= nil then -- check if the logSplitter has its animation
            
                if spec.isPressed then
                    if not spec.currentState then
                        self:setlogSplitter(true)
                    end
                else
                    if spec.currentState then
                        self:setlogSplitter(false)
                    end
                end    
                
                -- help text
                if g_currentMission.controlPlayer then
                    g_currentMission:addHelpButtonText(g_i18n:getText(spec.l10nName), InputBinding.TOGGLE_logSplitter) 
                end    
            
            end
        end
        
    end
	
	self.spec_logSplitter.isPressed = false
end

function logSplitter:setlogSplitter(wantedState, noEventSend)
    setlogSplitterEvent.sendEvent(self, wantedState, noEventSend)
	local spec = self.spec_logSplitter
    if wantedState then -- if currentState is true (max) then play animation to min
        self:playAnimation(spec.animationName, spec.animationSpeed, self:getAnimationTime(spec.animationName), true)
        spec.currentState = true
    else    
        self:playAnimation(spec.animationName, -spec.animationSpeed, self:getAnimationTime(spec.animationName), true)
        spec.currentState = false
    end
end

function logSplitter:onDelete()
	local spec = self.spec_logSplitter
    if spec.animationName ~= nil then
        removeTrigger(spec.trigger)
    end
	if spec.splitShapesTrigger ~= nil then
		removeTrigger(spec.splitShapesTrigger)
	end
	if self.isClient then
	   g_soundManager:deleteSamples(spec.samples)
	end
end
