--
-- Kverneland 3132MT 
-- Specialization for a mower.
--
-- author  	Henly20 
-- date  	19-12-2010.
-- www.ls-uk.info
-- ALL RIGHTS RESERVED
  
KevMT = {};
  
function KevMT.prerequisitesPresent(specializations)
		return true;
end;
  
function KevMT:load(xmlFile)

	  self.setTransRot = SpecializationUtil.callSpecializationsFunction("setTransRot");
	  self.TransRotAnimation = getXMLString(xmlFile, "vehicle.TransRot#animationName");
	  self.TransRot = false;
   	  self.setTransLift = SpecializationUtil.callSpecializationsFunction("setTransLift");
   	  self.TransLiftAnimation = getXMLString(xmlFile, "vehicle.TransLift#animationName");
	  self.TransLift = false;
      self.setIsTurnedOn = SpecializationUtil.callSpecializationsFunction("setIsTurnedOn");
      self.groundReferenceThreshold = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.groundReferenceNode#threshold"), 0.5);
      self.groundReferenceNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.groundReferenceNode#index"));
      if self.groundReferenceNode == nil then
          self.groundReferenceNode = self.components[2].node;
      end;
      
      if self.isClient then
          local mowerSound = getXMLString(xmlFile, "vehicle.mowerSound#file");
          if mowerSound ~= nil and mowerSound ~= "" then
              mowerSound = Utils.getFilename(mowerSound, self.baseDirectory); 
              self.mowerSound = createSample("mowerSound");
              self.mowerSoundEnabled = false;
              loadSample(self.mowerSound, mowerSound, false);
              self.mowerSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.mowerSound#pitchOffset"), 1);
              self.mowerSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.mowerSound#volume"), 1);
          end;
      end;
  
      local numCuttingAreas = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.cuttingAreas#count"), 0);
      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);
      end;
  
      self.isTurnedOn = false;
      self.wasToFast = false;
      
      self.mowerGroundFlag = self.nextDirtyFlag;
      self.nextDirtyFlag = self.mowerGroundFlag*2;

	  self.mowerParticleSystems = {};
      local i = 0;
      while true do
        local namei = string.format("vehicle.mowerParticleSystems.mowerParticleSystems(%d)", i);
		local nodei = Utils.indexToObject(self.components, getXMLString(xmlFile, namei .. "#index"));
		if nodei == nil then
			break;
		end; 
        Utils.loadParticleSystem(xmlFile, self.mowerParticleSystems, namei, nodei, false, nil, self.baseDirectory)		
		i = i +1;		
      end;
  
     self.onlyActiveWhenLowered = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.onlyActiveWhenLowered#value"), true);
	
      self.animTime = 0;	
      self.rotors = {};
  
      local i=0;
       while true do
          local baseName = string.format("vehicle.rotors.rotor(%d)", i);
          local node = {};
          node.index = getXMLString(xmlFile, baseName.. "#index");
          local direction = Utils.getNoNil(getXMLInt(xmlFile, baseName.. "#direction"), 1);
          node.speed = direction*Utils.getNoNil(getXMLFloat(xmlFile, baseName.. "#speed"), -0.01);
          if node.index == nil then
              break;
          end;
          node.index = Utils.indexToObject(self.components, node.index);
          if node.index ~= nil then
              table.insert(self.rotors, node);
          end;
          i = i+1;
      end;
	self.drumNode1 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.drum#index"));
    self.drumRotationScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.drum#rotationScale"), 1);
	
	self.pto = {};
	self.pto[1] = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.pto#index1"));
	self.pto[2] = Utils.indexToObject(self.components,getXMLString(xmlFile,"vehicle.pto#index2"));
	
	setVisibility(self.pto[1], true);
	setVisibility(self.pto[2], false);
	
    self.hudInfoBasePosX = 0.05;
    self.hudInfoBaseWidth = 0.16;
    self.hudInfoBasePosY = 0.1;
    self.hudInfoBaseHeight = 0.2;
    self.infoPanelPath = Utils.getFilename("kvernHud.png", self.baseDirectory);
	self.hudInfoBaseOverlay = Overlay:new("hudInfoBaseOverlay", self.infoPanelPath, self.hudInfoBasePosX, self.hudInfoBasePosY, self.hudInfoBaseWidth, self.hudInfoBaseHeight);
    self.showHudInfoBase = false;
end;
  
function KevMT:delete()
	Utils.deleteParticleSystem(self.mowerParticleSystems);
	
    if self.mowerSound ~= nil then
          delete(self.mowerSound);
    end;
	
 
end;
  
function KevMT:readStream(streamId, connection)
      local animTime = streamReadFloat32(streamId);
      KevMT.setRotorAnimTime(self, animTime);
	  
      local turnedOn = streamReadBool(streamId);
      self:setIsTurnedOn(turnedOn, true);
	  
      self:setTransLift(streamReadBool(streamId), true);	  
      self:setTransRot(streamReadBool(streamId), true);
end;
  
function KevMT:writeStream(streamId, connection)
      streamWriteFloat32(streamId, self.animTime);
      streamWriteBool(streamId, self.isTurnedOn);
	  
      streamWriteBool(streamId, self.TransLift);
      streamWriteBool(streamId, self.TransRot);
end;
  
function KevMT:readUpdateStream(streamId, timestamp, connection)
end;
  
function KevMT:writeUpdateStream(streamId, connection, dirtyMask)
end;
  
function KevMT:mouseEvent(posX, posY, isDown, isUp, button)
end;
  
function KevMT:keyEvent(unicode, sym, modifier, isDown)
      if self:getIsActiveForInput() then
		if isDown and sym == Input.KEY_KP_enter then
			self.showHudInfoBase = not self.showHudInfoBase;
		end;
	  end;
end;
  
function KevMT:update(dt)
  
      if self:getIsActiveForInput() then
          if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
              self:setIsTurnedOn(not self.isTurnedOn);
          end;
          if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
             self:setTransRot(not self.isTransRotOn);
          end;
          if InputBinding.hasEvent(InputBinding.ROTATEKEVLINKAGE) then
              self:setTransLift(not self.isTransLiftOn);
          end;
      end;
end;
  
function KevMT:updateTick(dt)
      self.wasToFast = false;
      if self:getIsActive() then
          if self.isTransRotOn then
				self.isTurnedOn = false;
          end;
          if self.isTurnedOn then
            self.animTime = self.animTime + dt;
            KevMT.setRotorAnimTime(self, self.animTime);
			if self.drumNode1 ~= nil then
				rotate(self.drumNode1, self.drumRotationScale * 5 * 1, 0, 0);
			end;
					
              local toFast = self:doCheckSpeedLimit() and self.lastSpeed*3600 > 31;
              if not toFast and (not self.onlyActiveWhenLowered or self:isLowered(false)) 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 foldAnimTime = self.foldAnimTime;
                          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});
                                  --Utils.updateMeadowArea(x, z, x1, z1, x2, z2);
                              end;
                          end;
                          if (table.getn(cuttingAreasSend) > 0) then
                              MowerAreaEvent.runLocally(cuttingAreasSend);
                              g_server:broadcastEvent(MowerAreaEvent:new(cuttingAreasSend));
                          end;
                      end;
                  end;
              end;
  
              if self.isClient then
                  if not self.mowerSoundEnabled and self:getIsActiveForSound() then
                      setSamplePitch(self.mowerSound, self.mowerSoundPitchOffset);
                      playSample(self.mowerSound, 0, self.mowerSoundVolume, 0);
                      self.mowerSoundEnabled = true;
                  end;
              end;
  
              self.wasToFast = toFast;
  
          else
              if self.isClient then
                  if self.mowerSoundEnabled then
                      stopSample(self.mowerSound);
                      self.mowerSoundEnabled = false;
                  end;
              end;
          end;
			
			if self.isTurnedOn and self.movingDirection ~= 0 and (not self.onlyActiveWhenLowered or self:isLowered(false)) and not self.isTransRotOn then
				Utils.setEmittingState(self.mowerParticleSystems, true);
			else
				Utils.setEmittingState(self.mowerParticleSystems, false);
			end;

      end;
end;
  
function KevMT:draw()
      if self.isClient 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;
		if self.showHudInfoBase then	
			g_currentMission:addExtraPrintText("Key Numpad Enter: Menu Off");
		else
			g_currentMission:addExtraPrintText("Key Numpad Enter: Menu On");
		end;

	if self.showHudInfoBase and self:getIsActive() then
		self.hudInfoBaseOverlay:render();
	end;  

          if self.wasToFast then
              g_currentMission:addWarning(g_i18n:getText("Dont_drive_to_fast") .. "\n" .. string.format(g_i18n:getText("Cruise_control_levelN"), "2", InputBinding.getKeyNamesOfDigitalAction(InputBinding.SPEED_LEVEL2)), 0.07+0.022, 0.019+0.029);
          end;
          if self.isTransRotOn and InputBinding.isPressed(InputBinding.IMPLEMENT_EXTRA) then
              g_currentMission:addWarning(string.format("Rotate to Field Position Before Turning On", 0.07+0.022, 0.019+0.029));
          end;
      end;
end;
  
function KevMT:onDetach()
      if self.deactivateOnDetach then
          KevMT.onDeactivate(self);
      else
          KevMT.onDeactivateSounds(self)
      end;
	if self.mowerParticleSystems ~= nil then
		Utils.setEmittingState(self.mowerParticleSystems, false);
	end;
	setVisibility(self.pto[2], true);
	setVisibility(self.pto[1], false);	
end;

function KevMT:onAttach(attacherVehicle)
	setVisibility(self.pto[1], true);
	setVisibility(self.pto[2], false);
end;
  
function KevMT:onLeave()
	if self.mowerParticleSystems ~= nil then
		Utils.setEmittingState(self.mowerParticleSystems, false);
	end; 

 if self.deactivateOnLeave then
          KevMT.onDeactivate(self);
      else
          KevMT.onDeactivateSounds(self)
      end;

	  self:setIsTurnedOn(false, true);

end;
  
function KevMT:onDeactivate()
      KevMT.onDeactivateSounds(self)
 
	  self:setIsTurnedOn(false, true);
	if self.mowerParticleSystems ~= nil then
		Utils.setEmittingState(self.mowerParticleSystems, false);
	end; 
end;
  
function KevMT:onDeactivateSounds()
      if self.isClient then
          if self.mowerSoundEnabled then
              stopSample(self.mowerSound);
              self.mowerSoundEnabled = false;
          end;
     end;
end;
  
function KevMT:setIsTurnedOn(turnedOn, noEventSend)
      SetTurnedOnEvent.sendEvent(self, turnedOn, noEventSend)
      self.isTurnedOn = turnedOn;
end;

function KevMT.setRotorAnimTime(self, animTime)
      self.animTime = animTime;
      for i=1, table.getn(self.rotors) do
          local rotor = self.rotors[i].index;
          local rotorRot = self.rotors[i].speed*animTime;
          --rotate(rotor, 0, rotorRot, 0);
          setRotation(rotor, 0 , rotorRot, 0);
      end;
end;

function KevMT:setTransLift(isTransLift,noEventSend)
	SetTransLiftEvent.sendEvent(self, isTransLift, noEventSend);
	-- Play TransLift animation --
	self.isTransLiftOn = isTransLift;
	if self.isTransLiftOn then
		if self.TransLiftAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.TransLiftAnimation, 1, nil, true);
			self.TransLift = true;
		end;
	else
		if self.TransLiftAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.TransLiftAnimation, -1, nil, true);
			self.TransLift = false;
		end;
	end;	
end;

function KevMT: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;

SetTransLiftEvent = {};
SetTransLiftEvent_mt = Class(SetTransLiftEvent, Event);

InitEventClass(SetTransLiftEvent, "SetTransLiftEvent");

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

function SetTransLiftEvent:new(vehicle, isTransLift)
    local self = SetTransLiftEvent:emptyNew()
    self.vehicle = vehicle;
	self.isTransLift = isTransLift;
    return self;
end;

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

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

function SetTransLiftEvent:run(connection)   
	self.vehicle:setTransLift(self.isTransLift, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(SetTransLiftEvent:new(vehicle, self.isTransLift), nil, connection, self.vehicle);
    end;
end;

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

