
  
  source("dataS/scripts/vehicles/specializations/SetTurnedOnEvent.lua");
  
  Fraese = {};
  
  function Fraese.prerequisitesPresent(specializations)
      return SpecializationUtil.hasSpecialization(Fillable, specializations);
  end;
  
  function Fraese:load(xmlFile)
	  
      self.setIsTurnedOn = SpecializationUtil.callSpecializationsFunction("setIsTurnedOn");
      self.allowFillFromShovelTrigger = Utils.overwrittenFunction(self.allowFillFromShovelTrigger, Fraese.allowFillFromShovelTrigger);
       self.fillShovelFromTrigger = Utils.overwrittenFunction(self.fillShovelFromTrigger, Fraese.fillShovelFromTrigger);
      self.setIsTurnedOn = Fraese.setIsTurnedOn;
      
      self.getAllowFillShovel = Utils.overwrittenFunction(self.getAllowFillShovel, Fraese.getAllowFillShovel);
	  self.resetFillLevelIfNeeded = Fraese.resetFillLevelIfNeeded;
      self.isTurnedOn = false;
	  self.fraeseLastfraeseTime = 0;
	  self.setTransRot = SpecializationUtil.callSpecializationsFunction("setTransRot");
	  self.TransRotAnimation = getXMLString(xmlFile, "vehicle.TransRot#animationName");
	  self.TransRot = false;
	  
	   self.rotateFraese = {};
		 local i=0;
		 while true do
			 local baseName = string.format("vehicle.fraeseRotatingParts.fraeseRotatingPart(%d)", i);
			 local index = getXMLString(xmlFile, baseName.. "#index");
			 local x,y,z = Utils.getVectorFromString(getXMLString(xmlFile, baseName.. "#rotationSpeed"));
			 local rotationSpeed = {x,y,z};
			 local runOutTime = Utils.getNoNil(getXMLFloat(xmlFile, baseName.. "#runOutTime"), 2)*1000;
			 if index == nil or rotationSpeed == nil or runOutTime == nil then
				 break;
			 end;
			 local node = Utils.indexToObject(self.components, index);
			 if node ~= nil then
				 local entry = {};
				 entry.node = node;
				 entry.runOutTime = runOutTime;
				 entry.rotationSpeedMax = rotationSpeed;
				 entry.rotationSpeedMin = {0,0,0};
				 entry.rotationSpeedCurrent = {0,0,0};
				 table.insert(self.rotateFraese, entry);
			 end;
			 i = i+1;
		 end;	
		
		
		self.fraeseSoundEnabled = false;
      if self.isClient then
          local fraeseSound = getXMLString(xmlFile, "vehicle.fraeseSound#file");
          if fraeseSound ~= nil and fraeseSound ~= "" then
              fraeseSound = Utils.getFilename(fraeseSound, self.baseDirectory);
              self.fraeseSound = createSample("fraeseSound");
              loadSample(self.fraeseSound, fraeseSound, false);
              self.fraeseSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fraeseSound#pitchOffset"), 1);
              self.fraeseSoundfraesePitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fraeseSound#fraesePitchOffset"), 0.8*self.fraeseSoundPitchOffset);
              self.fraeseSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fraeseSound#volume"), 1.0);
              setSamplePitch(self.fraeseSound, self.fraeseSoundPitchOffset);
          end;
  
          local fraeseStartSound = getXMLString(xmlFile, "vehicle.fraeseStartSound#file");
          if fraeseStartSound ~= nil and fraeseStartSound ~= "" then
              fraeseStartSound = Utils.getFilename(fraeseStartSound, self.baseDirectory);
              self.fraeseStartSound = createSample("fraeseStartSound");
              loadSample(self.fraeseStartSound, fraeseStartSound, false);
              self.fraeseStartSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fraeseStartSound#pitchOffset"), 1);
              self.fraeseStartSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fraeseStartSound#volume"), 1.0);
              setSamplePitch(self.fraeseStartSound, self.fraeseStartSoundPitchOffset);
          end;
  
          local fraeseStopSound = getXMLString(xmlFile, "vehicle.fraeseStopSound#file");
          if fraeseStopSound ~= nil and fraeseStopSound ~= "" then
              fraeseStopSound = Utils.getFilename(fraeseStopSound, self.baseDirectory);
              self.fraeseStopSound = createSample("fraeseStopSound");
              loadSample(self.fraeseStopSound, fraeseStopSound, false);
              self.fraeseStopSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fraeseStopSound#pitchOffset"), 1);
              self.fraeseStopSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fraeseStopSound#volume"), 1.0);
              setSamplePitch(self.fraeseStopSound, self.fraeseStopSoundPitchOffset);
          end;
       end
	   
  
      self.FraeseNeedsTurnOn = false;
      if self.shovelNodes ~= nil then
          self.FraeseNeedsTurnOn = true;
      end
  
      
  
     
  
      
  
      self.FraeseDirtyFlag = self:getNextDirtyFlag();
  end;
  
  
  function Fraese:readStream(streamId, connection)
	  local turnedOn = streamReadBool(streamId);
	  self:setIsTurnedOn(turnedOn, true);
      local fillLevel = streamReadFloat32(streamId);
      local fillType = streamReadUIntN(streamId, FruitUtil.sendNumBits);
	  self.currentFillType = streamReadInt8(streamId);
	  self:setTransRot(streamReadBool(streamId), true);
          
      
  end;
  
  function Fraese:writeStream(streamId, connection)
	if not connection:getIsServer() then
		streamWriteBool(streamId, self.isTurnedOn);
		streamWriteUIntN(streamId, self.currentFillType, FruitUtil.sendNumBits);
		streamWriteBool(streamId, self.TransRot);
     end;
  end;
  
  function Fraese:readUpdateStream(streamId, timestamp, connection)
      if connection:getIsServer() then
          if streamReadBool(streamId) then
			local fillLevel = streamReadUInt16(streamId)/65535*self.capacity;
            local fillType = streamReadUIntN(streamId, FruitUtil.sendNumBits);
			  
              
           end;
       end;
   end;

  
  function Fraese:writeUpdateStream(streamId, connection, dirtyMask)
        if not connection:getIsServer() then
			if streamWriteBool(streamId, bitAND(dirtyMask, self.DirtyFlag) ~= 0) then
              local percent = 0;
              if self.capacity > 0 then
                  percent = Utils.clamp(self.fillLevel / self.capacity, 0, 1);
              end;
              streamWriteUInt16(streamId, math.floor(percent*65535));
             
              streamWriteUIntN(streamId, self.currentFillType, FruitUtil.sendNumBits);
             
             
        end;
	end;	
  end
  
  function Fraese:delete()
      if self.isServer then
         
		  if self.fraeseSound ~= nil then
          delete(self.fraeseSound);
      end
      if self.fraeseStartSound ~= nil then
          delete(self.fraeseStartSound);
      end
      if self.fraeseStopSound ~= nil then
          delete(self.fraeseStopSound);
      end
      end
      
  end;
  
  
  
  
  
  
  
  function Fraese:mouseEvent(posX, posY, isDown, isUp, button)
  end;
  
  function Fraese:keyEvent(unicode, sym, modifier, isDown)
  end;
  
  function Fraese:update(dt)
      if self.isActive then
          if self.FraeseNeedsTurnOn then
              if self:getIsActiveForInput() then
                  if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
                      self:setIsTurnedOn(not self.isTurnedOn);
                  end
              end
          end
		if self.isTurnedOn then
					
					 for k, fraese in ipairs(self.rotateFraese) do
						 local values = Utils.getMovedLimitedValues(fraese.rotationSpeedCurrent, fraese.rotationSpeedMax, fraese.rotationSpeedMin, 3, fraese.runOutTime, dt, not self.isTurnedOn);
						 fraese.rotationSpeedCurrent = values;
						 rotate(fraese.node, unpack(fraese.rotationSpeedCurrent));
					 end;

                   if not self.fraeseSoundEnabled and self.fraeseSound ~= nil and self:getIsActiveForSound() then
                      if self.fraeseStartSound == nil or not isSamplePlaying(self.fraeseStartSound) or getSamplePlayOffset(self.fraeseStartSound) >= getSampleDuration(self.fraeseStartSound)-1.8*dt then
                          playSample(self.fraeseSound, 0, self.fraeseSoundVolume, 0);
                          self.fraeseSoundEnabled = true;
                      end
                  end
                  if self.fraeseSoundEnabled then
                      if self.fraeseLastfraeseTime >= self.time-200 then
                          setSamplePitch(self.fraeseSound, self.fraeseSoundfraesePitchOffset);
                      else
                          setSamplePitch(self.fraeseSound, self.fraeseSoundPitchOffset);
                      end;
                  end
              
			else
				if self.isClient and self.fraeseSoundEnabled and self.fraeseSound ~= nil and self:getIsActiveForSound() then
					stopSample(self.fraeseSound);
					self.fraeseSoundEnabled = false;
					
				end;
			end;
        
      end
  end;
  
 function Fraese:draw()
		if self.isClient then
			local percent = 0;
          if self.capacity > 0 then
             percent = self.fillLevel / self.capacity*100;
          
          if self.fraeseNeedsTurnOn then
              if self.isTurnedOn then
                  g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_off_OBJECT"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA);
              else
                  g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_on_OBJECT"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA);
              end;
          end
       
		end;
				
     end;      
 end 
  function Fraese:update(dt)
      if self.isActive then	
		if self.isClient and self:getIsActiveForInput(false) and not self:hasInputConflictWithSelection() then
  
				if self.fraeseNeedsTurnOn then
					if self:getIsActiveForInput() then
						if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
							self:setIsTurnedOn(not self.isTurnedOn);
							 self:setTransRot(not self.isTransRotOn);
						end
					end
				end
			
        end;
		
		
		if self.isTurnedOn then
					
					 for k, fraese in ipairs(self.rotateFraese) do
						 local values = Utils.getMovedLimitedValues(fraese.rotationSpeedCurrent, fraese.rotationSpeedMax, fraese.rotationSpeedMin, 3, fraese.runOutTime, dt, not self.isTurnedOn);
						 fraese.rotationSpeedCurrent = values;
						 rotate(fraese.node, unpack(fraese.rotationSpeedCurrent));
					 end;

                   if not self.fraeseSoundEnabled and self.fraeseSound ~= nil and self:getIsActiveForSound() then
                      if self.fraeseStartSound == nil or not isSamplePlaying(self.fraeseStartSound) or getSamplePlayOffset(self.fraeseStartSound) >= getSampleDuration(self.fraeseStartSound)-1.8*dt then
                          playSample(self.fraeseSound, 0, self.fraeseSoundVolume, 0);
                          self.fraeseSoundEnabled = true;
                      end
                  end
                  if self.fraeseSoundEnabled then
                      if self.fraeseLastfraeseTime >= self.time-200 then
                          setSamplePitch(self.fraeseSound, self.fraeseSoundfraesePitchOffset);
                      else
                          setSamplePitch(self.fraeseSound, self.fraeseSoundPitchOffset);
                      end;
                  end
              
			else
				if self.isClient and self.fraeseSoundEnabled and self.fraeseSound ~= nil and self:getIsActiveForSound() then
					stopSample(self.fraeseSound);
					self.fraeseSoundEnabled = false;
				end;
			end;
			
		end
	end
  
  function Fraese:onDetach()
      if self.deactivateOnDetach then
          Fraese.onDeactivate(self);
      else
          Fraese.onDeactivateSounds(self);
      end;
     
  end;
  
  function Fraese:onLeave()
      if self.deactivateOnLeave then
          Fraese.onDeactivate(self);
      else
          Fraese.onDeactivateSounds(self);
      end;
  end;
  
  function Fraese:onDeactivate()
      self:setIsTurnedOn(false, true)
      Fraese.onDeactivateSounds(self)
	  self.isTurnedOn = false;
  end;
  
  function Fraese:onDeactivateSounds()
      if self.fraeseSoundEnabled then
          stopSample(self.fraeseSound);
          self.fraeseSoundEnabled = false;
      end
	  
  end;
  
  function Fraese:setIsTurnedOn(isTurnedOn, noEventSend)
      SetTurnedOnEvent.sendEvent(self, isTurnedOn, noEventSend)
      if self.isTurnedOn ~= isTurnedOn then
          self.isTurnedOn = isTurnedOn;
		if self.isClient then
              if self.fraeseStartSound ~= nil then
                  stopSample(self.fraeseStartSound);
              end
              if self.fraeseStopSound ~= nil then
                  stopSample(self.fraeseStopSound);
              end
  
              if self:getIsActiveForSound() then
                  if self.isTurnedOn then
                      if self.fraeseStartSound ~= nil then
                          playSample(self.fraeseStartSound, 1, self.fraeseStartSoundVolume, 0);
                      end
                  else
                      if self.fraeseStopSound ~= nil then
                          playSample(self.fraeseStopSound, 1, self.fraeseStopSoundVolume, 0);
                      end
                  end
              end
			  
          end
          
      end
  end;
  
   function Fraese:setTransRot(isTransRot,noEventSend)
	 SetTransRotEvent.sendEvent(self, isTransRot, noEventSend);
	-- -- Play TransRot animation --
	 self.isTransRotOn = isTransRot;
	 if self.isTransRotOn then
		 if self.TransRotAnimation ~= nil and self.playAnimation ~= nil then
			 self:playAnimation(self.TransRotAnimation, 1, nil, true);
			 self.TransRot = true;

		 end;
	 else
		 if self.TransRotAnimation ~= nil and self.playAnimation ~= nil then
			 self:playAnimation(self.TransRotAnimation, -1, nil, true);
			 self.TransRot = false;
	
		 end;
	 end;
   end;
 
  
 


  
  function Fraese:fillShovelFromTrigger(superFunc, shovelTipTrigger, deltaFillLevel, fillType, dt)
      local value = 0;
      if superFunc ~= nil then
          value = superFunc(self, shovelTipTrigger, deltaFillLevel, fillType, dt)
      end
      if value > 0 then
          self.fraeseLastfraeseTime = self.time;
      end
      return value;
  end
  
  function Fraese:getAllowFillShovel(superFunc, fillType)
      if self.isTurnedOn then
          if superFunc ~= nil then
              return superFunc(self, fillType);
          end
      end
      return false;
  end;
  
  function Fraese:resetFillLevelIfNeeded(fillType)
  
      if self.currentFillType ~= fillType then
          self.fillLevel = 0;
      end;
  end;
  
  function Fraese:fillShovelFromGroundValue(superFunc, areas, fillType)
      local value = false;
      if superFunc ~= nil then
          value = superFunc(self, areas, fillType)
      end
      
      return value;
  end
  
  function Fraese:allowFillFromShovelTrigger(superFunc, areas, fillType)
      local value = false;
      if superFunc ~= nil then
          value = superFunc(self, areas, fillType)
      end
      if value then
          self.fraeseLastfraeseTime = self.time;
      end
      return value;
  end
  
 