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

	  self.setCondPanel = SpecializationUtil.callSpecializationsFunction("setCondPanel");
	  self.CondPanelAnimation = getXMLString(xmlFile, "vehicle.CondPanel#animationName");
	  self.CondPanel = false;  
	  self.setAutoRight = SpecializationUtil.callSpecializationsFunction("setAutoRight");
	  self.AutoRightAnimation = getXMLString(xmlFile, "vehicle.AutoRight#animationName");
	  self.AutoRight = false;	  
      self.setConditionerOn = SpecializationUtil.callSpecializationsFunction("setConditionerOn");
	  self.conditionerNodeRight = {};
	  self.conditionerNodeRight.node  = Utils.indexToObject(self.components,getXMLString(xmlFile, "vehicle.conditionerNodeRight#index"));
	  self.setAutoLeft= SpecializationUtil.callSpecializationsFunction("setAutoLeft");
	  self.AutoLeftAnimation = getXMLString(xmlFile, "vehicle.AutoLeft#animationName");
	  self.AutoLeft= false;	  
      self.setConditionerOn = SpecializationUtil.callSpecializationsFunction("setConditionerOn");
	  self.conditionerNodeLeft = {};
	  self.conditionerNodeLeft.node  = Utils.indexToObject(self.components,getXMLString(xmlFile, "vehicle.conditionerNodeLeft#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 = {};
      self.accumulatedFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
      for i=1, numCuttingAreas do
          self.accumulatedCuttingAreaValues[i] = 0;
      end;
	  self.isTurnedOn = false;
	  self.isConditionerOn = false;
	  self.isAutoRightOn = false;  
	  self.isAutoLeftOn = false;  	  
      self.windrowerGroundFlag = self.nextDirtyFlag;
      self.nextDirtyFlag = self.windrowerGroundFlag*2;
	  self.printWarningTime = 0;	  
	  
      self.KevUVScrollParts = {};
      local i = 0;
      while true do
          local key = string.format("vehicle.KevUVScrollParts.KevUVScrollPart(%d)", i);
          if not hasXMLProperty(xmlFile, key) then
              break;
          end;
          local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
          local speed = Utils.getVectorNFromString(getXMLString(xmlFile, key.."#speed"), 2);
          if node ~= nil and speed then
              table.insert(self.KevUVScrollParts, {node=node, speed=speed});
          end;
          i = i +1;
      end;
	  
	  self.ASParticleSystems = {};
      local i = 0;
      while true do
        local namei = string.format("vehicle.ASParticleSystems.ASParticleSystem(%d)", i);
		local nodei = Utils.indexToObject(self.components, getXMLString(xmlFile, namei .. "#index"));
		if nodei == nil then
			break;
		end; 
        Utils.loadParticleSystem(xmlFile, self.ASParticleSystems, namei, nodei, false, nil, self.baseDirectory)		
		i = i +1;		
      end;
	  
      self.TarUVScrollParts = {};
      local i = 0;
      while true do
          local key = string.format("vehicle.TarUVScrollParts.TarUVScrollPart(%d)", i);
          if not hasXMLProperty(xmlFile, key) then
              break;
          end;
          local node = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
          local speed = Utils.getVectorNFromString(getXMLString(xmlFile, key.."#speed"), 2);
          if node ~= nil and speed then
              table.insert(self.TarUVScrollParts, {node=node, speed=speed});
          end;
          i = i +1;
      end;
	  
	  self.ASParticleSystemsLeft = {};
      local i = 0;
      while true do
        local namei = string.format("vehicle.ASParticleSystemsLeft.ASParticleSystem(%d)", i);
		local nodei = Utils.indexToObject(self.components, getXMLString(xmlFile, namei .. "#index"));
		if nodei == nil then
			break;
		end; 
        Utils.loadParticleSystem(xmlFile, self.ASParticleSystemsLeft, namei, nodei, false, nil, self.baseDirectory)		
		i = i +1;		
      end;	  
end;
  
function TaarupCondAS:delete()
	if self.ASParticleSystems ~= nil then	
		Utils.deleteParticleSystem(self.ASParticleSystems);
	end;
	if self.ASParticleSystemsLeft ~= nil then	
		Utils.deleteParticleSystem(self.ASParticleSystemsLeft); 
	end;
end;
  
function TaarupCondAS:mouseEvent(posX, posY, isDown, isUp, button)
end;
  
function TaarupCondAS:keyEvent(unicode, sym, modifier, isDown)
end;
  
function TaarupCondAS:readStream(streamId, connection)
      local isConditionerOn = streamReadBool(streamId);
      self:setConditionerOn(isConditionerOn, true);
      self:setCondPanel(streamReadBool(streamId), true);
      self:setAutoRight(streamReadBool(streamId), true);	
      self:setAutoLeft(streamReadBool(streamId), true)	  
end;
  
function TaarupCondAS:writeStream(streamId, connection)
      streamWriteBool(streamId, self.isConditionerOn);
      streamWriteBool(streamId, self.isCondPanel);
	  streamWriteBool(streamId, self.AutoRight);	  
	  streamWriteBool(streamId, self.AutoLeft);	 
end;
  
function TaarupCondAS:readUpdateStream(streamId, timestamp, connection)
end;
  
function TaarupCondAS:writeUpdateStream(streamId, connection, dirtyMask)
end;
  
function TaarupCondAS:update(dt)
  
	if not self:getIsActive() then
		if self.conditionerInRange or self.conditionerInRangeLeft then
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA3) and (self.isAutoLeftOn and self.isAutoRightOn) then
				self:setCondPanel(not self.isCondPanel);

			end;				
			if self.isAutoLeftOn and self.isAutoRightOn then
				if self.isCondPanel 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;
	
	if self:getIsActiveForInput() then
			if InputBinding.hasEvent(InputBinding.TAARUP5090_AUTO_RIGHT) and not self.isCondPanel and not self.isTransport then
				self:setAutoRight(not self.isAutoRightOn);				
			end;
			if InputBinding.hasEvent(InputBinding.TAARUP5090_AUTO_LEFT) and not self.isCondPanel and not self.isTransport then
				self:setAutoLeft(not self.isAutoLeftOn);				
			end;	
			if InputBinding.hasEvent(InputBinding.TAARUP5090_TRANSPORT) then
				self:setAutoLeft(false);
				self:setAutoRight(false);	
				self:setCondPanel(false);				
			end;
	end;
end;
  
function TaarupCondAS:updateTick(dt)

		if g_currentMission.player ~= nil then
			local nearestDistance = 3;
			local vx, vy, vz = getWorldTranslation(g_currentMission.player.rootNode);		
			local px, py, pz = getWorldTranslation(self.conditionerNodeRight.node); 
			local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);	
			local ax, ay, az = getWorldTranslation(self.conditionerNodeLeft.node); 
			local distance1 = Utils.vector3Length(ax-vx, ay-vy, az-vz);				
			if distance < nearestDistance then
				self.conditionerInRange = true; 
			else
				self.conditionerInRange = false; 
			end;
			if distance1 < nearestDistance then
				self.conditionerInRangeLeft = true; 
			else
				self.conditionerInRangeLeft = false; 
			end;			
		end;
		
    if self:getIsActive() then
		if not self.isCondPanel then
			self:setConditionerOn(true);
			else
			self:setConditionerOn(false);
		end;
          if self.isConditionerOn and self.isTurnedOn then
              if self.isServer then
                  local toFast = self:doCheckSpeedLimit() and self.lastSpeed*3600 > 31;
                  if not toFast 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 cuttingAreasSend = {};
                              local dropAreasSend = {};
                              for i=1, numAreas do
                                  local cuttingArea = self.cuttingAreas[i];
                                  if self:getIsAreaActive(cuttingArea) then
                                      local x,_,z = getWorldTranslation(cuttingArea.start);
                                      local x1,_,z1 = getWorldTranslation(cuttingArea.width);
                                      local x2,_,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, self.accumulatedFruitType);
                                  if table.getn(cuttingAreasSend) > 0 or table.getn(dropAreasSend) > 0 then
                                      self.accumulatedFruitType = fruitType
                                      g_server:broadcastEvent(WindrowAreaEvent:new(cuttingAreasSend, dropAreasSend, fruitType, bitType));
                                  end;
                              end;
                          end;
                      end;
                  end;
  
                  self.wasToFast = toFast;
              end;
			end;
		local foldingArmRight = self.mowerFoldingParts[1].mainPart;
		local foldingArmLeft = self.mowerFoldingParts[2].mainPart;
		for _, part in pairs(self.KevUVScrollParts) do
			if self.isTurnedOn and not self.isAutoRightOn then	
				setShaderParameter(part.node, "uvScrollSpeed", part.speed[1], part.speed[2], 0, 0, false);
			else
				setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
			end;
		end;
		if self.isTurnedOn and self.movingDirection ~= 0 and not self.isAutoRightOn and self.lastAreaBiggerZero and foldingArmRight.isDown then
			Utils.setEmittingState(self.ASParticleSystems, true);
		else
			Utils.setEmittingState(self.ASParticleSystems, false);
		end;	
		for _, part in pairs(self.TarUVScrollParts) do
			if self.isTurnedOn and not self.isAutoLeftOn then	
				setShaderParameter(part.node, "uvScrollSpeed", part.speed[1], part.speed[2], 0, 0, false);
			else
				setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
			end;
		end;
		if self.isTurnedOn and self.movingDirection ~= 0 and not self.isAutoLeftOn and self.lastAreaBiggerZero and foldingArmLeft.isDown then
			Utils.setEmittingState(self.ASParticleSystemsLeft, true);
		else
			Utils.setEmittingState(self.ASParticleSystemsLeft, false);
		end;			
      end;
end;
  
function TaarupCondAS:draw()
    if self.isClient then
		if self.isConditionerOn and not self.isTransport then
			if not self.isCondPanel then
				if not self.isAutoRightOn then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("raiserightAS"), self.typeDesc), InputBinding.TAARUP5090_AUTO_RIGHT);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("lowerrightAS"), self.typeDesc), InputBinding.TAARUP5090_AUTO_RIGHT);
				end;
				if not self.isAutoLeftOn then
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("raiseLeftAS"), self.typeDesc), InputBinding.TAARUP5090_AUTO_LEFT);
				else
					g_currentMission:addHelpButtonText(string.format(g_i18n:getText("lowerLeftAS"), self.typeDesc), InputBinding.TAARUP5090_AUTO_LEFT);
				end;			
			end;
		end;
	end;
end;
  
function TaarupCondAS:onDetach()
	if self.ASParticleSystems ~= nil then
		Utils.setEmittingState(self.ASParticleSystems, false);
	end;
	if self.ASParticleSystemsLeft ~= nil then
		Utils.setEmittingState(self.ASParticleSystemsLeft, false);
	end;
	for _, part in pairs(self.KevUVScrollParts) do
		setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
	end;
	for _, part in pairs(self.TarUVScrollParts) do
		setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
	end;	
end;
  
function TaarupCondAS:onLeave()
	if self.deactivateOnLeave then
		TaarupCondAS.onDeactivate(self);
	else
		TaarupCondAS.onDeactivateSounds(self);
	end;
	if self.ASParticleSystems ~= nil then
		Utils.setEmittingState(self.ASParticleSystems, false);
	end; 
	if self.ASParticleSystemsLeft ~= nil then
		Utils.setEmittingState(self.ASParticleSystemsLeft, false);
	end; 	
end;


  
function TaarupCondAS:onDeactivate()
	for _, part in pairs(self.KevUVScrollParts) do
		setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
	end;
	for _, part in pairs(self.TarUVScrollParts) do
		setShaderParameter(part.node, "uvScrollSpeed", 0, 0, 0, 0, false);
	end;	
	if self.ASParticleSystems ~= nil then
		Utils.setEmittingState(self.ASParticleSystems, false);
	end; 	
	if self.ASParticleSystemsLeft ~= nil then
		Utils.setEmittingState(self.ASParticleSystemsLeft, false);
	end; 	
end;
  
function TaarupCondAS:onDeactivateSounds()

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

function TaarupCondAS:setCondPanel(isCondPanel,noEventSend)
	SetCondPanelEvent.sendEvent(self, isCondPanel, noEventSend);
	self.isCondPanel = isCondPanel;
	if self.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;

function TaarupCondAS:setAutoRight(isAutoRight,noEventSend)
	SetAutoRightEvent.sendEvent(self, isAutoRight, noEventSend);
	-- Play AutoRight animation --
	self.isAutoRightOn = isAutoRight;
	if self.isAutoRightOn then
		if self.AutoRightAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.AutoRightAnimation, 1, nil, true);
			self.AutoRight = true;
		end;
	else
		if self.AutoRightAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.AutoRightAnimation, -1, nil, true);
			self.AutoRight = false;
		end;
	end;	
end;

function TaarupCondAS:setAutoLeft(isAutoLeft,noEventSend)
	SetAutoLeftEvent.sendEvent(self, isAutoLeft, noEventSend);
	-- Play AutoLeftanimation --
	self.isAutoLeftOn = isAutoLeft;
	if self.isAutoLeftOn then
		if self.AutoLeftAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.AutoLeftAnimation, 1, nil, true);
			self.AutoLeft= true;
		end;
	else
		if self.AutoLeftAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.AutoLeftAnimation, -1, nil, true);
			self.AutoLeft= false;
		end;
	end;	
end;
