--
-- WelgerRP235
-- Class for all WelgerRP235s
--
-- @author  Felix "Outlaw" Sorge
-- @date  06/04/09
--
-- Copyright (C) Outlaw, Confidential, All Rights Reserved.

WelgerRP235 = {};

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

function WelgerRP235:load(xmlFile)

	self.connectCollisions = SpecializationUtil.callSpecializationsFunction("connectCollisions");
	self.anim = SpecializationUtil.callSpecializationsFunction("anim");
  	self.charId = {};
	self.clipIndex = {};
	self.Go = {}; 
	self.Done = {};
	self.CheckDone = {};
	self.collisionArm = {}; 
	self.moveColli = {}; 
	local count = getXMLInt(xmlFile, "vehicle.animParts#count");
    self.animParts = {}
	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.rootNode, 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.rootNode, getXMLString(xmlFile, partname.."#collision"));
			Collision.collisionAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partname.."#collsionAttacher"));
			Collision.armAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partname.. "#armAttacher"));
			Collision.index = 0;
			self.collisionArm[nameR] = Collision;
			self:connectCollisions(nameR);
		end; 
	end; 	
	
    self.dustParticleSystems = {};
    local dustParticleSystemCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.dustParticleSystems#count"), 0);
    for i=1, dustParticleSystemCount do
        local namei = string.format("vehicle.dustParticleSystems.part%d", i);
		local nodei = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, namei .. "#index"));
        Utils.loadParticleSystem(xmlFile, self.dustParticleSystems, namei, nodei, false, nil, self.baseDirectory)
    end;
    
	local count = getXMLInt(xmlFile, "vehicle.drums#count");
    self.drums = {}
	local part = self.drums;
    for i=1, count do
		part[i] = {};
        local partname = string.format("vehicle.drums.part" .. "%d", i);
	    part[i].index = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partname .. "#index"));
		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, partname .. "#rot"));
		part[i].rot = {};
	    part[i].rot[1] = Utils.getNoNil(x, 0);
	    part[i].rot[2] = Utils.getNoNil(y, 0);
	    part[i].rot[3] = Utils.getNoNil(z, 0);
		for j=1, 3 do
			if part[i].rot[j] ~= 0 then
				part[i].rot[j] = 1/part[i].rot[j]
			end;
		end;
    end;
		
	self.getTimeFromLevel = WelgerRP235.getTimeFromLevel;
    self.allowFillType = WelgerRP235.allowFillType;
    self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1);

    local firstBaleMarker = getXMLFloat(xmlFile, "vehicle.baleAnimation#firstBaleMarker");
    if firstBaleMarker ~= nil then
        local baleAnimCurve = AnimCurve:new(linearInterpolatorN);
        local keyI = 0;
        while true do
            local key = string.format("vehicle.baleAnimation.key(%d)", keyI);
            local t = getXMLFloat(xmlFile, key.."#time");
            local x,y,z = Utils.getVectorFromString(getXMLString(xmlFile, key.."#pos"));
            if x == nil or y == nil or z == nil then
                break;
            end;
            local rx, ry, rz = Utils.getVectorFromString(getXMLString(xmlFile, key.."#rot"));
            rx = math.rad(Utils.getNoNil(rx, 0));
            ry = math.rad(Utils.getNoNil(ry, 0));
            rz = math.rad(Utils.getNoNil(rz, 0));
            baleAnimCurve:addKeyframe({ v={x, y, z, rx, ry, rz}, time = t});
            keyI = keyI +1;
        end;
        if keyI > 0 then
            self.baleAnimCurve = baleAnimCurve;
            self.baleAnimRoot = Utils.getNoNil(Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleAnimation#node")), self.components[1].node);
            self.firstBaleMarker = firstBaleMarker;
            self.baleTypes = {};
            local i = 0;
            while true do
                local key = string.format("vehicle.baleTypes.baleType(%d)", i);
                local t = getXMLString(xmlFile, key.."#fruitType");
                local filename = getXMLString(xmlFile, key.."#filename");
                if t==nil or filename==nil then
                    break;
                end;

                local entry = {};
                entry.filename = filename;
                local desc = FruitUtil.fruitTypes[t];
                if desc ~= nil then
                    self.baleTypes[desc.index] = entry;

                    if self.defaultBaleType == nil then
                        self.defaultBaleType = entry;
                    end;
                end;
                i = i +1;
            end;
            if self.defaultBaleType == nil then
                self.baleTypes = nil;
            end;
        end;
    end;
	
	local balerSound = getXMLString(xmlFile, "vehicle.balerSound#file");
    if balerSound ~= nil and balerSound ~= "" then
        balerSound = Utils.getFilename(balerSound, self.baseDirectory); 
        self.balerSound = createSample("balerSound");
        self.balerSoundEnabled = false;
        loadSample(self.balerSound, balerSound, false);
        self.balerSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.balerSound#pitchOffset"), 1);
        self.balerSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.balerSound#volume"), 1);
    end;
	
    self.keys = {};
    local i=0;
    while true do
        local baseName = string.format("vehicle.keys.input(%d)", i);
        local inputName = getXMLString(xmlFile, baseName.. "#name");
        if inputName == nil then
            break;
        end;
        local inputKey = getXMLString(xmlFile, baseName.. "#key");
        if Input[inputKey] == nil then
            print("Error: invalid key '" .. inputKey .. "'  for input event '" .. inputName .. "'");
            break;
        end;
        self.keys[inputName] = Input[inputKey];
        i = i+1;
    end;
    
	self.counterpath = Utils.getFilename("counter.png", self.baseDirectory);
	self.hudPDAPoxX = 0.435;
    self.hudPDAPoxY = 1-0.330; 
    self.hudPDAWidth = 0.320;
    self.hudPDAHeight = 0.320;
	self.hudBasePoxX = 0.664;
    self.hudBasePoxY = 0.9350; 	
    self.hudPDAOverlay = Overlay:new("hudPDAControl", self.counterpath, self.hudPDAPoxX, self.hudPDAPoxY, self.hudPDAWidth, self.hudPDAHeight);
    self.baleMoveLastTime = 0;
	self.counter = 0; 
    self.bales = {};
    self.wasToFast = false;
    self.isTurnedOn = false;
	self.hudActive = true;
	self.checkA = 0;
	self.airC = 0; 
	self.dy = 3000; 
    self.sbale = 3500;
	self.block = false; 
	
end;




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

	if isDown and sym==self.keys.pickup and self.Go.pickup ~= true then
		self.isTurnedOn = not self.isTurnedOn;
		self.runPickup = not self.runPickup;
	end;
	
	if isDown and sym==self.keys.senken and self.runPickup == true then
		self.Go.pickup = not self.Go.pickup; 
		self.Done.pickup = true; 
	end;
	
	if isDown and sym==self.keys.PDA then
		self.hudActive = not self.hudActive; 
	end; 
    
end;


function WelgerRP235:update(dt)

    if self.attacherVehicle ~= nil then 
	
        if self.Go.pickup ~= nil and self.Done.pickup ~= false then			
			self:anim("pickup",false); 
		end; 
                
        if self.Go.klappe ~= nil and self.Done.klappe ~= false then			
			self:anim("klappe",false); 
		end; 
        
		if self.runPickup == true then
			for i=1, table.getn(self.drums) do
				rotate(self.drums[i].index, self.drums[i].rot[1]  * dt, self.drums[i].rot[2]  * dt, self.drums[i].rot[3]  * dt);
			end;
			if not self.balerSoundEnabled and self:getIsActiveForSound() then
	            setSamplePitch(self.balerSound, self.balerSoundPitchOffset);
	            playSample(self.balerSound, 0, self.balerSoundVolume, 0);
	            self.balerSoundEnabled = true;
	        end;
		else
			if self.balerSoundEnabled then
		        stopSample(self.balerSound);
		        self.balerSoundEnabled = false;
		    end;
		end; 
		
        if self.isTurnedOn and self:allowFillType(FruitUtil.FRUITTYPE_WHEAT) and self.block == false and self.Go.pickup == true then
            local toFast = self.lastSpeed*3600 > 29;
            if not toFast then
                local totalArea =0;
                local usedFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
                for k, cuttingArea in pairs(self.cuttingAreas) do
                    local x,y,z = getWorldTranslation(cuttingArea.start);
                    local x1,y1,z1 = getWorldTranslation(cuttingArea.width);
                    local x2,y2,z2 = getWorldTranslation(cuttingArea.height);
                    for fruitType,v in pairs(self.fillTypes) do
                        if fruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
                            local area = Utils.updateFruitWindrowArea(fruitType, x, z, x1, z1, x2, z2, 0);
                            area = area + Utils.updateFruitCutLongArea(fruitType, x, z, x1, z1, x2, z2, 0);
                            if area > 0 then
                                totalArea = totalArea+area;
                                usedFruitType = fruitType;
                            end;
                        end;
                    end;
                end;
				if totalArea == 0 then
					self.checkA = self.checkA + 1;
					if self.checkA >= 500 then
						Utils.setEmittingState(self.dustParticleSystems, false)
						self.checkA = 0; 
					end; 	
				end; 	
                if totalArea > 0 then
                    local literPerPixel = 4*8000/1200 / 6 / (2*2) *12/4;
					local deltaLevel = totalArea * literPerPixel * self.fillScale;
                    local deltaTime = self:getTimeFromLevel(deltaLevel);
                    local oldFillLevel = self.fillLevel;
					self:setFillLevel(self.fillLevel+deltaLevel, usedFruitType);
                    Utils.setEmittingState(self.dustParticleSystems, true)
                    if self.fillLevel == self.capacity then
	                    local baleType = self.baleTypes[usedFruitType];
	                    if baleType == nil then
	                        baleType = self.defaultBaleType;
	                    end;
	                    self.counter = self.counter + 1; 
	                    local baleroot = Utils.loadSharedI3DFile(baleType.filename, self.baseDirectory);
	                    local baleId = getChildAt(baleroot, 0); 
	                    self.baleIDD = baleId; 
	                    local x,y,z = getWorldTranslation(self.baleAnimRoot);
	                    setTranslation(baleId, x,y,z);
	                    local x,y,z = getWorldRotation(self.baleAnimRoot);
	                    setRotation(baleId, x,y,z);
	                    link(getRootNode(), baleId);
	                    delete(baleroot);
	                    g_currentMission:addItemToSave(Utils.getFilename(baleType.filename, self.baseDirectory), baleId, 0);

	                    if self.block == false then
	                        self.shootbale = true; 
	                        self.block = true; 
	                        self.Go.klappe = not self.Go.klappe; 
	                        self.Done.klappe = true; 
	                     end;      
                    end;
                end;
				
				
            end;
            self.wasToFast = toFast;
        end;
		
        if self.CheckDone.klappe == true and self.drop ~= true and self.fillLevel == self.capacity then
            if self.baleAnimCurve ~= nil and self.baleTypes ~= nil then
                Utils.setEmittingState(self.dustParticleSystems, false)
                self.drop = true; 
                self.delay = true;
            end;         
        end;
                            
        if self.shootbale then
            self.sbale = self.sbale - dt;
            if self.sbale <= 0 then
                local x,y,z = localDirectionToWorld(self.baleAnimRoot, 0,0,-1);
                addForce(self.baleIDD, x*3, y*3, z*3, 0,0,0, true);
                self.shootbale = false;
                self.sbale = 3500; 
            end;
        end;         
                           
                    
        if self.delay == true then
            self.dy = self.dy - dt;
            if self.dy <= 0 then
                self.Go.klappe = not self.Go.klappe; 
				self.Done.klappe = true; 
                self.delay = false;
                self.dy = 3000; 
				self.fillLevel = 0; 
				self.drop = nil;
				self.block = false; 
            end;
        end; 
		
	end; 

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


function WelgerRP235:getTimeFromLevel(level)
    if self.firstBaleMarker ~= nil then
        return level / self.capacity * self.firstBaleMarker;
    end;
    return 0;
end;


function WelgerRP235:draw()

	if self.Go.pickup ~= true then
	    if self.isTurnedOn then	
	        g_currentMission:addExtraPrintText("Taste "..string.upper(string.char(self.keys.pickup))..": " ..g_i18n:getText("WelgerRP235_2"));
	    else
	        g_currentMission:addExtraPrintText("Taste "..string.upper(string.char(self.keys.pickup))..": " ..g_i18n:getText("WelgerRP235_1"));
	    end;
	end; 
		
	if self.runPickup == true then
		if self.Go.pickup then
			g_currentMission:addExtraPrintText("Taste "..string.upper(string.char(self.keys.senken))..": " ..g_i18n:getText("WelgerRP235_6"));
		else
			g_currentMission:addExtraPrintText("Taste "..string.upper(string.char(self.keys.senken))..": " ..g_i18n:getText("WelgerRP235_5"));
		end; 	
	end;
	
	if self.hudActive then
		g_currentMission:addExtraPrintText("Taste "..string.upper(string.char(self.keys.PDA))..": " ..g_i18n:getText("WelgerRP235_8"));
	else
		g_currentMission:addExtraPrintText("Taste "..string.upper(string.char(self.keys.PDA))..": " ..g_i18n:getText("WelgerRP235_7"));
	end; 

	if self.hudActive == true then
		self.hudPDAOverlay:render();
		setTextBold(true);
		setTextColor(0, 0, 0, 1.0);
		if self.counter >= 10 then
			self.hudBasePoxX = 0.664 - 0.015;
		end; 
		if self.counter >= 100 then
			self.hudBasePoxX = 0.664 - 0.030;
		end; 
		if self.counter >= 1000 then
			self.hudBasePoxX = 0.664 - 0.045;
		end; 
		if self.counter >= 10000 then
			self.hudBasePoxX = 0.664 - 0.060;
		end; 
		if self.counter >= 100000 then
			self.hudBasePoxX = 0.664 - 0.075;
		end; 
		if self.counter >= 1000000 then
			self.hudBasePoxX = 0.664 - 0.090;
		end; 
		renderText(self.hudBasePoxX, self.hudBasePoxY, 0.040, string.format(self.counter));
	end; 

end;


function WelgerRP235:onDetach()
	self.Go.pillar = not self.Go.pillar; 
	self.Done.pillar = true; 
	Utils.setEmittingState(self.dustParticleSystems, false)
	if self.balerSoundEnabled then
        stopSample(self.balerSound);
        self.balerSoundEnabled = false;
    end;
end;


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


function WelgerRP235:onLeave()
	if self.balerSoundEnabled then
        stopSample(self.balerSound);
        self.balerSoundEnabled = false;
    end;
end;


function WelgerRP235:allowFillType(fillType)
    return self.fillTypes[fillType] == true;
end;


function WelgerRP235: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 WelgerRP235:delete()
	removeJoint(self.collisionArm.pillar.index); 
	removeJoint(self.collisionArm.klappe.index); 
	Utils.setEmittingState(self.dustParticleSystems, false)
	if self.balerSoundEnabled then
        stopSample(self.balerSound);
        self.balerSoundEnabled = false;
    end;
end;


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


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