
---xyzspain 




Lely_Tornado = {};

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

function Lely_Tornado:load(xmlFile)


-- desplazamiento de conjuntos
	self.setHydraulicDirection = SpecializationUtil.callSpecializationsFunction("setHydraulicDirection");
	
	local hydraulicsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hydraulics#count"), 0);	
	self.hydraulics = {};	
	for i=1, hydraulicsCount do
		local hydraulicName = string.format("vehicle.hydraulics.hydraulic%d", i);		
		self.hydraulics[i] = {};		
		self.hydraulics[i].node = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#index"));
		self.hydraulics[i].punch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punch"));
		self.hydraulics[i].translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punchFixpoint"));
		self.hydraulics[i].fixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#fixpoint"));	
		local ax, ay, az;		
		if self.hydraulics[i].punch ~= nil then
			ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
		else
			ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		end;
		local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);		
		self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		self.hydraulics[i].doScale = Utils.getNoNil(getXMLBool(xmlFile, hydraulicName .. "#doScale"), false);
	end;
	-------------------
---emision de particulas ruedas

self.wheelParticleSystems = {};
    local psFile = getXMLString(xmlFile, "vehicle.wheelParticleSystems#file");
    if psFile ~= nil then
        local i=0;
        while true do
            local baseName = string.format("vehicle.wheelParticleSystems.wheelParticleSystem(%d)", i);
            local node = getXMLString(xmlFile, baseName.. "#node");
            if node == nil then
                break;
            end;
            node = Utils.indexToObject(self.components, node);
			self.wheelParticleSystems.node = node;
            if node ~= nil then
                local wheelParticleSystem = {};
                wheelParticleSystem.particleSystems = {};
                Utils.loadParticleSystem(xmlFile, wheelParticleSystem.particleSystems, "vehicle.wheelParticleSystems", node, false, nil, self.baseDirectory);
                table.insert(self.wheelParticleSystems, wheelParticleSystem);
            end;
            i = i+1;
        end;
    end;
	
	--grassParticle
	self.grassParticleSystems = {};
    local psFile = getXMLString(xmlFile, "vehicle.grassParticleSystems#file");
    if psFile ~= nil then
        local i=0;
        while true do
            local baseName = string.format("vehicle.grassParticleSystems.grassParticleSystem(%d)", i);
            local node = getXMLString(xmlFile, baseName.. "#node");
            if node == nil then
                break;
            end;
            node = Utils.indexToObject(self.components, node);
			self.grassParticleSystems.node = node;
            if node ~= nil then
                local grassParticleSystem = {};
                grassParticleSystem.particleSystems = {};
                Utils.loadParticleSystem(xmlFile, grassParticleSystem.particleSystems, "vehicle.grassParticleSystems", node, false, nil, self.baseDirectory);
                table.insert(self.grassParticleSystems, grassParticleSystem);
            end;
            i = i+1;
        end;
    end;
	
	-------------
	-------------	piezas que copian rotacion de otras en funcion del contacto o no de estas con el suelo
	self.numWheelCenter = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.wheelCenter#count"), 0); 
	self.wheelCenter = {}; 
 for i=1, self.numWheelCenter do 
     local partnamei = string.format("vehicle.wheelCenter.part" .. "%d", i); 
     self.wheelCenter[i] = {}; 
     self.wheelCenter[i].index = Utils.indexToObject(self.components, getXMLString(xmlFile, partnamei.."#index")); 
   
 end;
		--------------------------
  local numRotParts = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.RotParts#count"), 0);
    self.RotParts = {};
    for i=1, numRotParts do
      local partnamei = string.format("vehicle.RotParts.part" .. "%d", i);
      self.RotParts[i] = {};
      self.RotParts[i].index = Utils.indexToObject(self.components, getXMLString(xmlFile, partnamei .. "#index"));
      local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partnamei .. "#minRot"));
      self.RotParts[i].minRot = {};
      self.RotParts[i].minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
      self.RotParts[i].minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
      self.RotParts[i].minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
      x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partnamei .. "#maxRot"));
      self.RotParts[i].maxRot = {};
      self.RotParts[i].maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
      self.RotParts[i].maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
      self.RotParts[i].maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
      self.RotParts[i].rotTime = Utils.getNoNil(getXMLString(xmlFile,  partnamei .. "#rotSpeed"), 2)*1000;
    end;	
	
self.rotParts =false;
	
				---libertad bloques
	self.setJointRotLimit = SpecializationUtil.callSpecializationsFunction("setJointRotLimit");
	self.firstDo = {};
	self.arm = {};
	self.setTransportMode = SpecializationUtil.callSpecializationsFunction("setTransportMode");
	self.setPickupMode = SpecializationUtil.callSpecializationsFunction("setPickupMode");
	self.allowPickingUp = Lely_Tornado.allowPickingUp;

	


	local path = Utils.getFilename("Balecounter_hud.dds", self.baseDirectory);
    self.balecounterHud = Overlay:new("counterOverlay", path, 0.8143, 0.8315, 0.176, 0.06638);
	
	self.baleCount = 0;
	self.baleMoveLastTime = 0;
	self.lastBaleCount = 0;
	
	
	
	
	
	
	
	self.isTurnedOn=false;
	self.free=false
	
	
	
end;

function Lely_Tornado:delete()
	if self.balecounterHud ~= nil then
		self.balecounterHud:delete();
	end;
	
	for i=1, table.getn(self.wheelParticleSystems) do
		Utils.deleteParticleSystem(self.wheelParticleSystems[i].particleSystems);
	end;
	
	for i=1, table.getn(self.grassParticleSystems) do
		Utils.deleteParticleSystem(self.grassParticleSystems[i].particleSystems);
	end;
			
end;



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

function Lely_Tornado:keyEvent(unicode, sym, modifier, isDown)

end;



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

function Lely_Tornado:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		self.baleCount = Utils.getNoNil(getXMLInt(xmlFile, key.."#baleCount"), 0);
		if self.animationParts[2].isLoading and self.animationParts[2].inputTime > self.animationParts[2].offSet then
			self:setTransportMode(true);
		end;
	end;
    return BaseMission.VEHICLE_LOAD_OK;
end;

function Lely_Tornado:update(dt)
	if self.attacherVehicle ~= nil then
		if self.fillLevel >= self.capacity / 2 then
			---renderText(0.1, 0.12, 0.03," capacity/2 ok  ");
		 self.rotParts=true;
		 elseif self.fillLevel == 0 then
		 self.rotParts=false;
		end;
		
	--if self.attacherVehicle.lastSpeed*3600 > 10 then
		for k=1,  table.getn(self.grassParticleSystems) do
			Utils.setEmittingState(self.grassParticleSystems[k].particleSystems, true);
		end;
	--end
	
	---emision de particulas-----------
	local dens = 0; local dens1; local dens2; local dens3;
	 local x,y,z = getWorldTranslation(self.wheels[1].repr);
	 local x1,y1,z1 = getWorldTranslation(self.wheels[2].repr);
	 local x2,y2,z2 = getWorldTranslation(self.wheels[1].repr);
	local id = g_currentMission.terrainDetailId;
	local xx, zz, widthX, widthZ, heightX, heightZ = Utils.getXZWidthAndHeight(id, x, z, x1, z1, x2, z2);
	dens1 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.cultivatorChannel, 1);
	dens2 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.sowingChannel, 1);
	dens3 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.ploughChannel, 1);
	if g_currentMission.environment.lastRainScale <= 0.1 and g_currentMission.environment.timeSinceLastRain > 30 then
		dens = dens1+dens2+dens3;
	end;
	if  self.lastSpeed*self.speedDisplayScale*3600 > 4 then
		if dens > 0 then
				for k=1,  table.getn(self.wheelParticleSystems) do
				Utils.setEmittingState(self.wheelParticleSystems[k].particleSystems, self.wheels[k].hasGroundContact);
			end;
		elseif dens <=0 then
			for i=1, table.getn(self.wheelParticleSystems) do
				Utils.setEmittingState(self.wheelParticleSystems[i].particleSystems, false);
			end;
		
		end;
	else
		for i=1, table.getn(self.wheelParticleSystems) do
				Utils.setEmittingState(self.wheelParticleSystems[i].particleSystems, false);
			end;
	end;	
		
		-------------------------- rotacion del rodillo pickup
		if self.wheels[3].hasGroundContact and self.isTurnedOn then
				
				local x1,y1,z1 = getRotation(self.wheels[3].repr);
				for i=1, self.numWheelCenter do 
				 setRotation(self.wheelCenter[i].index, math.abs(x1),math.abs(y1), math.abs(z1));
				end; 
			
		end;	
		
		
		
		 if self:getIsActiveForInput() then  
				if self.animationParts[2].clipEndTime then
					if InputBinding.hasEvent(InputBinding.PICKUP) then
						self:setPickupMode(not self.pickupMode);
					end;
					
				end;
				if self.animationParts[1].clipStartTime then
					if InputBinding.hasEvent(InputBinding.BALE) then
						self:setTransportMode(not self.transportMode);
					end;
				end;
		
				if InputBinding.hasEvent(InputBinding.RESET) then
					self.baleCount = 0;
				end;
				
				
	  end;---------active
	
				if self.fillLevel >= self.capacity  then
							
					self.isTurnedOn = false;
						---parada tractor en auto
						self.attacherVehicle.motor:setSpeedLevel(0, true);
					
					if self.isServer then
						 for i=3, table.getn(self.wheels) do
							local wheel = self.wheels[i];
							setWheelShapeProps(wheel.node, wheel.wheelShape, 0, 0, wheel.steeringAngle);
						end;
					end;
					
					
				elseif self.fillLevel < self.capacity  then
					if  self:getIsActiveForInput() then
							if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then ------test ok
							-- if self.animationParts[1].clipEndTime then
								 self.isTurnedOn = true;	
							end;
					end;
							
							
				end;
	

	    
	
	
	
	if  self.transportMode then
			self:setAnimationTime(2, self.animationParts[2].animDuration);	
	else
		self:setAnimationTime(2, self.animationParts[2].offSet);
	end;
	if not self.pickupMode then
		self:setAnimationTime(1, self.animationParts[1].offSet);
	else
		self:setAnimationTime(1, self.animationParts[1].animDuration);			
	end;
	
	
	
	
	if self.setAnimationTime ~= nil then
		if self.isTurnedOn then
			self:setAnimationTime(3, 1);
		else
			self:setAnimationTime(3, 0);
		end;
	end;
	
		
	-- end;  ---attacher
	 
	 
	 
		if self.rotParts ~= nil   then
				for i=1, table.getn(self.RotParts) do
					local rot = {getRotation(self.RotParts[i].index)};
					local newRot = Utils.getMovedLimitedValues(rot, self.RotParts[i].maxRot, self.RotParts[i].minRot, 3, self.RotParts[i].rotTime, dt, not self.rotParts);
					setRotation(self.RotParts[i].index, unpack(newRot));
				end;
		end;
	
	
	
	
		--- asignacion de ejes de libertad  de rotacion segun condiciones de emsamblage  0 x, 2 z ,1 y  
	end	
	
	
		
	 self:setJointRotLimit(self.componentJoints[1],20, 0, 1000,  self.animationParts[1].clipEndTime, 0,dt);	
	 self:setJointRotLimit(self.componentJoints[7],20, 10, 1000, self.animationParts[1].clipEndTime , 0,dt);	
	 self:setJointRotLimit(self.componentJoints[6],60, 0, 1000, self.free==true , 0,dt);	
	  self:setJointRotLimit(self.componentJoints[6],60, 0, 1000, self.free==true , 2,dt);
	self:setJointRotLimit(self.componentJoints[6],60, 0, 1000, self.free==true , 1,dt);	
	
	
		for i, jointDesc in pairs(self.componentJoints) do
			setJointFrame(self.componentJoints[i].jointIndex, 0, self.componentJoints[i].jointNode);
		end;
		
		
		
		self:setHydraulicDirection();	
	
end;

function Lely_Tornado:allowPickingUp()
	local allow = false;
	
		if self.animationParts[1].currentPosition > 300 then
				allow = true;
		end;
	
	return allow;
end;

function Lely_Tornado:setTransportMode(transportMode)
	TransportEvent.sendEvent(self, transportMode, noEventSend);
	self.transportMode = transportMode;
end;


function Lely_Tornado:setPickupMode(pickupMode)
	PickupEvent.sendEvent(self, pickupMode, noEventSend);
	self.pickupMode = pickupMode;
end;

	
function Lely_Tornado:updateTick(dt)	
	
	if self.balerUnloadingState == Baler.UNLOADING_CLOSED and table.getn(self.bales) > 0 then -- make bale invisible inside chamber, otherwise pops out before release of belt pressure
		  for i=1, table.getn(self.bales) do
				setVisibility(self.bales[i].id,false);
		  end
	end; --no reset needed, is handled by dropBale

	if table.getn(self.bales) > self.lastBaleCount then
		self.baleCount = self.baleCount + 1;
		self.lastBaleCount = self.lastBaleCount + 1;
		self.balerKnotCleaningTime = (self.time-50);
	elseif table.getn(self.bales) < self.lastBaleCount then
		self.lastBaleCount = self.lastBaleCount - 1;
	end;
end;

function Lely_Tornado:draw()
	
	
	if self.animationParts[1].clipStartTime  and self.animationParts[2].clipStartTime  then
		g_currentMission:addHelpButtonText(g_i18n:getText("Lely_Tornado_3"), InputBinding.BALE);
		g_currentMission:addExtraPrintText(g_i18n:getText("Lely_Tornado_5"));
			--g_currentMission:addExtraPrintText(g_i18n:getText("Lely_Tornado_10"));
	elseif self.animationParts[2].clipEndTime and  self.animationParts[2].clipStartTime  then 
		 g_currentMission:addHelpButtonText(g_i18n:getText("Lely_Tornado_4"), InputBinding.BALE);
	elseif self.animationParts[2].clipEndTime then
		if self.animationParts[1].clipStartTime then
			g_currentMission:addHelpButtonText(g_i18n:getText("Lely_Tornado_1"), InputBinding.PICKUP);
		elseif self.animationParts[1].clipEndTime  then
			g_currentMission:addHelpButtonText(g_i18n:getText("Lely_Tornado_2"), InputBinding.PICKUP);
			
		end;
		
		g_currentMission:addHelpButtonText(g_i18n:getText("Lely_Tornado_6"), InputBinding.RESET);
		self.balecounterHud:render();
		setTextAlignment(RenderText.ALIGN_RIGHT);
		setTextBold(true);	
		setTextColor(1, 1, 1, 1);
		renderText(0.9653, 0.849, 0.032, tostring(self.baleCount));
		setTextAlignment(RenderText.ALIGN_LEFT);
		setTextBold(false);	
	end;
	
end;

function Lely_Tornado:onAttach(attacherVehicle)
	--self.attacherVehicle = attacherVehicle;
	
	self.free=true
end;

function Lely_Tornado:onDetach()
	self.isTurnedOn = false;
	self.free=false
	
	self.detachTimer = 3000;
end;


function Lely_Tornado:readStream(streamId, connection)  
	self.baleCount = streamReadInt32(streamId);

	
end;

function Lely_Tornado:writeStream(streamId, connection)
	streamWriteInt32(streamId, self.baleCount);
	
	
end;
function Lely_Tornado:setJointRotLimit(nodei, up, down, speed, value, axle, dt)

	if not self.firstDo[nodei] then
		self.firstDo[nodei] = true;
		self.arm[nodei] = {0}; 
	end; 
	x, y, z = getRotation(nodei);
	rot = {x,y,z};	
	newRotLimit = {}; 
	newRotLimit[nodei] = {0,0,0};
	newRotLimit[nodei] = Utils.getMovedLimitedValues(self.arm[nodei], {down}, {up}, 1, speed * 2, dt, value);
	if math.abs(newRotLimit[nodei][1] - self.arm[nodei][1]) > 0.001 then
		local joint = nodei;
		setJointRotationLimit(joint.jointIndex, axle, true, Utils.degToRad(-newRotLimit[nodei][1]), Utils.degToRad(newRotLimit[nodei][1]));
	end;
	self.arm[nodei] = newRotLimit[nodei];			
end;
function Lely_Tornado:setHydraulicDirection()
	for i=1, table.getn(self.hydraulics) do
		local ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		local bx, by, bz = getWorldTranslation(self.hydraulics[i].fixPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.hydraulics[i].node), bx-ax, by-ay, bz-az);
		
		setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
		local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		if self.hydraulics[i].doScale then
			local xScale, yScale, zScale = getScale(self.hydraulics[i].node);
			local newScale = yScale * (distance / self.hydraulics[i].punchDistance);
			setScale(self.hydraulics[i].node, 1, 1, newScale);
		else
			if self.hydraulics[i].punch ~= nil then
				setTranslation(self.hydraulics[i].punch, 0, 0, distance-self.hydraulics[i].punchDistance);
			end;
		end;
	
	end;
end; 