AnimationNetwort = {};

function AnimationNetwort.prerequisitesPresent(specializations)
    return true;
end;

function AnimationNetwort:load(xmlFile)

	self.setAnimationTime = SpecializationUtil.callSpecializationsFunction("setAnimationTime");
	
	self.animationParts = {};
	local i = 0;
	while true do
		local partName = string.format("vehicle.animationParts.animationPart(%d)", i);
		local animationPart = {};
		local partStr = getXMLString(xmlFile, partName .. "#rootNode");
		if partStr == nil then
            break;
        end;
        animationPart.rootNode = Utils.indexToObject(self.components, partStr);
		local charSet = getAnimCharacterSet(animationPart.rootNode);
		if charSet == nil then
			print("Error: invalid animation rootNode " .. partStr);
			break;
		else
			animationPart.animCharSet = charSet;
			animationPart.clip = getAnimClipIndex(animationPart.animCharSet, getXMLString(xmlFile, partName.."#clipName"));
			assignAnimTrackClip(animationPart.animCharSet, 0, animationPart.clip);
			animationPart.clipSpeed = Utils.getNoNil(getXMLFloat(xmlFile, partName .. "#clipSpeed"), 1);
			animationPart.cSpeed = animationPart.clipSpeed;
			setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, animationPart.clipSpeed);
			animationPart.loop = Utils.getNoNil(getXMLBool(xmlFile, partName.."#loop"), false);
			setAnimTrackLoopState(animationPart.animCharSet, 0, animationPart.loop);
			animationPart.startPosition =  Utils.getNoNil(getXMLInt(xmlFile, partName .. "#startPosition"), 0);
			animationPart.currentPosition = animationPart.startPosition;
			setAnimTrackTime(animationPart.animCharSet, 0, animationPart.currentPosition);
			animationPart.accerlation = Utils.getNoNil(getXMLFloat(xmlFile, partName .. "#accerlation"), 0);
			animationPart.deAccerlation = Utils.getNoNil(getXMLFloat(xmlFile, partName .. "#deAccerlation"), 0)*-1;
			animationPart.loopSpeed = 0;
			local numJoints = Utils.getNoNil(getXMLInt(xmlFile, partName .. "#numJoints"), 0); 
			if numJoints > 0 then
				animationPart.joints = {};
				for j=1, numJoints do
					local jointString = string.format("%s.componentJoint%d", partName, j);
					local index = Utils.getNoNil(getXMLInt(xmlFile, jointString .."#index"), 0);
					if index == 0 then 
						print("Error: Invalid ComponenteJointIndex: "..index.."");
						break;
					end;
					local jointIndex = self.componentJoints[index];
					setJointFrame(jointIndex.jointIndex, 0, jointIndex.jointNode);
					table.insert(animationPart.joints, jointIndex);
				end;
			end;
			animationPart.offSet = Utils.getNoNil(getXMLInt(xmlFile, partName .. "#offSet"), 50);
			animationPart.loadSave = Utils.getNoNil(getXMLBool(xmlFile, partName.."#loadSave"), false);
			animationPart.animDuration = getAnimClipDuration(animationPart.animCharSet, animationPart.clip);
			if animationPart.currentPosition >= animationPart.animDuration then
				print("Error: Animation Part"..i.." startPosition larger or exakt then animation clip duration!");
				break;
			end;
			animationPart.animationEnabled = false;
			animationPart.inputTime = animationPart.currentPosition;
			animationPart.inputDone = false;
			animationPart.clipEndTime = false;
			animationPart.clipStartTime = false;
			animationPart.isLoading = false;
			table.insert(self.animationParts, animationPart);
        end;
        i = i + 1;
    end;
    self.poz = self.animationParts[10].animDuration;
    self.pad = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.pad#index"));
end;

function AnimationNetwort:delete()
end;

function AnimationNetwort:getSaveAttributesAndNodes(nodeIdent)
	local attributes = nil;
	local numToSave = 0;
	for _, animationPart in pairs(self.animationParts) do
		if animationPart.loadSave then
			numToSave = numToSave + 1;
		end;
	end;
	for k, animationPart in pairs(self.animationParts) do
		if animationPart.loadSave then
			local minTime = math.max(animationPart.currentPosition, 0);
			local maxTime = math.min(minTime, animationPart.animDuration);
			local currentTime = string.format("%d", maxTime);
			local saveAttributes = "animation" .. k .. "=\"" .. currentTime .. "\"";
			if numToSave > 1 and attributes ~= nil then
				attributes = attributes .. " " .. saveAttributes;
			else
				attributes = saveAttributes;
			end;
		end;
	end;
	return attributes, nil;
end;

function AnimationNetwort:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		for k, animationPart in pairs(self.animationParts) do
			local keyString = string.format("#animation%d", k);
			local inputTime = Utils.getNoNil(getXMLInt(xmlFile, key .. keyString), animationPart.startPosition);
			self:setAnimationTime(k, inputTime, true);
			animationPart.isLoading = animationPart.loadSave;
		end;
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function AnimationNetwort:readStream(streamId, connection)
	for k, animationPart in pairs(self.animationParts) do
		local timeInput = streamReadInt32(streamId);
		self:setAnimationTime(k, timeInput, true);
		animationPart.isLoading = true;
	end;
end;

function AnimationNetwort:writeStream(streamId, connection)
	for k, animationPart in pairs(self.animationParts) do
		streamWriteInt32(streamId, animationPart.inputTime);
	end;
end;

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

function AnimationNetwort:keyEvent(unicode, sym, modifier, isDown)
    if self.isClient and self:getIsActiveForInput() then
	if isDown and sym == Input.KEY_6 then	
		self.kisventiOn = not self.kisventiOn;
	end;
	if isDown and sym == Input.KEY_7 then	
		self.ablakt1On = not self.ablakt1On;
	end;
	if isDown and sym == Input.KEY_8 then	
		self.ablakt2On = not self.ablakt2On;
	end;
	if isDown and sym == Input.KEY_f2 then	
		self.help = not self.help;
	end;
    end;
end;

function AnimationNetwort:update(dt)

    if self.isClient and self:getIsActiveForInput() then
	if Input.isKeyPressed(Input.KEY_KP_4) then	
		if self.animationParts[1].clipEndTime then
				
			self:setAnimationTime(1, self.animationParts[1].offSet);
		
		elseif self.animationParts[1].clipStartTime then
				
			self:setAnimationTime(1, self.animationParts[1].animDuration);
			
		end;	
	end;
	if Input.isKeyPressed(Input.KEY_KP_6) then	
		if self.animationParts[2].clipEndTime then
				
			self:setAnimationTime(2, self.animationParts[2].offSet);
		
		elseif self.animationParts[2].clipStartTime then
				
			self:setAnimationTime(2, self.animationParts[2].animDuration);
			
		end;	
	end;
	if Input.isKeyPressed(Input.KEY_KP_7) then	
		if self.animationParts[3].clipEndTime then
				
			self:setAnimationTime(3, self.animationParts[3].offSet);
		
		elseif self.animationParts[3].clipStartTime then
				
			self:setAnimationTime(3, self.animationParts[3].animDuration);
			
		end;	
	end;
	if Input.isKeyPressed(Input.KEY_KP_9) then	
		if self.animationParts[4].clipEndTime then
				
			self:setAnimationTime(4, self.animationParts[4].offSet);
		
		elseif self.animationParts[4].clipStartTime then
				
			self:setAnimationTime(4, self.animationParts[4].animDuration);
			
		end;	
	end;
	if Input.isKeyPressed(Input.KEY_KP_5) then	
		if self.animationParts[5].clipEndTime then
				
			self:setAnimationTime(5, self.animationParts[5].offSet);
		
		elseif self.animationParts[5].clipStartTime then
				
			self:setAnimationTime(5, self.animationParts[5].animDuration);
			
		end;	
	end;
	if self.ablakt1On then	
		if self.animationParts[8].clipEndTime then
				
			self:setAnimationTime(8, self.animationParts[8].offSet);
		
		elseif self.animationParts[8].clipStartTime then
				
			self:setAnimationTime(8, self.animationParts[8].animDuration);
			
		end;
	else
		if self.animationParts[8].clipEndTime then

			self:setAnimationTime(8, 0);
		end;
	end;
	if self.ablakt2On then	
		if self.animationParts[9].clipEndTime then
				
			self:setAnimationTime(9, self.animationParts[9].offSet);
		
		elseif self.animationParts[9].clipStartTime then
				
			self:setAnimationTime(9, self.animationParts[9].animDuration);
			
		end;
	else
		if self.animationParts[9].clipEndTime then

			self:setAnimationTime(9, 0);
		end;
	end;

    	if self.isAITractorActivated then
		self.animationParts[10].clipSpeed = self.animationParts[10].cSpeed;
		if self.turnStage == 0 then
			self:setAnimationTime(10, self.poz);

		else
			self:setAnimationTime(10, 0);

		end;
    	elseif self:getIsActiveForInput() and self.isEntered then
	   if InputBinding.isPressed(InputBinding.HIDRAULIKAFEL) then
		self.animationParts[10].clipSpeed = self.animationParts[10].cSpeed;
		self.poz = self.animationParts[10].currentPosition;				
		self:setAnimationTime(10, 0);

		self.stop = false;
		if self.animationParts[10].currentPosition <= 200 then
	      		if self.selectedImplement ~= 0 then
	          		local implement = self.attachedImplements[self.selectedImplement];
	          		local jointDesc = self.attacherJoints[implement.jointDescIndex];
	          		self:setJointMoveDown(implement.jointDescIndex, false, false);
	      		end;
		end;			   
	   elseif InputBinding.isPressed(InputBinding.HIDRAULIKALE) then

		self.animationParts[10].clipSpeed = self.animationParts[10].cSpeed;
		self.poz = self.animationParts[10].currentPosition;				
		self:setAnimationTime(10, self.animationParts[10].animDuration);

		self.stop = false;
		if self.animationParts[10].currentPosition <= 1000 then
	      		if self.selectedImplement ~= 0 then
	          		local implement = self.attachedImplements[self.selectedImplement];
	          		local jointDesc = self.attacherJoints[implement.jointDescIndex];
	          		self:setJointMoveDown(implement.jointDescIndex, true, true);
	      		end;
		end;					
	   elseif InputBinding.hasEvent(InputBinding.ATTACH) then
		self.stop = true;
		self.animationParts[10].clipSpeed = self.animationParts[10].cSpeed;
		self.poz = self.animationParts[10].currentPosition;
		self:setAnimationTime(10, 0);

	   elseif InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then
		self.stop = true;
		self.animationParts[10].clipSpeed = self.animationParts[10].cSpeed;
	        if self.animationParts[10].currentPosition ~= self.poz then		
			self:setAnimationTime(10, self.poz);
   		 	if self.selectedImplement ~= 0 then
        			local implement = self.attachedImplements[self.selectedImplement];
        			if implement.object.allowsLowering then
            				local jointDesc = self.attacherJoints[implement.jointDescIndex];
            				if jointDesc.allowsLowering then
                				jointDesc.moveDown = true;
            				end;
        			end;
   			end;
		else
			self:setAnimationTime(10, 0);
		   	if self.selectedImplement ~= 0 then
        			local implement = self.attachedImplements[self.selectedImplement];
        			if implement.object.allowsLowering then
            				local jointDesc = self.attacherJoints[implement.jointDescIndex];
            				if jointDesc.allowsLowering then
                				jointDesc.moveDown = false;
            				end;
        			end;
   		 	end;

		end;
	   elseif not self.stop then
		self.animationParts[10].clipSpeed = 0;
	   end;
	end;


	if self.kisventiOn then
			
		self:setAnimationTime(6, 1);
		
	else
			
		self:setAnimationTime(6, 0);
		
	end;
	if self.isMotorStarted then
		self:setAnimationTime(7, 1);
		
	else
			
		self:setAnimationTime(7, 0);
		
	end;

	if not self.help then
            renderText(0.001, 0.985, 0.015, "F2: Info be");
        else
            renderText(0.001, 0.985, 0.015, "F2: Info ki");
        end;
        
        if self.help then
            		renderText(0.02, 0.18, 0.03, "- JUMZ 6 Info -");
            		renderText(0.02, 0.22, 0.02, "Numpad 1: iranyjelzo balra");
			renderText(0.02, 0.24, 0.02, "Numpad 2: elakadasjelzo");
			renderText(0.02, 0.26, 0.02, "Numpad 3: iranyjelzo jobbra");
			renderText(0.02, 0.28, 0.02, "Numpad 4: bal ajto nyit/zar");
			renderText(0.02, 0.30, 0.02, "Numpad 6: jobb ajto nyit/zar");
			renderText(0.02, 0.32, 0.02, "Numpad 5: hatso ablak nyit/zar");
			renderText(0.02, 0.34, 0.02, "Numpad 7: bal ablak nyit/zar");
			renderText(0.02, 0.36, 0.02, "Numpad 9: jobb ablak nyit/zar");
			renderText(0.02, 0.38, 0.02, "6: ventilator be/ki");
			renderText(0.02, 0.40, 0.02, "7: elso ablaktorlo be/ki");
			renderText(0.02, 0.42, 0.02, "8: hatso ablaktorlo be/ki");
			renderText(0.02, 0.44, 0.02, "HOME/END: hidraulika fel/le");
            		renderText(0.02, 0.46, 0.02, "F: fenyszoro be/ki");
            		renderText(0.02, 0.48, 0.02, "F (nyomva tart): tavolsagi feny be/ki");
            		renderText(0.02, 0.50, 0.02, "5: munkalampa be/ki");
            		renderText(0.02, 0.52, 0.02, "SHIFT: hatranez (belso nezetben)");

		end;
    end;

end;

function AnimationNetwort:updateTick(dt)
	for k, animationPart in pairs(self.animationParts) do
		if animationPart.animationEnabled then
			local currentTime = animationPart.currentPosition;
			local timeInput = animationPart.inputTime;
			local clipSpeed = animationPart.clipSpeed;
			local loopState = animationPart.loop;
			local duration = animationPart.animDuration;
			local accerlationSpeed = animationPart.loopSpeed;
			if animationPart.isLoading then
				clipSpeed = animationPart.clipSpeed*animationPart.offSet;
				animationPart.isLoading = false;
			end;
			if loopState == true then
				if timeInput ~= 0 then
					if animationPart.accerlation ~= 0 then
						accerlationSpeed = math.min(accerlationSpeed+((accerlationSpeed+animationPart.accerlation)*animationPart.accerlation), clipSpeed);
						setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, accerlationSpeed);
						if accerlationSpeed >= clipSpeed then
							animationPart.inputDone = true;
							animationPart.loopSpeed = clipSpeed;
						else
							animationPart.loopSpeed = accerlationSpeed;
						end;
					else
						setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, clipSpeed);
						animationPart.inputDone = true;
					end;
				elseif timeInput == 0 then
					if animationPart.deAccerlation ~= 0 then
						accerlationSpeed = math.max(accerlationSpeed+(accerlationSpeed*animationPart.deAccerlation), 0);
						setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, accerlationSpeed);
						if accerlationSpeed <= 0 then
							animationPart.inputDone = true;
							animationPart.loopSpeed = 0;
						else
							animationPart.loopSpeed = accerlationSpeed;
						end;
					else
						setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, 0);
						disableAnimTrack(animationPart.animCharSet, animationPart.clip);
						animationPart.inputDone = true;
					end;
				end;
			elseif loopState == false then
				if currentTime < timeInput and animationPart.inputDone == false then
					setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, clipSpeed);
					if currentTime+animationPart.offSet >= timeInput then
						animationPart.inputDone = true;
						setAnimTrackTime(animationPart.animCharSet, animationPart.clip, timeInput);
						setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, 0);
					end;
				elseif currentTime > timeInput and animationPart.inputDone == false then
					setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, -clipSpeed);
					if currentTime-animationPart.offSet <= timeInput then
						animationPart.inputDone = true;
						setAnimTrackTime(animationPart.animCharSet, animationPart.clip, timeInput);
						setAnimTrackSpeedScale(animationPart.animCharSet, animationPart.clip, 0);
					end;
				end;
				if currentTime >= duration-animationPart.offSet then
					animationPart.clipEndTime = true;
				elseif currentTime <= animationPart.offSet then
					animationPart.clipStartTime = true;
				elseif currentTime == animationPart.startPosition then
					animationPart.clipStartTime = true;
				else
					animationPart.clipStartTime = false;
					animationPart.clipEndTime = false;
				end;
			end;
			if animationPart.joints ~= nil then
				for k, joint in pairs(animationPart.joints) do
					setJointFrame(joint.jointIndex, 0, joint.jointNode);
				end;
			end;
			animationPart.currentPosition = getAnimTrackTime(animationPart.animCharSet, animationPart.clip);
		else
			enableAnimTrack(animationPart.animCharSet, animationPart.clip);
		end;
		animationPart.animationEnabled = isAnimTrackEnabled(animationPart.animCharSet, animationPart.clip);
	end;
end;

function AnimationNetwort:setAnimationTime(animationPart, timeInput, noEventSend)
	local minTime = math.max(timeInput, 0);
	local maxTime = math.min(minTime, self.animationParts[animationPart].animDuration);
	SetAnimationEvent.sendEvent(self, animationPart, maxTime, noEventSend);
	if maxTime ~= self.animationParts[animationPart].currentPosition then
		self.animationParts[animationPart].inputDone = false;
		self.animationParts[animationPart].inputTime = maxTime;
	end;
end;

function AnimationNetwort:draw()	
end;

function AnimationNetwort:onLeave()

    if self.isClient then
	self.ablakt1On = false;
	self.ablakt2On = false;
	self.kisventiOn = false;
	self:setAnimationTime(6, 0);

	self:setAnimationTime(7, 0);
	self:setAnimationTime(8, 0);
	self:setAnimationTime(9, 0);	
    end;
	
end;

function AnimationNetwort:validateAttacherJoint(implement, jointDesc, dt)
	local jointType = implement.object.attacherJoint.jointType;
	if jointType == Vehicle.JOINTTYPE_TRAILERLOW then
		setVisibility(self.pad, true);
	else
		setVisibility(self.pad, false);
	end;

    return true;
end;