--
-- GaluchoSidesAnim
-- Class for animated drop sides
--
-- @author  PeterJ  - euroDZN
-- @date  23/04/2013
--
-- http://eurodzn.wordpress.com/
--
-- Copyright (C) euroDZN, Confidential, All Rights Reserved.

GaluchoSidesAnim = {};

function GaluchoSidesAnim.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Trailer, specializations) and SpecializationUtil.hasSpecialization(VariableBody, specializations);
end;

function GaluchoSidesAnim:load(xmlFile)

	self.toggleAnimState = SpecializationUtil.callSpecializationsFunction("toggleAnimState");

	self.sidesAnim1 = getXMLString(xmlFile, "vehicle.sidesAnimations.animations#animName1");
	self.maxAnimDuration1 = self:getAnimationDuration(self.sidesAnim1);
	self.sidesAnim2 = getXMLString(xmlFile, "vehicle.sidesAnimations.animations#animName2");
	self.maxAnimDuration2 = self:getAnimationDuration(self.sidesAnim2);
	self.sidesAnim3 = getXMLString(xmlFile, "vehicle.sidesAnimations.animations#animName3");
	self.maxAnimDuration3 = self:getAnimationDuration(self.sidesAnim3);
	self.sidesAnim4 = getXMLString(xmlFile, "vehicle.sidesAnimations.animations#animName4");
	self.maxAnimDuration4 = self:getAnimationDuration(self.sidesAnim4);
	self.varBodyConfig = getXMLString(xmlFile, "vehicle.sidesAnimations#variableBodyName");
	self.isAnimOn = false;
	self.previousState1 = false;
	self.previousState2 = false;
	self.previousState3 = false;
	self.previousState4 = false;
	self.sideAnimTime = 0;
end;

function GaluchoSidesAnim:delete()
end;

function GaluchoSidesAnim:readStream(streamId, connection)
	local idx = streamReadInt8(streamId);
	local state = streamReadBool(streamId);
	self:toggleAnimState(idx, state, true);
end;

function GaluchoSidesAnim:writeStream(streamId, connection)
	streamWriteInt8(streamId, self.activeIdx);
	streamWriteBool(streamId, self.isAnimOn);
end;

function GaluchoSidesAnim:mouseEvent(posX, posY, isDown, isUp, button)
end;

function GaluchoSidesAnim:keyEvent(unicode, sym, modifier, isDown)
end;

function GaluchoSidesAnim:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		if self.fillLevel < 0.001 then
			local leftSideOpen = getXMLBool(xmlFile, key.."#leftSideOpen");
			if leftSideOpen ~= nil and leftSideOpen then
				self.previousState1 = leftSideOpen;
				GaluchoSidesAnim.setAnimTime(self, 1, 1);
			end;
			local rightSideOpen = getXMLBool(xmlFile, key.."#rightSideOpen");
			if rightSideOpen ~= nil and rightSideOpen then
				self.previousState2 = rightSideOpen;
				GaluchoSidesAnim.setAnimTime(self, 2, 1);
			end;
			local backSideOpen = getXMLBool(xmlFile, key.."#backSideOpen");
			if backSideOpen ~= nil and backSideOpen then
				self.previousState3 = backSideOpen;
				GaluchoSidesAnim.setAnimTime(self, 3, 1);
			end;
			local sidesRemoved = getXMLBool(xmlFile, key.."#sidesRemoved");
			if sidesRemoved ~= nil and sidesRemoved then
				self.previousState4 = sidesRemoved;
				GaluchoSidesAnim.setAnimTime(self, 4, 1);
			end;
		end;
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function GaluchoSidesAnim:getSaveAttributesAndNodes(nodeIdent)
	if self.sidesAnim1 ~= nil and self.fillLevel < 0.001 then
		local attributes = 'leftSideOpen="'..tostring(self.previousState1)..'" rightSideOpen="'..tostring(self.previousState2)..'" backSideOpen="'..tostring(self.previousState3)..'" sidesRemoved="'..tostring(self.previousState4)..'"';
		return attributes, nil;
	end;
end;

function GaluchoSidesAnim:update(dt)
	if self:getIsActiveForInput() then
		if self.fillLevel == 0 and self.tipState == Trailer.TIPSTATE_CLOSED and self.varBodyConfig ~= nil then
			if string.match(self.varBodyConfig, self.varBody.nodes[self.varBody.activeIdx].name) then
				if self:getAnimationTime(self.sidesAnim4) == 0 then
					if InputBinding.hasEvent(InputBinding.LEFT_SIDE) then
						self:toggleAnimState(1, not self.isAnimOn);
					end;
					if InputBinding.hasEvent(InputBinding.RIGHT_SIDE) then
						self:toggleAnimState(2, not self.isAnimOn);
					end;
					if InputBinding.hasEvent(InputBinding.BACK_SIDE) then
						self:toggleAnimState(3, not self.isAnimOn);
					end;
				end;
				if self:getAnimationTime(self.sidesAnim1) > 0.85 and self:getAnimationTime(self.sidesAnim2) > 0.85 and self:getAnimationTime(self.sidesAnim3) > 0.85 then
					if InputBinding.hasEvent(InputBinding.REMOVE_SIDES) then
						self:toggleAnimState(4, not self.isAnimOn);
					end;	
				end;
				if self:getAnimationTime(self.sidesAnim1) == 0 and self:getAnimationTime(self.sidesAnim2) == 0 and self:getAnimationTime(self.sidesAnim3) == 0 then
					if self.capacity == 0 and not self.isBaleAttach then
						self:toggleAnimState(0, true);
					end;
				else
					if self.capacity > 0 then
						self:toggleAnimState(0, false);
					end;
				end;
			end;
		end;
	end;
end;

function GaluchoSidesAnim:updateTick(dt)
end;

function GaluchoSidesAnim:draw()
	if self:getIsActiveForInput(true) then
		if self.tipState == Trailer.TIPSTATE_CLOSED and self.fillLevel == 0 and self.varBodyConfig ~= nil then
			if string.match(self.varBodyConfig, self.varBody.nodes[self.varBody.activeIdx].name) and self:getAnimationTime(self.sidesAnim4) == 0 then
				g_currentMission:addExtraPrintText(g_i18n:getText("operate_sides"));
			end;
			if self:getAnimationTime(self.sidesAnim1) > 0.85 and self:getAnimationTime(self.sidesAnim2) > 0.85 and self:getAnimationTime(self.sidesAnim3) > 0.85 then
				if self.previousState4 then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("assemble_sides")), InputBinding.REMOVE_SIDES);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("remove_sides")), InputBinding.REMOVE_SIDES);
				end;
			end;
		end;
	end;
end;

function GaluchoSidesAnim:toggleAnimState(idx, state, noEventSend)
	if idx == 0 then
		if state then
			self.capacity = self.varBody.nodes[self.varBody.activeIdx].capacity;
		else
			self.capacity = 0;
		end;
	end;
	local speed = 1;
	if idx == 1 then
		if self.previousState1 == state then
			state = not state;
		end;
		if not state then
			speed = -speed;
		end;
		self:playAnimation(self.sidesAnim1, speed, nil, true);
		self.previousState1 = state;
	end;
	if idx == 2 then
		if self.previousState2 == state then
			state = not state;
		end;
		if not state then
			speed = -speed;
		end;
		self:playAnimation(self.sidesAnim2, speed, nil, true);
		self.previousState2 = state;
	end;
	if idx == 3 then
		if self.previousState3 == state then
			state = not state;
		end;
		if not state then
			speed = -speed;
		end;
		self:playAnimation(self.sidesAnim3, speed, nil, true);
		self.previousState3 = state;
	end;
	if idx == 4 then
		if self.previousState4 == state then
			state = not state;
		end;
		if not state then
			speed = -speed;
		end;
		self:playAnimation(self.sidesAnim4, speed, nil, true);
		self.previousState4 = state;
	end;
	self.activeIdx = idx;
	self.isAnimOn = state;
	
	SetToggleAnimEvent.sendEvent(self, idx, state, noEventSend);
	if self.updateCylinderedInitial ~= nil then
		self:updateCylinderedInitial();
	end;
end;

function GaluchoSidesAnim.setAnimTime(self, idx, animTime)
	self.activeIdx = idx;
	local speed = 1;
	if self.activeIdx == 1 then
		if self.sidesAnim1 ~= nil then
			self.sideAnimTime = animTime;
			local stopAnimTime = (self.sideAnimTime*self.maxAnimDuration1)/self:getAnimationDuration(self.sidesAnim1);
			self:playAnimation(self.sidesAnim1, speed, nil, true);
			self:setAnimationStopTime(self.sidesAnim1, stopAnimTime);
			AnimatedVehicle.updateAnimationByName(self, self.sidesAnim1, 99999999);
		end;
	elseif self.activeIdx == 2 then
		if self.sidesAnim2 ~= nil then
			self.sideAnimTime = animTime;
			local stopAnimTime = (self.sideAnimTime*self.maxAnimDuration2)/self:getAnimationDuration(self.sidesAnim2);
			self:playAnimation(self.sidesAnim2, speed, nil, true);
			self:setAnimationStopTime(self.sidesAnim2, stopAnimTime);
			AnimatedVehicle.updateAnimationByName(self, self.sidesAnim2, 99999999);
		end;
	elseif self.activeIdx == 3 then
		if self.sidesAnim3 ~= nil then
			self.sideAnimTime = animTime;
			local stopAnimTime = (self.sideAnimTime*self.maxAnimDuration3)/self:getAnimationDuration(self.sidesAnim3);
			self:playAnimation(self.sidesAnim3, speed, nil, true);
			self:setAnimationStopTime(self.sidesAnim3, stopAnimTime);
			AnimatedVehicle.updateAnimationByName(self, self.sidesAnim3, 99999999);
		end;
	elseif self.activeIdx == 4 then
		if self.sidesAnim4 ~= nil then
			self.sideAnimTime = animTime;
			local stopAnimTime = (self.sideAnimTime*self.maxAnimDuration4)/self:getAnimationDuration(self.sidesAnim4);
			self:playAnimation(self.sidesAnim4, speed, nil, true);
			self:setAnimationStopTime(self.sidesAnim4, stopAnimTime);
			AnimatedVehicle.updateAnimationByName(self, self.sidesAnim4, 99999999);
		end;
	end;
	if self.updateCylinderedInitial ~= nil then
		self:updateCylinderedInitial();
	end;
end;

SetToggleAnimEvent = {};
SetToggleAnimEvent_mt = Class(SetToggleAnimEvent, Event);
InitEventClass(SetToggleAnimEvent, "SetToggleAnimEvent");

function SetToggleAnimEvent:emptyNew()
    local self = Event:new(SetToggleAnimEvent_mt);
    self.className="SetToggleAnimEvent";
    return self;
end;

function SetToggleAnimEvent:new(vehicle, id, state)
	local self = SetToggleAnimEvent:emptyNew()
	self.vehicle = vehicle;
	self.id = id;
	self.state = state;
	return self;
end;

function SetToggleAnimEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.vehicle = networkGetObject(id);
	self.id  = streamReadInt8(streamId);
    self.state = streamReadBool(streamId);
    self:run(connection);
end;

function SetToggleAnimEvent:writeStream(streamId, connection)
	streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteInt8(streamId, self.id);
	streamWriteBool(streamId, self.state);
end;

function SetToggleAnimEvent:run(connection)
	self.vehicle:toggleAnimState(self.id,self.state, true);
	if not connection:getIsServer() then
		g_server:broadcastEvent(SetToggleAnimEvent:new(self.vehicle, self.id, self.state), nil, connection, self.vehicle);
	end;	
end;

function SetToggleAnimEvent.sendEvent(vehicle, id, state, nes)
	if nes == nil or nes == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetToggleAnimEvent:new(vehicle, id, state), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetToggleAnimEvent:new(vehicle, id, state));
		end;
	end;
end;
