  --
  -- ForageWagon
  -- Class for all ForageWagons
  --
  -- @author  Stefan Geiger
  -- @date  25/06/08
  --
  -- Copyright (C) GIANTS Software GmbH, Confidential, All Rights Reserved.
  
  FergForageWagon = {};
  
  source("dataS/scripts/vehicles/specializations/SetTurnedOnEvent.lua");
  source("dataS/scripts/vehicles/specializations/ForageWagonAreaEvent.lua");
  
function FergForageWagon.prerequisitesPresent(specializations)
      -- return SpecializationUtil.hasSpecialization(Trailer, specializations);
      return true;	  
end;
  
function FergForageWagon:load(xmlFile)
  
      self.setIsTurnedOn = SpecializationUtil.callSpecializationsFunction("setIsTurnedOn");
  
      -- Backward compatibility: Convert non-windrow fill types to the correspoding windrow fill types
      if Utils.getNoNil(getXMLBool(xmlFile, "vehicle.fillTypes#convertToWindrowFillType"), true) then
          local fillTypesToAdd = {};
          for fillType, enabled in pairs(self.fillTypes) do
              if fillType ~= Fillable.FILLTYPE_UNKNOWN and enabled then
                  local fruitType = FruitUtil.fillTypeToFruitType[fillType];
                  if fruitType ~= nil and not FruitUtil.fillTypeIsWindrow[fillType] then
                      local windrowFillType = FruitUtil.fruitTypeToWindrowFillType[fruitType];
                      if windrowFillType ~= nil and not self.fillTypes[windrowFillType] then
                          self.fillTypes[fillType] = nil;
                          table.insert(fillTypesToAdd, windrowFillType);
                          print("Warning: converted non-windrow fill type to windrow fill type in "..self.configFileName);
                      end
                  end
              end
          end
          for _,fillType in pairs(fillTypesToAdd) do
              self.fillTypes[fillType] = true;
          end
      end
  
      self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1);
      self.wasToFast = false;
      self.isTurnedOn = false;
  
      self.lastForageWagonArea = 0;
  
      self.forageWagonGroundFlag = self:getNextDirtyFlag();
      self.groundReferenceThreshold = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.groundReferenceNode#threshold"), 0.2);
      self.groundReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.groundReferenceNode#index"));
      self.sowingMachineContactReportsActive = false;
      self.hasGroundContact = false;
	  
      self.contactReportNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.contactReportNode#index"));
      if self.contactReportNode == nil then
          self.contactReportNode = self.components[1].node;
      end;
  
      self.contactReportNodes = {};
      local contactReportNodeFound = false;
      local i=0;
      while true do
          local baseName = string.format("vehicle.contactReportNodes.contactReportNode(%d)", i);
          local index = getXMLString(xmlFile, baseName.. "#index");
          if index == nil then
              break;
          end;
          local node = Utils.indexToObject(self.components, index);
          if node ~= nil then
              local entry = {};
              entry.node = node;
              entry.hasGroundContact = false;
  
              self.contactReportNodes[node] = entry;
              contactReportNodeFound = true;
          end;
          i = i+1;
      end;
      if not contactReportNodeFound then
          local entry = {};
          entry.node = self.contactReportNode;
          entry.hasGroundContact = false;
          self.contactReportNodes[entry.node] = entry;
      end;
end;
  
function FergForageWagon:delete()

end;
  
function FergForageWagon:readStream(streamId, connection)
      local turnedOn = streamReadBool(streamId);
      self:setIsTurnedOn(turnedOn, true);
end;
  
function FergForageWagon:writeStream(streamId, connection)
      streamWriteBool(streamId, self.isTurnedOn);
end;
  
function FergForageWagon:readUpdateStream(streamId, timestamp, connection)
        if connection:getIsServer() then
          self.sowingMachineHasGroundContact = streamReadBool(streamId);

      end;
end;
  
function FergForageWagon:writeUpdateStream(streamId, connection, dirtyMask)
      if not connection:getIsServer() then
          streamWriteBool(streamId, self.sowingMachineHasGroundContact);
      end;
end;
  
function FergForageWagon:mouseEvent(posX, posY, isDown, isUp, button)
end;
  
function FergForageWagon:keyEvent(unicode, sym, modifier, isDown)
end;
  
function FergForageWagon:update(dt)
  
      -- if self:getIsActiveForInput() then
          -- if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
              -- self:setIsTurnedOn(not self.isTurnedOn);
          -- end;
      -- end;
	  
	-- if self.isTurnedOn ~= nil then
	-- print(self.isTurnedOn);
	-- end;
end;
  
  function FergForageWagon:updateTick(dt)
      self.wasToFast = false;
      self.lastForageWagonArea = 0;
      if self:getIsActive() then
	  
          if self.isServer then
              local hasGroundContact = false;
  
  			if self.groundReferenceNode ~= nil then
  				local x,y,z = getWorldTranslation(self.groundReferenceNode);
  				local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 0, z);
  				if terrainHeight+self.groundReferenceThreshold >= y then
  					hasGroundContact = true;
  				end;
  			else
  				for k, v in pairs(self.contactReportNodes) do
  					if v.hasGroundContact then
  						hasGroundContact = true;
  						break;
  					end;
  				end;
  				if not hasGroundContact then
                      for k,v in pairs(self.wheels) do
                          if v.hasGroundContact then
                              hasGroundContact = true;
                              break;
                          end;
                      end;
                  end;
              end
              if self.sowingMachineHasGroundContact ~= hasGroundContact then
                  self:raiseDirtyFlags(self.forageWagonGroundFlag);
  
                  self.sowingMachineHasGroundContact = hasGroundContact;
              end;
          end;
          local hasGroundContact = self.sowingMachineHasGroundContact;	
		  if hasGroundContact then
				self.isTurnedOn = true;
			else
				self.isTurnedOn = false;
		  end;
          if self.isTurnedOn then
              if self.fillLevel < self.capacity then
  
                  local toFast = self:doCheckSpeedLimit() and self.lastSpeed*3600 > 29;
                  self.wasToFast = toFast;
                  if self.isServer then
                      if not toFast then
                          local cuttingAreasSend = {};
                          for k, cuttingArea in pairs(self.cuttingAreas) do
                              if self:getIsAreaActive(cuttingArea) then
                                  local x,y,z = getWorldTranslation(cuttingArea.start);
                                  local x1,y1,z1 = getWorldTranslation(cuttingArea.width);
                                  local x2,y2,z2 = getWorldTranslation(cuttingArea.height);
  
                                  table.insert(cuttingAreasSend, {x,z,x1,z1,x2,z2});
                              end;
                          end;
                          if (table.getn(cuttingAreasSend) > 0) then
                              local fruitTypeFix = false;
                              local fruitType = FruitUtil.FRUITTYPE_UNKNOWN;
                              if self.fillLevel > self.capacity*self.fillTypeChangeThreshold and FruitUtil.fillTypeToFruitType[self.currentFillType] ~= nil and FruitUtil.fillTypeIsWindrow[self.currentFillType] then
                                  fruitTypeFix = true;
                                  fruitType = FruitUtil.fillTypeToFruitType[self.currentFillType];
                              end
                              local area, usedFruitType = ForageWagonAreaEvent.runLocally(cuttingAreasSend, self.fillTypes, fruitTypeFix, fruitType);
                              if area > 0 then
                                  self.lastForageWagonArea = area;
  
                                  local pixelToSqm = g_currentMission:getFruitPixelsToSqm(); -- 4096px are mapped to 2048m
                                  local literPerSqm = FruitUtil.getFillTypeLiterPerSqm(FruitUtil.fruitTypeToWindrowFillType[usedFruitType], 1);
                                  local sqm = area*pixelToSqm;
  
                                  local deltaLevel = sqm*literPerSqm * self.fillScale;
  
                                  self:setFillLevel(self.fillLevel+deltaLevel, FruitUtil.fruitTypeToWindrowFillType[usedFruitType], true);
                                  g_server:broadcastEvent(ForageWagonAreaEvent:new(cuttingAreasSend, usedFruitType));
                              end;
                          end;
                      end;
                  end;
              end
          end;
  
      end;
end;
  
function FergForageWagon:draw()
      if self.wasToFast then
          g_currentMission:addWarning(g_i18n:getText("Dont_drive_to_fast") .. "\n" .. string.format(g_i18n:getText("Cruise_control_levelN"), "2"), 0.07+0.022, 0.019+0.029);
      end;
end;
  
function FergForageWagon:onDetach()
      -- self:setIsTurnedOn(false)
      if self.deactivateOnDetach then
          FergForageWagon.onDeactivate(self);
          FergForageWagon.removeContactReports(self);
      else

      end;
end;

function FergForageWagon:onAttach(attacherVehicle)
      -- self:setIsTurnedOn(true, false);
      FergForageWagon.addContactReports(self);	  
end;
  
function FergForageWagon:onLeave()
      if self.deactivateOnLeave then
          FergForageWagon.onDeactivate(self);
          FergForageWagon.removeContactReports(self);
      else
      end;
end;

function FergForageWagon:onEnter(isControlling)
      if isControlling then
          FergForageWagon.addContactReports(self);
      end;
end
  
function FergForageWagon:onDeactivate()
      self:setIsTurnedOn(false, true)
end;
  
function FergForageWagon:setIsTurnedOn(isTurnedOn, noEventSend)
      SetTurnedOnEvent.sendEvent(self, isTurnedOn, noEventSend)
      self.isTurnedOn = isTurnedOn;
end;

function FergForageWagon:addContactReports()
      if not self.sowingMachineContactReportsActive then
          for k, v in pairs(self.contactReportNodes) do
              addContactReport(v.node, 0.0001, "groundContactReport", self);
          end;
  
          self.sowingMachineContactReportsActive = true;
      end;
end;
  
function FergForageWagon:removeContactReports()
      if self.sowingMachineContactReportsActive then
          for k, v in pairs(self.contactReportNodes) do
              removeContactReport(v.node);
              v.hasGroundContact = false;
          end;
          self.sowingMachineContactReportsActive = false;
      end;
end;
  
function FergForageWagon:groundContactReport(objectId, otherObjectId, isStart, normalForce, tangentialForce)
      if otherObjectId == g_currentMission.terrainRootNode then
          local entry = self.contactReportNodes[objectId];
          if entry ~= nil then
              entry.hasGroundContact = isStart or normalForce > 0 or tangentialForce > 0;
          end;
      end;
end;
