  --
     -- Shovel
     -- Class for all sprayers
     --
     -- @author  Stefan Geiger
     -- @date  24/02/08
     --
     -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.

    Shov = {};


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

    function Shov:load(xmlFile)

        self.findTrailerRaycastCallback = Shov.findTrailerRaycastCallback;
        self.setManureIsFilled = Shov.setManureIsFilled;
        self.getIsManureEmptying = Shov.getIsManureEmptying;

        self.manureTipReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.manure#tipReferenceNode"));
        self.manureFillPlane = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.manure#fillPlane"));
       self.manureCapacity = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.manure#capacity"), 0);
        self.manureIsFilled = false;

        self.emptyParticleSystems = {};
        Utils.loadParticleSystem(xmlFile, self.emptyParticleSystems, "vehicle.emptyParticleSystem", self.components, false, nil, self.baseDirectory);

        self.ShovDirtyFlag = self:getNextDirtyFlag();

        self:setManureIsFilled(false);
    end;

    function Shov:delete()
        Utils.deleteParticleSystem(self.emptyParticleSystems);
    end;

    function Shov:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
        local manureIsFilled = getXMLBool(xmlFile, key.."#manureIsFilled");
        if manureIsFilled ~= nil then
            self:setManureIsFilled(manureIsFilled);
        end;
        return BaseMission.VEHICLE_LOAD_OK;
    end;

    function Shov:getSaveAttributesAndNodes(nodeIdent)
        local attributes = 'manureIsFilled="'..tostring(self.manureIsFilled)..'"';
        return attributes, nil;
    end;

    function Shov:readStream(streamId, connection)
        local isFilled = streamReadBool(streamId);
        self:setManureIsFilled(isFilled);
    end;

    function Shov:writeStream(streamId, connection)
        streamWriteBool(streamId, self.manureIsFilled);
    end;

    function Shov:readUpdateStream(streamId, timestamp, connection)
        if connection:getIsServer() then
            local isFilled = streamReadBool(streamId);
            self:setManureIsFilled(isFilled);
        end;
    end;

    function Shov:writeUpdateStream(streamId, connection, dirtyMask)
        if not connection:getIsServer() then
            streamWriteBool(streamId, self.manureIsFilled);
        end;
    end;

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

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

    function Shov:update(dt)
    end;

    function Shov:updateTick(dt)

          if self.isServer then

                if self.manureIsFilled then
                    if self.manureTipReferenceNode ~= nil and self.manureFillPlane ~= nil then
                        if self:getIsManureEmptying() then
                            -- do raycast and empty..

                            self.trailerFound = 0;
                            local x,y,z = getWorldTranslation(self.manureTipReferenceNode);
                            raycastAll(x, y, z, 0, -1, 0, "findTrailerRaycastCallback", 10, self);

                            local trailer = g_currentMission.objectToTrailer[self.trailerFound];
                            if self.trailerFound ~= 0 and trailer ~= nil and trailer:allowFillType(Fillable.FILLTYPE_MANURE) and trailer.allowFillFromAir then
                                trailer:resetFillLevelIfNeeded(Fillable.FILLTYPE_MANURE);
                               trailer:setFillLevel(trailer.fillLevel + self.manureCapacity, Fillable.FILLTYPE_MANURE);
                           end;
                           self:setManureIsFilled(false);
                       end;
                   end;
               end;
          end;
         
       
   end;

   function Shov:draw()
   end;

   function Shov:onDetach()
       if self.deactivateOnDetach then
           Shov.onDeactivate(self);
       else
           Shov.onDeactivateSounds(self);
       end;
   end;

   function Shov:onLeave()
       if self.deactivateOnLeave then
           Shov.onDeactivate(self);
       else
           Shov.onDeactivateSounds(self);
       end;
   end;

   function Shov:onDeactivate()
       Shov.onDeactivateSounds(self);
   end;

   function Shov:onDeactivateSounds()
   end;

   function Shov:setManureIsFilled(isFilled)
       if self.manureIsFilled ~= isFilled then
           self.manureIsFilled = isFilled;
           if not isFilled then
               Utils.resetNumOfEmittedParticles(self.emptyParticleSystems)
               Utils.setEmittingState(self.emptyParticleSystems, true);
           end;
           if self.isServer then
               self:raiseDirtyFlags(self.shovDirtyFlag);
           end;
       end;
       if self.manureFillPlane ~= nil then
           setVisibility(self.manureFillPlane, self.manureIsFilled);
       end;

   end;

   function Shov:getIsManureEmptying()
       if self.manureTipReferenceNode ~= nil then
           local dx,dy,dz = localDirectionToWorld(self.manureTipReferenceNode, 0,0,1);
           -- more than 55? rotated towards the ground
           if dy < -0.573576436351 then
               return true;
           end;
       end;
       return false;
   end;

   function Shov:findTrailerRaycastCallback(transformId, x, y, z, distance)

       if getUserAttribute(transformId, "vehicleType") == 2 then
           self.trailerFound = transformId;
           return false;
       end;

       return true;

   end;