--
-- FlieglTDK11088
-- Specialization for FlieglTDK11088
--
-- @author Felix "Outlaw" Sorge
-- @date  20/05/09
-- @web www.ls-modsource.de - www.ls-mods.de
--
-- Copyright (C) Outlaw, All Rights Reserved.
--


FlieglTDK11088 = {};

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

function FlieglTDK11088:load(xmlFile)

	self.fertilizerInRange = SpecializationUtil.callSpecializationsFunction("fertilizerInRange");
	
	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.rotationParts = {};
	local numRotationParts = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.rotationParts#count"), 0);
    for i=1, numRotationParts do
      local partnamei = string.format("vehicle.rotationParts.part" .. "%d", i);
      self.rotationParts[i] = {};
      self.rotationParts[i].index = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partnamei .. "#index"));
      local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partnamei .. "#minRot"));
      self.rotationParts[i].minRot = {};
      self.rotationParts[i].minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
      self.rotationParts[i].minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
      self.rotationParts[i].minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
      x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partnamei .. "#maxRot"));
      self.rotationParts[i].maxRot = {};
      self.rotationParts[i].maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
      self.rotationParts[i].maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
      self.rotationParts[i].maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
      self.rotationParts[i].rotTime = Utils.getNoNil(getXMLString(xmlFile,  partnamei .. "#rotTime"), 2)*1000;
    end;
	
	
	self.translationParts = {};
	local numtranslationParts = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.translationParts#count"), 0);
    for i=1, numtranslationParts do
      local partnamei = string.format("vehicle.translationParts.part" .. "%d", i);
      self.translationParts[i] = {};
      self.translationParts[i].index = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partnamei .. "#index"));
      local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partnamei .. "#minTrans"));
      self.translationParts[i].minTrans = {};
      self.translationParts[i].minTrans[1] = Utils.getNoNil(x, 0);
      self.translationParts[i].minTrans[2] = Utils.getNoNil(y, 0);
      self.translationParts[i].minTrans[3] = Utils.getNoNil(z, 0);
      x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partnamei .. "#maxTrans"));
      self.translationParts[i].maxTrans = {};
      self.translationParts[i].maxTrans[1] = Utils.getNoNil(x, 0);
      self.translationParts[i].maxTrans[2] = Utils.getNoNil(y, 0);
      self.translationParts[i].maxTrans[3] = Utils.getNoNil(z, 0);
      self.translationParts[i].transTime = Utils.getNoNil(getXMLString(xmlFile,  partnamei .. "#transTime"), 2)*1000;
    end;
	
	
	self.literPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.literPerSecond#value"), 1);
	
	self.chargeTypes = {};
	self.fillTypes[FruitUtil.FRUITTYPE_UNKNOWN] = true;
	local chargeTypes = getXMLString(xmlFile, "vehicle.chargeTypes#chargeTypes");
    if chargeTypes ~= nil then
		self.chargefillNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chargeTypes#fillNode"));
		self.chargeNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chargeTypes#node"));
        local types = Utils.splitString(" ", chargeTypes);
        for k,v in pairs(types) do
            local desc = FruitUtil.fruitTypes[v];
            if desc ~= nil then
                self.chargeTypes[desc.index] = true;
            end;
        end;
    end;
	
	self.chargeParticle = {};
    local i = 0;
    while true do
		local nodei = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.chargeParticle#index"));
        local key = string.format("vehicle.chargeParticle.chargeParticle(%d)", i);
        local t = getXMLString(xmlFile, key.."#type");
		if t == nil then
            break;
        end
        local currentPS = {};
		local particleNode = Utils.loadParticleSystem(xmlFile, currentPS, key, nodei, false, "$data/vehicles/particleSystems/trailerDischargeParticleSystem.i3d", self.baseDirectory);
		self.chargeParticle[t] = currentPS;
		i = i +1;
    end;
	
	self.keyType = InputBinding.getButtonKeyName;
	self.keyName = "Taste";	
	if g_settingsJoystickEnabled then 
		self.keySet = not self.keySet;
	end; 	
	
end;


function FlieglTDK11088:update(dt)

	if not self.firstRun then
		self.firstRun = true;
		for chargeTypes,v in pairs(self.chargeTypes) do
			if chargeTypes == self.currentFillType and self.currentFillType ~= FruitUtil.FRUITTYPE_UNKNOWN then
				setVisibility(self.chargeNode, true); 
			else	
				setVisibility(self.chargeNode, false); 
			end;
		end;
	end; 	

	
	if self.Go.charge ~= nil and self.Done.charge ~= false then
		self:anim("charge", false); 
	end; 

	if self.GoHigh ~= nil and self.tipState == 0 then
		for i=1, table.getn(self.rotationParts) do
			local rot = {getRotation(self.rotationParts[i].index)};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationParts[i].maxRot, self.rotationParts[i].minRot, 3, self.rotationParts[i].rotTime, dt, not self.GoHigh);
			setRotation(self.rotationParts[i].index, unpack(newRot));
		end; 
		
		for i=1, table.getn(self.translationParts) do
			local trans = {getTranslation(self.translationParts[i].index)};
			local newTrans = Utils.getMovedLimitedValues(trans, self.translationParts[i].maxTrans, self.translationParts[i].minTrans, 3, self.translationParts[i].transTime, dt, not self.GoHigh);
			setTranslation(self.translationParts[i].index, unpack(newTrans));
		end; 
	end; 	
								

	for chargeTypes,v in pairs(self.chargeTypes) do	
		if chargeTypes == self.currentFillType then
			if self.fillLevel ~= 0 then
				setVisibility(self.chargeNode, true); 
				self:fertilizerInRange(dt);
			end; 
			
		elseif self.fillLevel == 0 then
			self.turnOn = false; 
			Utils.setEmittingState(self.savePS, false);
			setVisibility(self.chargeNode, false);
			self:setFillLevel(0, FruitUtil.FRUITTYPE_UNKNOWN);
			if self.Go.charge then
				self.Go.charge = not self.Go.charge; 
				self.Done.charge = true; 
			end;  
			if self.GoHigh then
				self.GoHigh = not self.GoHigh; 
			end; 				
		end; 	
	end; 	

	if self.Go.pillar ~= nil and self.Done.pillar ~= false then
		self:anim("pillar", false); 
	end;
	
end;


function FlieglTDK11088:fertilizerInRange(dt)
	self.particelActive = true; 
    local nearestDistance = 3.0;
	local px, py, pz = getWorldTranslation(self.chargefillNode);
	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];			
			for fruitType,v in pairs(attachable.fillTypes) do
				if fruitType == self.currentFillType and attachable.rootNode ~= self.rootNode and attachable.setFillLevel ~= nil then
			
					if attachable.fillLevel == attachable.capacity  or self.filllevel == 0 then
						Utils.setEmittingState(self.savePS, false);
						self.turnOn = false; 
						if self.Go.charge then
							self.Go.charge = not self.Go.charge; 
							self.Done.charge = true; 
						end;  
						if self.GoHigh then
							self.GoHigh = not self.GoHigh; 
						end; 
					
					elseif attachable.fillLevel ~= attachable.capacity  and self.fillLevel ~= 0 then
						if self.turnOn then
							g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.FlieglTDK11088_ON).. ": " ..g_i18n:getText("FlieglTDK11088_2")); 
							if InputBinding.hasEvent(InputBinding.FlieglTDK11088_ON) then
								self.turnOn = not self.turnOn; 
							end;
							
							if not self.Go.charge then
								self.Go.charge = not self.Go.charge; 
								self.Done.charge = true; 
							end; 
							if self.CheckDone.charge then

								local percent = self.fillLevel /self.capacity*100;	
								self.savePS = self.chargeParticle[FruitUtil.fruitIndexToDesc[self.currentFillType].name]; 
								Utils.setEmittingState(self.savePS, true);
								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.particelActive = false;
								
								if not self.GoHigh and percent <= 30 then
									self.GoHigh = not self.GoHigh; 
								end; 
							end; 
						else
							g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.FlieglTDK11088_ON).. ": " ..g_i18n:getText("FlieglTDK11088_1")); 
							if InputBinding.hasEvent(InputBinding.FlieglTDK11088_ON)  then
								self.turnOn = not self.turnOn; 
							end;
						end;
					end; 
				end;
			end;
		end;
    end;
		
	if self.particelActive then
		Utils.setEmittingState(self.savePS, false);
		if self.CheckDone.charge and self.Go.charge then
			self.Go.charge = not self.Go.charge; 
			self.Done.charge = true; 
			self.turnOn = false; 
		end;  
		if self.GoHigh then
			self.GoHigh = not self.GoHigh; 
		end; 
	end; 
	
end;


function FlieglTDK11088:delete()
	Utils.deleteParticleSystem(self.chargeParticle)
	if self.savePS then
		Utils.setEmittingState(self.savePS, false);
		Utils.deleteParticleSystem(self.savePS)
	end;
	removeJoint(self.collisionArm.pillar.index); 
end;


function FlieglTDK11088: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 FlieglTDK11088: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 FlieglTDK11088:mouseEvent(posX, posY, isDown, isUp, button)
end;


function FlieglTDK11088:keyEvent(unicode, sym, modifier, isDown)
	if isDown and sym==Input.KEY_8 then
		self.keySet = not self.keySet; 
		if self.keySet then
			self.keyType = InputBinding.getButtonName;
			self.keyName = "Button"; 
		else
			self.keyType = InputBinding.getButtonKeyName;
			self.keyName = "Taste"; 
		end; 
	end; 
end;


function FlieglTDK11088:draw()
end;


function FlieglTDK11088:onAttach()
	self.Go.pillar = not self.Go.pillar; 
	self.Done.pillar = true; 
end; 	


function FlieglTDK11088:onDetach()
	self.Go.pillar = not self.Go.pillar; 
	self.Done.pillar = true; 
	Utils.setEmittingState(self.savePS, false)
end;