--
-- fertilizerSiloTrigger
-- Specialization for fertilizerSiloTrigger
--
-- @author Felix "Outlaw" Sorge
-- @date  20/05/09
-- @web www.ls-modsource.de - www.ls-mods.de
--
-- Converted to 2011 and edited by Timbertaz
--

fertilizerSiloTrigger = {};

function fertilizerSiloTrigger.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Trailer, specializations);
end;

function fertilizerSiloTrigger:load(xmlFile)
 
local workSound = getXMLString(xmlFile, "vehicle.workSound#file");
    if workSound ~= nil and workSound ~= "" then
        workSound = Utils.getFilename(workSound, self.baseDirectory); 
        self.workSound = createSample("workSound");
        self.workSoundEnabled = false;
        loadSample(self.workSound, workSound, false);
        self.workSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.workSound#pitchOffset"), 1);
        self.workSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.workSound#volume"), 1);
    end;  
    
    
self.drumNodeRotary = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rotary#index"));
self.drumRotationScale2 = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotary#rotationScale"), 1);
self.farmer = false;
self.tankerReady = false;
self.overload =false;
self.xActivated = false;

   self.pipeParticleSystem = {};
    self.pipeParticleSystemindex = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.pipeParticleSystem#index"));
    Utils.loadParticleSystem(xmlFile, self.pipeParticleSystem, "vehicle.pipeParticleSystem", self.pipeParticleSystemindex, false, nil, self.baseDirectory);
    self.pipeParticleActivated  = false;
     

      self.exhaustParticleSystem = {};
    self.exhaustParticleSystemindex = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.exhaustParticleSystem#index"));
    Utils.loadParticleSystem(xmlFile, self.exhaustParticleSystem, "vehicle.exhaustParticleSystem", self.exhaustParticleSystemindex, false, nil, self.baseDirectory);
    self.exhaustParticleActivated  = false;
     self.fertilizerInLowRange = SpecializationUtil.callSpecializationsFunction("fertilizerInLowRange");

     self.fertilizerInTankerRange = SpecializationUtil.callSpecializationsFunction("fertilizerInTankerRange");
	self.farmerInRange = SpecializationUtil.callSpecializationsFunction("farmerInRange");
	

	self.connectCollisions = SpecializationUtil.callSpecializationsFunction("connectCollisions");
	self.anim = SpecializationUtil.callSpecializationsFunction("anim");
	self.Go = {}; 
	self.Done = {};
	self.charId = {};
	self.clipIndex = {};
	self.CheckDone = {};
	self.moveColli = {}; 
    self.animParts = {}
	self.collisionArm = {}; 
	local count = getXMLInt(xmlFile, "vehicle.animParts#count");
	local part = self.animParts;
    for i=1, count do
		part[i] = {};
        local partname = string.format("vehicle.animParts.part".."%d", i);
	    local nameR = getXMLString(xmlFile, partname.."#name");
		self.charId[nameR] = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.."#rootNode"));
		self.clipIndex[nameR] = getXMLString(xmlFile, partname.."#animationClip");
		self.CheckDone[nameR] = false;
		self.moveColli[nameR] = getXMLString(xmlFile, partname.."#moveColli");
		if self.moveColli[nameR] ~= nil then
			local Collision = {};
			Collision.collision = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.."#collision"));
			Collision.collisionAttacher = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.."#collsionAttacher"));
			Collision.armAttacher = Utils.indexToObject(self.components, getXMLString(xmlFile, partname.. "#armAttacher"));
			Collision.index = 0;
			self.collisionArm[nameR] = Collision;
			self:connectCollisions(nameR);
		end; 
	end; 
			
	
	self.literPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.literPerSecond#value"), 1);
	self.fillPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillPerSecond#value"), 1);
        self.maxLevel = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.capacity#value"), 1);
	self.checkType = getXMLString(xmlFile, "vehicle.fillTypes#fruitTypes");
	self.fillLowNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fillNode#lower"));
	self.fillArmNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fillNode#arm"));
        self.fillTankerNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.fillNode#lower"));
	self.comp1Node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.comp1Node#index"));
	self.comp0Node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.comp0Node#index"));
	self.palletNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.palletNode#index"));
	self.buildNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.buildNode#index"));
	self.compLink = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.compLink#index"));
	self.pumpNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pumpNode#index"));
	self.pumpPipesNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pumpPipesNode#index"));
	self.manurePlaneNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.manurePlaneNode#index"));
	self.modus = 0; 
	self.keyType = InputBinding.getKeyNamesOfDigitalAction;
	self.keyName = "Taste"; 
	
	if self.fillLevel == 0 or self.fillLevel == nil then
	self:setFillLevel(1, FruitUtil.FRUITTYPE_FERTILIZER);
	end;
	
end;

function fertilizerSiloTrigger:update(dt)

    if InputBinding.hasEvent(InputBinding.FERTILIZERSILOSTART) then
		   	    if self.pipeParticleActivated   == false then
		   	     self.pipeParticleActivated = true
		   	    

		   	else
		   		self.pipeParticleActivated = false
               
		    end;
		end;
											    
	  if  self.pipeParticleActivated   then
	    Utils.setEmittingState(self.pipeParticleSystem, true);
	    else
	    Utils.setEmittingState(self.pipeParticleSystem, false);
	   end;

if self.fillLevel ==0 or self.fillLevel== self.maxLevel then
 Utils.setEmittingState(self.pipeParticleSystem, false);
end;
                 
	
	if self.modus == 0 then
	-- nur palette / only palett
	setVisibility(self.pumpNode, false);
	setVisibility(self.pumpPipesNode, false);
	setVisibility(self.manurePlaneNode, false);
		setVisibility(self.comp1Node, false);
		setVisibility(self.buildNode, false);
		setVisibility(self.palletNode, true);
		setCollisionMask(self.comp1Node, 0)
		setRigidBodyType(self.comp1Node, "None");
		link(self.compLink, self.comp1Node);
		setTranslation(self.comp1Node, 0,0,0)
		setRotation(self.comp1Node, 0,0,0)
			
	elseif self.modus == 1 then		
	-- platte weg und bauansicht / without palett only buildplan
		setVisibility(self.buildNode, true);
		setVisibility(self.palletNode, true);
		
		
	elseif self.modus == 2 then
	-- aufbau / buliding...			
		setCollisionMask(self.comp1Node, 2102)
		setRigidBodyType(self.comp1Node, "Kinematic");
		setCollisionMask(self.comp0Node, 0)
		setRigidBodyType(self.comp0Node, "None");
			
		if not self.Go.build then
			self.Go.build = not self.Go.build; 
			self.Done.build = true; 
		end; 
		
	elseif self.modus == 3 then
	-- trigger ist aufgebaut mit fuellfunktion / build done - fill works
		if not self.firstRun then
			self.firstRun = true; 
		--	FruitUtil.fruitIndexToDesc[self.currentFillType].pricePerLiter = self.pricePerLiter;
		--	FruitUtil.fruitIndexToDesc[self.currentFillType].literPerSqm = self.literPerSqm;
		     self.currentFillType = Fillable.FILLTYPE_FERTILIZER;
		     setVisibility(self.pumpNode, true);
	         setVisibility(self.pumpPipesNode, true);
	         setVisibility(self.manurePlaneNode, true);
			setVisibility(self.buildNode, false);
			setVisibility(self.comp1Node, true);
			setVisibility(self.palletNode, false);
			setCollisionMask(self.comp1Node, 0)
			setRigidBodyType(self.comp1Node, "None");
            link(self.compLink, self.comp1Node);
			setTranslation(self.comp1Node, 0,0,0)
			setRotation(self.comp1Node, 0,0,0)
			setCollisionMask(self.comp1Node, 2102)
			setRigidBodyType(self.comp1Node, "Kinematic");
			setCollisionMask(self.comp0Node, 0)
			setRigidBodyType(self.comp0Node, "None");
			self.startTractor = true;
		end;
		
		local newFill = self.fillPerSecond*dt/1000.0
		self:setFillLevel(self.fillLevel + newFill, FruitUtil.FRUITTYPE_FERTILIZER);
		self:fertilizerInLowRange(dt);

		self:fertilizerInTankerRange(dt);

	elseif self.modus == 4 then
		-- wieder einpacken, wurde schon ausgeführt  / rebuild 
		setVisibility(self.buildNode, true);
		g_currentMission:addExtraPrintText(g_i18n:getText("fertilizerSiloTrigger_6"));
	end; 	
	
	
		
	if self.CheckDone.build then
		-- aufbau fertig / build done
		self.modus = 3; 
		setVisibility(self.buildNode, false);
		setVisibility(self.comp1Node, true);
	end; 
		
	if self.Go.build ~= nil and self.Done.build ~= false then
		self:anim("build", false); 
	end; 
	
	if not self.firstRunLvl then

		self.firstRunLvl = true;
		--FruitUtil.fruitIndexToDesc[self.currentFillType].pricePerLiter = self.pricePerLiter;
		--FruitUtil.fruitIndexToDesc[self.currentFillType].literPerSqm = self.literPerSqm;
		self.currentFillType = Fillable.FILLTYPE_FERTILIZER;	
	end; 

	if self.inLowRange   then
		if self.fillLowGo   then
			g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.fertilizerSiloTrigger_refuel).. ": " ..g_i18n:getText("fertilizerSiloTrigger_8"));
		else
			g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.fertilizerSiloTrigger_refuel).. ": " ..g_i18n:getText("fertilizerSiloTrigger_7"));
		end; 
		if InputBinding.hasEvent(InputBinding.fertilizerSiloTrigger_refuel)  then

			self.fillLowGo = not self.fillLowGo; 

		end;
		 end;
           if self.inTankerRange then
		if  self.fillTankerGo then
			g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.fertilizerSiloTrigger_overload).. ": " ..g_i18n:getText("fertilizerSiloTrigger_10"));
		else
			g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.fertilizerSiloTrigger_overload).. ": " ..g_i18n:getText("fertilizerSiloTrigger_9"));
    	end; 

		if InputBinding.hasEvent(InputBinding.fertilizerSiloTrigger_overload)  then
			 self.fillTankerGo = not self.fillTankerGo;
		end;
		 end;	

	self:farmerInRange(); 
			
end;

function fertilizerSiloTrigger:fertilizerInLowRange(dt)
	self.inLowRange = false; 
    local nearestDistance = 3.0;
	local px, py, pz = getWorldTranslation(self.fillLowNode);
	for i=1, table.getn(g_currentMission.attachables) do
		local vx, vy, vz = getWorldTranslation(g_currentMission.attachables[i].rootNode);
		local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);

		if distance < nearestDistance then
			local attachable = g_currentMission.attachables[i];	
			self.trailerInRange = g_currentMission.attachables[i];
			if attachable.setFillLevel ~= nil and not attachable.allowFillWithArm   then
				for fruitType,v in pairs(attachable.fillTypes) do
					if fruitType == self.currentFillType and attachable.rootNode ~= self.rootNode then
						if  attachable.fillLevel ~= attachable.capacity  then
							self.inLowRange = true;
                            renderText(0.80, 0.86, 0.02, "- Fill Level -");
                            renderText(0.80, 0.84, 0.02, tostring(math.floor(self.fillLevel)));
							 self.pipeParticleActivated = false;
                             if self.fillLevel == 0 then
                               setTextColor(1, 0, 0, 1);
                               renderText(0.80, 0.86, 0.02, "- Silo EMPTY -");
                                self.inLowRange = false;
                                end;
								 if attachable.fillLevel == attachable.capacity then
                                self.pipeParticleActivated = false;
                                self.inLowRange = false;
                                self.fillLowGo = false;
                            end;	 
							if self.fillLowGo then
								local deltaLevel = self.literPerSecond*dt/1000.0;
								deltaLevel = math.min(deltaLevel, attachable.capacity - attachable.fillLevel);
								self.fillLevel = self.fillLevel-deltaLevel;
								self:setFillLevel(self.fillLevel , self.currentFillType);
								attachable:setFillLevel(attachable.fillLevel + deltaLevel, self.currentFillType);
                               self.pipeParticleActivated = true;

						end;    end;
					end; 	
				end;
			end; 		
			nearestDistance = distance;
		end; 
    end;
	if not self.inLowRange then
		self.fillLowGo = false;
		 Utils.setEmittingState(self.pipeParticleSystem, false);
	end;
	if not self.fillLowGo then
		
		 Utils.setEmittingState(self.pipeParticleSystem, false);
	end;
end;




function fertilizerSiloTrigger:farmerInRange(dt)
    local nearestDistance = 12.0;
	local px, py, pz = getWorldTranslation(self.rootNode);
	local vx, vy, vz = getWorldTranslation(getCamera());
	if vx ~= nil and  vy ~= nil and vz ~= nil then
		local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);
		
	if distance < nearestDistance then
if self.startTractor then
	   renderText(0.80, 0.86, 0.02, "- Fill Level -");
	renderText(0.80, 0.84, 0.02, tostring(math.floor(self.fillLevel)));
end;
		if self.modus == 0 then
			-- trigger bauansicht
			g_currentMission:addHelpButtonText(g_i18n:getText("fertilizerSiloTrigger_1"), InputBinding.LOWER_IMPLEMENT);
			if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then
				self.modus = 1; 
			end; 
			
		elseif self.modus == 1 then
			-- trigger aufbauen
			g_currentMission:addHelpButtonText(g_i18n:getText("fertilizerSiloTrigger_2"), InputBinding.IMPLEMENT_EXTRA);
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
				self.modus = 2; 
			end; 
			
		elseif self.modus == 3 then
			-- trigger einpacken
		--	g_currentMission:addHelpButtonText(g_i18n:getText("fertilizerSiloTrigger_5"), InputBinding.IMPLEMENT_EXTRA);
			if InputBinding.isPressed(InputBinding.IMPLEMENT_EXTRA) then
				self.modus = 4; 
			end;
           end;
		end;

	end;
	
	 
end;


function fertilizerSiloTrigger:fertilizerInTankerRange(dt)

	self.inTankerRange = false;
    local nearestDistance = 3.0;
	local px, py, pz = getWorldTranslation(self.fillLowNode);
	for i=1, table.getn(g_currentMission.attachables) do
		local vx, vy, vz = getWorldTranslation(g_currentMission.attachables[i].rootNode);
		local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);

		if distance < nearestDistance  then
			local attachable = g_currentMission.attachables[i];
			self.trailerInRange = g_currentMission.attachables[i];
			if attachable.setFillLevel ~= nil and not attachable.allowFillWithArm and attachable.fertilizerTanker then

				for fruitType,v in pairs(attachable.fillTypes) do
					if fruitType == self.currentFillType and attachable.rootNode ~= self.rootNode then
						
							self.inTankerRange = true;
                            
                            renderText(0.80, 0.86, 0.02, "- Fill Level -");
                            renderText(0.80, 0.84, 0.02, tostring(math.floor(self.fillLevel)));
                            
                            if attachable.fillLevel == 0 then
                                
                                self.inTankerRange=false;
                                self.fillTankerGo = false;
                                 
                            end;
                            
                             if self.fillLevel == 0 then
                               setTextColor(1, 0, 0, 1);
                               renderText(0.80, 0.86, 0.02, "- Silo EMPTY -");
                                end;
                                
                             if self.fillLevel == self.maxLevel then
                               setTextColor(1, 0, 0, 1);
                               renderText(0.80, 0.86, 0.02, "- Silo FULL -");
                               self.fillTankerGo= false;
                               self.overload = false;
                               
                                end;

						     if self.fillTankerGo then 
								local deltaLevel = self.literPerSecond*dt/1000.0;
								deltaLevel = math.min(deltaLevel, attachable.capacity + attachable.fillLevel);
								self.fillLevel = self.fillLevel+deltaLevel;
								self:setFillLevel(self.fillLevel , self.currentFillType);
								attachable:setFillLevel(attachable.fillLevel - deltaLevel, self.currentFillType);
                                  
							end; 
						end;
					
				end;
			end;
			nearestDistance = distance;
		end;
    end;
	if not self.inTankerRange then
		self.fillTankerGo = false;
	end;
end;

function fertilizerSiloTrigger:delete()
	link(self.comp1Node, self.comp1Node);
end;

function fertilizerSiloTrigger:anim(varName, loopCheck)
	if self.moveColli[varName] ~= nil then
		local Collision = self.collisionArm[varName];
		setJointFrame(Collision.index, 0, Collision.armAttacher);
	end;
	if self.Go[varName] == true and self.Done[varName] ~= false then
		local charId = getAnimCharacterSet(self.charId[varName]);
		local clipIndex = getAnimClipIndex(charId, self.clipIndex[varName]);
		assignAnimTrackClip(charId , 0, clipIndex);
		setAnimTrackLoopState(charId, 0, loopCheck);
		setAnimTrackSpeedScale(charId, 0, 1);
		enableAnimTrack(charId, 0);
		if getAnimTrackTime(charId, 0) >= getAnimClipDuration(charId, clipIndex) and loopCheck == false then
			disableAnimTrack(charId, 0);	
			self.Done[varName] = false;	
			self.CheckDone[varName] = true;	
		end; 
	elseif self.Go[varName] == false and self.Done[varName] ~= false then
		local charId = getAnimCharacterSet(self.charId[varName]);
		local clipIndex = getAnimClipIndex(charId, self.clipIndex[varName]);
		if loopCheck == true then
			disableAnimTrack(charId, 0);
			self.Done[varName] = false;	
		end; 	
		assignAnimTrackClip(charId , 0, clipIndex);
		setAnimTrackLoopState(charId, 0, loopCheck);
		setAnimTrackSpeedScale(charId, 0, -1);
		enableAnimTrack(charId, 0);
		if getAnimTrackTime(charId, 0) <= 0 then
			disableAnimTrack(charId, 0);
			self.Done[varName] = false;	
			self.CheckDone[varName] = false;
		end;
	end;
end; 

function fertilizerSiloTrigger:connectCollisions(varName)
	local Collision = self.collisionArm[varName];
	local constr = JointConstructor:new();
	constr:setActors(self.rootNode, Collision.collision);
	constr:setJointTransforms(Collision.armAttacher, Collision.collisionAttacher);
	for i=1, 3 do		            
		constr:setRotationLimit(i-1, 0, 0, 0);
		constr:setTranslationLimit(i-1, true, 0, 0);
	end;
	Collision.index = constr:finalize();
end;

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

function fertilizerSiloTrigger:keyEvent(unicode, sym, modifier, isDown)
end;

function fertilizerSiloTrigger:draw()



end;

function fertilizerSiloTrigger:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if resetVehicles then
		self.modus = 0;
	else
		self.modus = Utils.getNoNil(getXMLFloat(xmlFile, key.."#modus"), 0);
	end; 
    return BaseMission.VEHICLE_LOAD_OK;
end;

function fertilizerSiloTrigger:getSaveAttributesAndNodes(nodeIdent)
	if self.modus == 4 then
		self.modus = 0;
	end; 	
	local attributes = 'modus="'..tonumber(self.modus)..'"';
	return attributes, nil;
end;