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


BrentAvalanche1594 = {};

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

function BrentAvalanche1594:load(xmlFile)

	self.lowerRmp = SpecializationUtil.callSpecializationsFunction("lowerRmp");
	self.disableSounds = SpecializationUtil.callSpecializationsFunction("disableSounds");
	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 = {};
	self.startpoint = {};
	self.loopCheck = {};
	self.Speed = {};
	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");
		self.startpoint[nameR] = Utils.getNoNil(getXMLFloat(xmlFile, partname.."#startpoint"),0.0);
		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; 
		local charId = getAnimCharacterSet(self.charId[nameR]);
		local clipIndex = getAnimClipIndex(charId, self.clipIndex[nameR]);
		assignAnimTrackClip(charId , 0, clipIndex);
		setAnimTrackTime(charId, 0, self.startpoint[nameR]);
		enableAnimTrack(charId, 0);
		disableAnimTrack(charId, 0);
		self.loopCheck[nameR] = false;
		self.Speed[nameR] = 1.0;
	end; 
	
	
	self.trailerInRange = SpecializationUtil.callSpecializationsFunction("trailerInRange");
	self.literPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.literPerSecond#value"), 1);
	self.pipelightNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipelight#node"));
	setVisibility(self.pipelightNode, false);
	
	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"));
        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;
		
	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);
    end;
	
	local loopSound = getXMLString(xmlFile, "vehicle.loopSound#file");
    if loopSound ~= nil and loopSound ~= "" then
        loopSound = Utils.getFilename(loopSound, self.baseDirectory); 
        self.loopSound = createSample("loopSound");
        self.workSoundEnabled = false;
        loadSample(self.loopSound, loopSound, false);
    end;
	
	self.keyType = InputBinding.getKeyNamesOfDigitalAction;
	self.keyName = "Taste";	 	
	
	setMass(self.rootNode, 2); 

	self.overlay = Utils.getFilename("overlay.png", self.baseDirectory);
    self.hudPDAOverlay = Overlay:new("hudPDAControl", self.overlay, g_currentMission.fruitSymbolX, g_currentMission.fruitSymbolY-0.11, g_currentMission.fruitSymbolSize, g_currentMission.fruitSymbolSize * (4 / 3)); 
	
end;


function BrentAvalanche1594:update(dt)
	setMass(self.rootNode, 2); 
	if self.attacherVehicle then
		self.Speed.trsp = 1.0; 
		if self:getIsActiveForInput() and InputBinding.hasEvent(InputBinding.BrentAvalanche1594_on) and self.inRangeDraw and self.Go.trsp and self.CheckDone.trsp then
			self.turnOn = not self.turnOn; 
		elseif self:getIsActiveForInput() and InputBinding.hasEvent(InputBinding.BrentAvalanche1594_on) and not self.inRangeDraw and self.turnOn and self.Go.trsp and self.CheckDone.trsp then
			self.turnOn = not self.turnOn; 
		end; 		

		if self:getIsActiveForInput() and InputBinding.hasEvent(InputBinding.BrentAvalanche1594_pipelight) and self.Go.trsp and self.CheckDone.trsp then
			self.pipelight = not self.pipelight; 
		end; 	
		
		if self:getIsActiveForInput() and InputBinding.hasEvent(InputBinding.BrentAvalanche1594_transport) and not self.turnOn then
			self.Go.trsp = not self.Go.trsp; 
			self.pipelight = false; 
			self.Done.trsp = true; 
			if not self.Go.trsp then
				self.Go.pipe = 0;
				self.Done.pipe = true; 
			else
				self.Go.pipe = 4000;
				self.Done.pipe = true; 
			end; 
		end; 	
					
		if self:getIsActiveForInput() and InputBinding.isPressed(InputBinding.BrentAvalanche1594_down) and InputBinding.isPressed(InputBinding.BrentAvalanche1594_up) == false and self.Go.trsp and self.CheckDone.trsp then
			self.Go.pipe = true; 
			self.Done.pipe = true;
		
		elseif self:getIsActiveForInput() and InputBinding.isPressed(InputBinding.BrentAvalanche1594_up) and InputBinding.isPressed(InputBinding.BrentAvalanche1594_down) == false and self.Go.trsp and self.CheckDone.trsp then
			self.Go.pipe = false; 
			self.Done.pipe = true;
		elseif self.Go.trsp and self.CheckDone.trsp then
			self.Done.pipe = false; 
		end; 
				
		
		if self.pipelight then
			setVisibility(self.pipelightNode, true);
		else	
			setVisibility(self.pipelightNode, false);
		end; 		
	
		if not self.turnOn then
			self:lowerRmp(); 
			Utils.setEmittingState(self.savePS, false);		
			self:disableSounds();
		end;
		
		for chargeTypes,v in pairs(self.chargeTypes) do	
			if chargeTypes == self.currentFillType and self.CheckDone.trsp then
				if self.fillLevel ~= 0 then
					self:trailerInRange(dt);
				end; 
			elseif self.fillLevel == 0 then
				self:lowerRmp(); 
				Utils.setEmittingState(self.savePS, false);
				if self.turnOn then
					self.turnOn = false; 
				end; 
				self:disableSounds();
				self:setFillLevel(0, FruitUtil.FRUITTYPE_UNKNOWN); 				
			end; 	
		end; 	
	end; 
	
	
	if self.Go.pillar ~= nil and self.Done.pillar ~= false then
		self:anim("pillar", false); 
	end;

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

function BrentAvalanche1594:trailerInRange(dt)
	self.inRange = false; 
	self.inRangeDraw = false;	
    local nearestDistance = 4.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);
		local attachable = g_currentMission.attachables[i];	
		if distance < nearestDistance and attachable.setFillLevel ~= nil and attachable.allowFillFromAir and attachable.rootNode ~= self.rootNode and attachable:allowFillType(self.currentFillType, true) then	
			for fruitType,v in pairs(attachable.fillTypes) do
				if fruitType == self.currentFillType then
					if attachable.fillLevel == attachable.capacity  or self.filllevel == 0 then
						self.turnOn = false; 
						self:disableSounds();
						self:lowerRmp(); 
					elseif attachable.fillLevel ~= attachable.capacity and self.fillLevel ~= 0 then
						self.inRangeDraw = true;						
						if self.turnOn then
							self.inRange = true; 
							if not self.backupRmp then
								self.backupRmp = self.attacherVehicle.motor.minRpm;
							end; 
							
							if self.attacherVehicle.motor.minRpm >= -700 then
								self.attacherVehicle.motor.minRpm = self.attacherVehicle.motor.minRpm - 10; 
							end; 
							if not self.workSoundEnabled then
							    playSample(self.workSound, 1, 0.3, 0);
								setSamplePitch(self.workSound,1);
								self.workSoundEnabled = true;
								local SoundOffset = getSampleDuration(self.workSound); 
								self.playSoundTime = self.time+SoundOffset;
							end;
							
							if self.playSoundTime <= self.time and not self.loopSoundEnabled then
								playSample(self.loopSound, 0, 0.3, 0);
								setSamplePitch(self.loopSound,1);
								self.loopSoundEnabled = true;
							end;
							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);	
						end; 	
					end; 
				end;
			end;
		end;
    end;
		
	if not self.inRange and self.turnOn then
		Utils.setEmittingState(self.savePS, false);
		self.turnOn = false; 
		self:lowerRmp(); 
		self:disableSounds();
	end;
	
end;

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

function BrentAvalanche1594: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.getKeyNamesOfDigitalAction;
			self.keyName = "Button"; 
		else
			self.keyType = InputBinding.getKeyNamesOfDigitalAction;
			self.keyName = "Taste"; 
		end; 
	end; 
end;

function BrentAvalanche1594:draw()
	if self.turnOn and self.inRangeDraw and self.Go.trsp and self.CheckDone.trsp then
		g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.BrentAvalanche1594_on).. ": " ..g_i18n:getText("BrentAvalanche1594_2")); 
	elseif self.inRangeDraw and self.Go.trsp and self.CheckDone.trsp  then
		g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.BrentAvalanche1594_on).. ": " ..g_i18n:getText("BrentAvalanche1594_1")); 
	end; 
	
	
	if self.pipelight and self.Go.trsp and self.CheckDone.trsp then
		g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.BrentAvalanche1594_pipelight).. ": " ..g_i18n:getText("BrentAvalanche1594_4")); 
	elseif self.Go.trsp and self.CheckDone.trsp then
		g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.BrentAvalanche1594_pipelight).. ": " ..g_i18n:getText("BrentAvalanche1594_3")); 
	end; 
	
	
	if self.Go.trsp and not self.turnOn then
		g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.BrentAvalanche1594_transport).. ": " ..g_i18n:getText("BrentAvalanche1594_6")); 
	elseif not self.turnOn then
		g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.BrentAvalanche1594_transport).. ": " ..g_i18n:getText("BrentAvalanche1594_5")); 
	end; 
	
	if self.Go.trsp and self.CheckDone.trsp then
		g_currentMission:addExtraPrintText(self.keyName.. " " ..self.keyType(InputBinding.BrentAvalanche1594_down).. "/" ..self.keyType(InputBinding.BrentAvalanche1594_up).. ": " ..g_i18n:getText("BrentAvalanche1594_7")); 
	end; 
	
	if self.inRangeDraw and not self.turnOn and self.fillLevel ~= 0 and self.CheckDone.trsp and self.Go.trsp then
		self.hudPDAOverlay:render();
	end; 
	
end;

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

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

function BrentAvalanche1594:delete()
	for k,v in pairs(self.chargeParticle) do
		Utils.deleteParticleSystem(v);
	end;
	self:disableSounds();
end;

function BrentAvalanche1594:anim(varName, loopCheck)
	if self.moveColli[varName] ~= nil then
		local Collision = self.collisionArm[varName];
		setJointFrame(Collision.index, 0, Collision.armAttacher);
	end;
	local loopCheck = self.loopCheck[varName];
	local speed = Utils.getNoNil(self.Speed[varName],1);
	local offset = 10;  
	local charId = getAnimCharacterSet(self.charId[varName]);
	local clipIndex = getAnimClipIndex(charId, self.clipIndex[varName]);
	if self.Done[varName] ~= false then
		if self.Go[varName] == true then
			assignAnimTrackClip(charId , 0, clipIndex);
			setAnimTrackLoopState(charId, 0, loopCheck);
			setAnimTrackSpeedScale(charId, 0, speed);
			enableAnimTrack(charId, 0);
			if getAnimTrackTime(charId, 0) >= getAnimClipDuration(charId, clipIndex) and loopCheck == false then
				self.Done[varName] = false;	
				self.CheckDone[varName] = self.Go[varName];	
			end;
			if getAnimTrackTime(charId, 0) >= getAnimClipDuration(charId, clipIndex) and loopCheck then
				local setTime = getAnimClipDuration(charId, clipIndex) - getAnimClipDuration(charId, clipIndex);
				setAnimTrackTime(charId, 0, setTime);
			end;
		elseif self.Go[varName] == false then
			if loopCheck == true then
				self.Done[varName] = false;	
			else
				assignAnimTrackClip(charId , 0, clipIndex);
				setAnimTrackLoopState(charId, 0, loopCheck);
				setAnimTrackSpeedScale(charId, 0, -speed);
				enableAnimTrack(charId, 0);
				if getAnimTrackTime(charId, 0) <= 0 then
					self.Done[varName] = false;	
					self.CheckDone[varName] = self.Go[varName];
				end;
			end;
		elseif self.Go[varName] ~= nil then
			assignAnimTrackClip(charId , 0, clipIndex);
			setAnimTrackLoopState(charId, 0, loopCheck);
			if self.Go[varName] < 0.0 then
				self.Go[varName] = 0.0;
			elseif self.Go[varName] > getAnimClipDuration(charId, clipIndex) then
				self.Go[varName] = getAnimClipDuration(charId, clipIndex);
			end;
			if getAnimTrackTime(charId, 0) >= self.Go[varName] then
				setAnimTrackSpeedScale(charId, 0, -speed);
			else
				setAnimTrackSpeedScale(charId, 0, speed);
			end;
			enableAnimTrack(charId, 0);
			if getAnimTrackTime(charId, 0) <= self.Go[varName] + offset and getAnimTrackTime(charId, 0) >= self.Go[varName] - offset then
				self.Done[varName] = false;	
				self.CheckDone[varName] = self.Go[varName];
			end;
		end;
	end;
	if self.Done[varName] == false then
		disableAnimTrack(charId, 0);
	end;
end; 

function BrentAvalanche1594: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 BrentAvalanche1594:getSaveAttributesAndNodes(nodeIdent)
	if self.CheckDone.trsp then
		trsp = "false";
	else
		trsp = "true";
	end; 	
	local attributes = 'transport="'..trsp..'"';
	return attributes, nil;
end;

function BrentAvalanche1594:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
    local trsp = getXMLString(xmlFile, key.."#transport");
	if trsp == "false" and not resetVehicles then
		self.Go.trsp = not self.Go.trsp; 
		self.Done.trsp = true; 
		self.Go.pipe = 4000;
		self.Done.pipe = true; 
		self.Speed.trsp = 100.0; 
		
	end; 
    return BaseMission.VEHICLE_LOAD_OK;
end;

function BrentAvalanche1594:lowerRmp()
	if self.backupRmp and self.attacherVehicle then
		if self.attacherVehicle.motor.minRpm <= self.backupRmp then
			self.attacherVehicle.motor.minRpm = self.attacherVehicle.motor.minRpm + 10; 
		else
			self.attacherVehicle.motor.minRpm = self.backupRmp; 
			self.backupRmp = nil; 			
		end; 	
	end; 
end;

function BrentAvalanche1594:disableSounds()
	if self.loopSoundEnabled then
		stopSample(self.loopSound);
		self.loopSoundEnabled = false;
	end;
	if self.workSoundEnabled then
		stopSample(self.workSound);
		self.workSoundEnabled = false;
	end;	
end; 