-- author  igor29381
-- v1.3
-- date  31.10.2019
--
AnimatedPart = {};

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

function AnimatedPart.registerFunctions(vehicleType)
    SpecializationUtil.registerFunction(vehicleType, "setAnimationState", AnimatedPart.setAnimationState);
end;

function AnimatedPart.registerEventListeners(vehicleType)
    SpecializationUtil.registerEventListener(vehicleType, "onLoad", AnimatedPart);
    SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", AnimatedPart);
    SpecializationUtil.registerEventListener(vehicleType, "onReadStream", AnimatedPart);
    SpecializationUtil.registerEventListener(vehicleType, "onWriteStream", AnimatedPart);
	SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", AnimatedPart);
end

function AnimatedPart:onLoad(savegame)
	self.animatedPart = {};
    self.animatedPart.animation = getXMLString(self.xmlFile, "vehicle.animatedPart#animationName");
	self.animatedPart.text = {};
	local startText = getXMLString(self.xmlFile, "vehicle.animatedPart#startText");
	local backText = getXMLString(self.xmlFile, "vehicle.animatedPart#backText");
	self.animatedPart.text[true] = g_i18n:getText(backText);
	self.animatedPart.text[false] = g_i18n:getText(startText);
	local inputActionStr = Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.animatedPart#inputAction"), "TOGGLE_COVER");
	if inputActionStr then
		self.animatedPart.inputAction = InputAction[inputActionStr];
	end;
	self.animatedPart.state = false;
end;

function AnimatedPart:onPostLoad(savegame)
	if savegame then
		local state = Utils.getNoNil(getXMLBool(savegame.xmlFile, string.format("%s.%s.AnimatedPart#state", savegame.key, self.customEnvironment)), false);
		if state then
			self:setAnimationState(state);
		end;
	end;
end;

function AnimatedPart:saveToXMLFile(xmlFile, key, usedModNames)
	setXMLBool(xmlFile, key.."#state", Utils.getNoNil(self.animatedPart.state, false));
end;

function AnimatedPart:onReadStream(streamId, connection)
	if self.animatedPart.animation then
		local state = streamReadBool(streamId);
		self:setAnimationState(state);
	end
end

function AnimatedPart:onWriteStream(streamId, connection)
	if self.animatedPart.animation then
		streamWriteBool(streamId, self.animatedPart.state);
	end;
end;

function AnimatedPart:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
    if self.isClient then
        local spec = self[string.format("spec_%s.AnimatedPart", self.customEnvironment)];
		self:clearActionEventsTable(spec.actionEvents);
        if isActiveForInputIgnoreSelection then
            local _, actionEventId = self:addActionEvent(spec.actionEvents, self.animatedPart.inputAction, self, AnimatedPart.actionEventAnimationState, false, true, false, true);
			g_inputBinding:setActionEventTextPriority(actionEventId, GS_PRIO_HIGH);
            g_inputBinding:setActionEventActive(actionEventId, true);
            AnimatedPart.updateActionText(self);
        end
    end
end

function AnimatedPart.actionEventAnimationState(self, actionName, inputValue, callbackState, isAnalog)
	local state = not self.animatedPart.state;
	if self.isServer then
		self:setAnimationState(state);
		g_server:broadcastEvent(AnimatedPartEvent:new(state, self));
	else
		g_client:getServerConnection():sendEvent(AnimatedPartEvent:new(state, self));
	end;
end;

function AnimatedPart:setAnimationState(state)
    if self.animatedPart.animation then
        self.animatedPart.state = state;
        if state then
            self:playAnimation(self.animatedPart.animation, 1, self:getAnimationTime(self.animatedPart.animation), true);
        else
			self:playAnimation(self.animatedPart.animation, -1, self:getAnimationTime(self.animatedPart.animation), true);
        end;
		AnimatedPart.updateActionText(self);
    end;
end;

function AnimatedPart.updateActionText(self)
    local spec = self[string.format("spec_%s.AnimatedPart", self.customEnvironment)];
    local actionEvent = spec.actionEvents[self.animatedPart.inputAction];
    if actionEvent ~= nil and actionEvent.actionEventId ~= nil then
        local text = self.animatedPart.text[self.animatedPart.state];
        g_inputBinding:setActionEventText(actionEvent.actionEventId, text);
    end;
end;

AnimatedPartEvent = {};
AnimatedPartEvent_mt = Class(AnimatedPartEvent, Event);
InitEventClass(AnimatedPartEvent, "AnimatedPartEvent");

function AnimatedPartEvent:emptyNew()
	local self = Event:new(AnimatedPartEvent_mt);
    return self;
end;

function AnimatedPartEvent:new(state, object)
	local self = AnimatedPartEvent:emptyNew();
	self.state = state;
	self.object = object;
	return self;
end;

function AnimatedPartEvent:readStream(streamId, connection)
	local state = streamReadBool(streamId);
    local object = NetworkUtil.readNodeObject(streamId);
	object:setAnimationState(state);
	if g_server then
		g_server:broadcastEvent(AnimatedPartEvent:new(state, object));
	end;
end;

function AnimatedPartEvent:writeStream(streamId, connection)
	streamWriteBool(streamId, self.state);
	NetworkUtil.writeNodeObject(streamId, self.object);
end;
