--
-- Kverneland 4028 
-- Specialization conditioning on a mower.
--
-- author  	Henly20 
-- date  	19-12-2010.
-- www.ls-uk.info
-- ALL RIGHTS RESERVED
  
KevCond = {};
  
function KevCond.prerequisitesPresent(specializations)
 	return SpecializationUtil.hasSpecialization(KevMT, specializations);
end;
  
function KevCond:load(xmlFile)

	  self.setCondPanel = SpecializationUtil.callSpecializationsFunction("setCondPanel");
	  self.CondPanelAnimation = getXMLString(xmlFile, "vehicle.CondPanel#animationName");
	  self.CondPanel = true;  
      self.setConditionerOn = SpecializationUtil.callSpecializationsFunction("setConditionerOn");
	  self.conditionerNode = {};
	  self.conditionerNode.node  = Utils.indexToObject(self.components,getXMLString(xmlFile, "vehicle.conditionerNode#index"));

      self.groundReferenceThreshold = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.groundReferenceNode#threshold"), 0.2);
      self.groundReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.groundReferenceNode#index"));
      if self.groundReferenceNode == nil then
          self.groundReferenceNode = self.components[1].node;
      end;
  
      local numWindrowerDropAreas = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.windrowerDropAreas#count"), 0);
      if numWindrowerDropAreas == 0 then
          print("Warning: No drop areas specified in '"..self.configFileName.."'");
      else
          if numWindrowerDropAreas ~= 1 and numWindrowerDropAreas ~= table.getn(self.cuttingAreas) then
              print("Warning: Number of cutting areas and drop areas should be equal in '"..self.configFileName.."'");
          end;
      end;
      self.windrowerDropAreas = {}
      for i=1, numWindrowerDropAreas do
          self.windrowerDropAreas[i] = {};
          local areanamei = string.format("vehicle.windrowerDropAreas.windrowerDropArea%d", i);
          self.windrowerDropAreas[i].start = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#startIndex"));
          self.windrowerDropAreas[i].width = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#widthIndex"));
          self.windrowerDropAreas[i].height = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#heightIndex"));
      end;
  
      local numCuttingAreas = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.cuttingAreas#count"), 0);
      self.accumulatedCuttingAreaValues = {};
      for i=1, numCuttingAreas do
          local areanamei = string.format("vehicle.cuttingAreas.cuttingArea%d", i);
          self.cuttingAreas[i].foldMinLimit = Utils.getNoNil(getXMLFloat(xmlFile, areanamei .. "#foldMinLimit"), 0);
          self.cuttingAreas[i].foldMaxLimit = Utils.getNoNil(getXMLFloat(xmlFile, areanamei .. "#foldMaxLimit"), 1);
          self.accumulatedCuttingAreaValues[i] = 0;
      end;
	  self.isTurnedOn = false;
	  self.isConditionerOn = false;
  
      self.windrowerGroundFlag = self.nextDirtyFlag;
      self.nextDirtyFlag = self.windrowerGroundFlag*2;
end;
  
function KevCond:delete()

  
end;
  
function KevCond:mouseEvent(posX, posY, isDown, isUp, button)
end;
  
function KevCond:keyEvent(unicode, sym, modifier, isDown)
end;

function KevCond:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then

	end;
    return BaseMission.VEHICLE_LOAD_OK;
end;

function KevCond:getSaveAttributesAndNodes(nodeIdent)

end;
  
function KevCond:readStream(streamId, connection)
      local isConditionerOn = streamReadBool(streamId);
      self:setConditionerOn(isConditionerOn, true);
      self:setCondPanel(streamReadBool(streamId), true);
end;
  
function KevCond:writeStream(streamId, connection)
      streamWriteBool(streamId, self.isConditionerOn);
      streamWriteBool(streamId, self.CondPanel);
end;
  
function KevCond:readUpdateStream(streamId, timestamp, connection)
end;
  
function KevCond:writeUpdateStream(streamId, connection, dirtyMask)
end;
  
function KevCond:update(dt)
  
	if not self:getIsActive() then
		if self.conditionerInRange then
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) then

				self:setCondPanel(not self.CondPanel);
			end;
			if self.CondPanel then
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("conditionerOn"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA3);
			else
				g_currentMission:addHelpButtonText(string.format(g_i18n:getText("conditionerOff"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA3);
			end;
		end;
	end;
end;
  
function KevCond:updateTick(dt)

		if g_currentMission.player ~= nil then
			local nearestDistance = 1.5;
			local vx, vy, vz = getWorldTranslation(g_currentMission.player.rootNode);		
			local px, py, pz = getWorldTranslation(self.conditionerNode.node); 
			local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);	
			if distance < nearestDistance then
				self.conditionerInRange = true; 
			else
				self.conditionerInRange = false; 
			end;
		end;
		
    if self:getIsActive() then
		if self.CondPanel then
			self:setConditionerOn(false);
			else
			self:setConditionerOn(true);
		end;
          if self.isConditionerOn and self.isTurnedOn and not self.isWheelRotOn then
              if self.isServer then
                      local x,y,z = getWorldTranslation(self.groundReferenceNode);
                      local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, x, 0, z);
                      if terrainHeight+self.groundReferenceThreshold >= y then
                          local numDropAreas = table.getn(self.windrowerDropAreas);
                          local numAreas = table.getn(self.cuttingAreas);
                          if numDropAreas > 0 and numAreas > 0 then
                              local sum = 0;
                              local fruitType = FruitUtil.FRUITTYPE_GRASS;
                              local fruitTypeFix = false;
                              local cuttingAreasSend = {};
                              local dropAreasSend = {};
                              for i=1, numAreas do
                                  local cuttingArea = self.cuttingAreas[i];
                                  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;
                              for i=1, numDropAreas do
                                  local dropArea = self.windrowerDropAreas[i];
                                  local dx,dy,dz = getWorldTranslation(dropArea.start);
                                  local dx1,dy1,dz1 = getWorldTranslation(dropArea.width);
                                  local dx2,dy2,dz2 = getWorldTranslation(dropArea.height);
                                  table.insert(dropAreasSend, {dx, dz, dx1, dz1, dx2, dz2});
                              end;
                              if table.getn(cuttingAreasSend) > 0 then
                                  local cuttingAreasSend, dropAreasSend, fruitType, bitType = WindrowAreaEvent.runLocally(cuttingAreasSend, dropAreasSend, self.accumulatedCuttingAreaValues);
                                  if table.getn(cuttingAreasSend) > 0 then
                                      g_server:broadcastEvent(WindrowAreaEvent:new(cuttingAreasSend, dropAreasSend, fruitType, bitType));
                                  end;
                              end;
                          end;
                      end;

              end;
			end;

      end;
end;
  
function KevCond:draw()

end;
  
function KevCond:onDetach()



end;
  
function KevCond:onLeave()

	  self:setConditionerOn(false, true);

end;
  
function KevCond:onDeactivate()

end;
  
function KevCond:onDeactivateSounds()

end;
  
function KevCond:setConditionerOn(isConditionerOn, noEventSend)
      SetConditionerOnEvent.sendEvent(self, isConditionerOn, noEventSend)
      self.isConditionerOn = isConditionerOn;
end;

function KevCond:setCondPanel(isCondPanel,noEventSend)
	SetCondPanelEvent.sendEvent(self, isCondPanel, noEventSend);

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

SetCondPanelEvent = {};
SetCondPanelEvent_mt = Class(SetCondPanelEvent, Event);

InitEventClass(SetCondPanelEvent, "SetCondPanelEvent");

function SetCondPanelEvent:emptyNew()
    local self = Event:new(SetCondPanelEvent_mt);
    self.className="SetCondPanelEvent";
    return self;
end;

function SetCondPanelEvent:new(vehicle, isCondState)
    local self = SetCondPanelEvent:emptyNew()
    self.vehicle = vehicle;
	self.isCondPanelState = isCondState;
    return self;
end;

function SetCondPanelEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.isCondPanelState = streamReadBool(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function SetCondPanelEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.isCondPanelState);
end;

function SetCondPanelEvent:run(connection)   
	self.vehicle:setCondPanel(self.isCondPanelState, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(SetCondPanelEvent:new(self.vehicle, self.isCondPanelState), nil, connection, self.vehicle);
    end;
end;

function SetCondPanelEvent.sendEvent(vehicle, isCondState, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetCondPanelEvent:new(vehicle, isCondState), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetCondPanelEvent:new(vehicle, isCondState));
		end;
	end;
end;

SetConditionerOnEvent = {};
SetConditionerOnEvent_mt = Class(SetConditionerOnEvent, Event);
  
InitEventClass(SetConditionerOnEvent, "SetConditionerOnEvent");
  
function SetConditionerOnEvent:emptyNew()
     local self = Event:new(SetConditionerOnEvent_mt);
      self.className="SetConditionerOnEvent";
      return self;
end;
  
function SetConditionerOnEvent:new(object, condtionerOn)
      local self = SetConditionerOnEvent:emptyNew()
      self.object = object;
      self.condtionerOn = condtionerOn;
      return self;
end;
  
function SetConditionerOnEvent:readStream(streamId, connection)
      local id = streamReadInt32(streamId);
      self.condtionerOn = streamReadBool(streamId);
      self.object = networkGetObject(id);
      self:run(connection);
end;
  
function SetConditionerOnEvent:writeStream(streamId, connection)
      streamWriteInt32(streamId, networkGetObjectId(self.object));
      streamWriteBool(streamId, self.condtionerOn);
end;
  
function SetConditionerOnEvent:run(connection)
      if not connection:getIsServer() then
         g_server:broadcastEvent(self, false, connection, self.object);
      end;
      self.object:setConditionerOn(self.condtionerOn, true);
end;
  
function SetConditionerOnEvent.sendEvent(vehicle, condtionerOn, noEventSend)
      if condtionerOn ~= vehicle.isConditionerOn then
          if noEventSend == nil or noEventSend == false then
              if g_server ~= nil then
                  g_server:broadcastEvent(SetConditionerOnEvent:new(vehicle, condtionerOn), nil, nil, vehicle);
              else
                  g_client:getServerConnection():sendEvent(SetConditionerOnEvent:new(vehicle, condtionerOn));
              end;
          end;
      end;
end;