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);
			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;
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 k > 1 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)
end;

function AnimationNetwort:update(dt)
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;