-- Top Saw
-- Extension specialization for WoodHarvester (required) to add a second saw
-- Version 1.0.0.0
-- @author Vector Man
-- @date 2022-10-06
-- copyright (c) Vector Man, All Rights Reserved.

source(g_currentModDirectory .. "scripts/TopSawCutTreeEvent.lua")

TopSaw = {
	prerequisitesPresent = function (specializations)
		return SpecializationUtil.hasSpecialization(WoodHarvester, specializations)
	end,
	initSpecialization = function ()
		local schema = Vehicle.xmlSchema

		schema:setXMLSpecializationType("TopSaw")
		schema:register(XMLValueType.NODE_INDEX, "vehicle.woodHarvester.topSaw.cutNode#node", "Cut node")
		schema:register(XMLValueType.FLOAT, "vehicle.woodHarvester.topSaw.cutNode#sizeY", "Size Y", 1)
		schema:register(XMLValueType.FLOAT, "vehicle.woodHarvester.topSaw.cutNode#sizeZ", "Size Z", 1)
		EffectManager.registerEffectXMLPaths(schema, "vehicle.woodHarvester.topSaw.cutEffects")
		schema:register(XMLValueType.STRING, "vehicle.woodHarvester.topSaw.cutAnimation#name", "Cut animation name")
		schema:register(XMLValueType.FLOAT, "vehicle.woodHarvester.topSaw.cutAnimation#speedScale", "Cut animation speed scale")
		schema:register(XMLValueType.FLOAT, "vehicle.woodHarvester.topSaw.cutAnimation#cutTime", "Cut animation cut time")
		schema:setXMLSpecializationType()

		local schemaSavegame = Vehicle.xmlSchemaSavegame
	end,
}
TopSaw.specName = string.format("spec_%s.topSaw", g_currentModName)

function TopSaw.registerFunctions(vehicleType)
	SpecializationUtil.registerFunction(vehicleType, "inputAction_CUT_TOP", TopSaw.inputAction_CUT_TOP)
	SpecializationUtil.registerFunction(vehicleType, "cutTop", TopSaw.cutTop)
end

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

function TopSaw:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
	if self.isClient then
		local spec = self.spec_topSaw
		self:clearActionEventsTable(spec.actionEvents)

		if isActiveForInputIgnoreSelection then
			local actionEventId
			_, actionEventId = self:addActionEvent(spec.actionEvents, "CUT_TOP", self, TopSaw.inputAction_CUT_TOP, false, true, false, true, true, nil )
			g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH)
			g_inputBinding:setActionEventTextVisibility(actionEventId, true)
			g_inputBinding:setActionEventText(actionEventId, g_i18n:getText("input_CUT_TOP"))
			_, actionEventId = InputBinding.registerActionEvent(g_inputBinding, "CUT_TOP", self, TopSaw.inputAction_CUT_TOP, false, true, false, true)
		end
	end
end

function TopSaw:onLoad(savegame)
	
	-- Create spec table in self
    self.spec_topSaw = self[TopSaw.specName]
	local spec = self.spec_topSaw
	
	spec.isCutting = false
	
	local baseKey = "vehicle.woodHarvester.topSaw"
	spec.xmlValues = {
		cutNode = self.xmlFile:getValue(baseKey..".cutNode#node", nil, self.components, self.i3dMappings),
		cutSizeY = self.xmlFile:getValue(baseKey..".cutNode#sizeY", 1),
		cutSizeZ = self.xmlFile:getValue(baseKey..".cutNode#sizeZ", 1),
		cutEffects = g_effectManager:loadEffect(self.xmlFile, "vehicle.woodHarvester.topSaw.cutEffects", self.components, self, self.i3dMappings),
		cutAnimation = {
			name = self.xmlFile:getValue(baseKey..".cutAnimation#name"),
			speedScale = self.xmlFile:getValue(baseKey..".cutAnimation#speedScale", 1),
			cutTime = self.xmlFile:getValue("vehicle.woodHarvester.topSaw.cutAnimation#cutTime", 1)
		}
	}
end

function TopSaw:onUpdate(dt, isActiveForInput, isActiveForInputIgnoreSelection, isSelected)
	local spec = self.spec_topSaw
	local specWoodHarvester = self.spec_woodHarvester
	
	if self:getIsAnimationPlaying(spec.xmlValues.cutAnimation.name) and self.isClient then
		g_effectManager:setFillType(spec.xmlValues.cutEffects, FillType.WOODCHIPS)
		g_effectManager:startEffects(spec.xmlValues.cutEffects)
	elseif self.isClient then
		g_effectManager:stopEffects(spec.xmlValues.cutEffects)
	end
	
	if spec.actionEvents["CUT_TOP"] ~= nil then
		if specWoodHarvester.attachedSplitShape ~= nil and not self:getIsAnimationPlaying(spec.xmlValues.cutAnimation.name) then
			g_inputBinding:setActionEventTextVisibility(spec.actionEvents["CUT_TOP"].actionEventId, true)
		else
			g_inputBinding:setActionEventTextVisibility(spec.actionEvents["CUT_TOP"].actionEventId, false)
		end
	end
	
	if self.isServer and spec.isCutting then
		if self:getAnimationTime(spec.xmlValues.cutAnimation.name) > spec.xmlValues.cutAnimation.cutTime then
			spec.isCutting = false

			removeJoint(specWoodHarvester.attachedSplitShapeJointIndex)
			specWoodHarvester.attachedSplitShapeJointIndex = nil
			
			local x, y, z = getWorldTranslation(spec.xmlValues.cutNode)
			local nx, ny, nz = localDirectionToWorld(spec.xmlValues.cutNode, 1, 0, 0)
			local yx, yy, yz = localDirectionToWorld(spec.xmlValues.cutNode, 0, 1, 0)
			
			local currentSplitShape = specWoodHarvester.attachedSplitShape
			specWoodHarvester.prevSplitShape = currentSplitShape
			
			g_currentMission:removeKnownSplitShape(currentSplitShape)
			
			splitShape(currentSplitShape, x, y, z, nx, ny, nz, yx, yy, yz, spec.xmlValues.cutSizeY, spec.xmlValues.cutSizeZ)
			g_treePlantManager:removingSplitShape(currentSplitShape)
			specWoodHarvester.curSplitShape = nil
			specWoodHarvester.attachedSplitShape = nil
			self:playAnimation(specWoodHarvester.grabAnimation.name, specWoodHarvester.grabAnimation.speedScale, self:getAnimationTime(specWoodHarvester.grabAnimation.name))
		end
	end
end

function TopSaw:cutTop(noEventSend)
	local spec = self.spec_topSaw
	local specWoodHarvester = self.spec_woodHarvester
	
	TopSawCutTreeEvent.sendEvent(self, noEventSend)

	spec.isCutting = true
	specWoodHarvester.hasAttachedSplitShape = false
	
	if self.isServer then
		self:setAnimationTime(spec.xmlValues.cutAnimation.name, 0, true)
		self:playAnimation(spec.xmlValues.cutAnimation.name, spec.xmlValues.cutAnimation.speedScale, self:getAnimationTime(spec.xmlValues.cutAnimation.name))
	end
end

function TopSaw:onDelete()
	local spec = self.spec_topSaw
	g_effectManager:deleteEffects(spec.xmlValues.cutEffects)
end
	
function TopSaw:inputAction_CUT_TOP(actionName, inputValue, callbackState, isAnalog)
	local spec = self.spec_topSaw
	local specWoodHarvester = self.spec_woodHarvester
	
	if specWoodHarvester.hasAttachedSplitShape and not self:getIsAnimationPlaying(spec.xmlValues.cutAnimation.name) then
		self:cutTop()
	end
end