--
-- WelgerRP235380
-- Original Script : WelgerRP235 by Outlaw
-- Updated/Modified for the Claas Variant 380 by Bayn (re-edited for welger by JohnDeereMad)
-- 
-- @date  07/09/09
--
-- www.tsforum3.com + www.lsuk.info

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;
    
    self.Drum1 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Drum1#index"));
    self.Drum2 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Drum2#index"));
    self.Drum3 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Drum3#index"));
		
	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;
	
    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;
	
	-- Sound for full capacity --

    FCSoundFile = Utils.getFilename("Sounds/Capacity.ogg", self.baseDirectory);
    self.FCSoundId = createSample("CapacitySound");
    loadSample(self.FCSoundId, FCSoundFile, false);
    self.FCPlaying = false;
	
	-- selfs --
    
	self.counterpath = Utils.getFilename("counter.png", self.baseDirectory);
	self.hudPDAPoxX = 0.805;
    self.hudPDAPoxY = 1-0.440; 
    self.hudPDAWidth = 0.190;
    self.hudPDAHeight = 0.323;
	self.hudBasePoxX = 0.915;
    self.hudBasePoxY = 0.728; 	
    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 = false;
	self.checkA = 0;
	self.airC = 0; 
	self.dy = 3000; 
    self.sbale = 3500;
	self.GoForDoor = 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; 
	
	if isDown and sym==self.keys.Door and self.GoForDoor and self.fillLevel == self.capacity then
        self.Go.klappe = not self.Go.klappe; 
        self.Done.klappe = true; 	
	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
				rotate(self.Drum1, dt*-0.01, 0, 0);
				rotate(self.Drum2, dt*0.01, 0, 0);
				rotate(self.Drum3, dt*0.01, 0, 0);
		end; 
		
        if self.isTurnedOn and self:allowFillType(FruitUtil.FRUITTYPE_WHEAT) and self.block ~= true 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
						Utils.setEmittingState(self.dustParticleSystems, false)
				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);
				-- Manual Door --
                    if self.block ~= true and self.fillLevel == self.capacity then
                        self.shootbale = true; 
                        self.block = true; 
						self.GoForDoor = true;
                     end;      
  
                    end;
                end;
            end;
            self.wasToFast = toFast;
        end;
		
        if self.CheckDone.klappe == true and self.drop ~= true 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.CheckDone.klappe == false and self.drop == true then
           self.fillLevel = 0; 
           self.drop = nil;
           self.block = nil; 
        end; 
                    
        if self.delay then
            self.dy = self.dy - dt;
            if self.dy <= 0 then
                self.delay = false;
                self.dy = 500; 
            end;
        end; 
		
	end; 
	
		if self.fillLevel == self.capacity then
			if self:getIsActiveForSound() then
				if not self.FCPlaying then
					playSample(self.FCSoundId, 1, 1, 0);
					self.FCPlaying = true;
				end;
			end;
		else
			if self.FCPlaying then
				stopSample(self.FCSoundId);
				self.FCPlaying = false;
			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("Key "..string.upper(string.char(self.keys.pickup))..": " ..g_i18n:getText("WelgerRP235_2"));
	    else
	        g_currentMission:addExtraPrintText("Key "..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("Key "..string.upper(string.char(self.keys.senken))..": " ..g_i18n:getText("WelgerRP235_6"));
		else
			g_currentMission:addExtraPrintText("Key "..string.upper(string.char(self.keys.senken))..": " ..g_i18n:getText("WelgerRP235_5"));
		end; 	
	end;
	
	if self.GoForDoor and self.fillLevel == self.capacity then
		g_currentMission:addExtraPrintText("Key "..string.upper(string.char(self.keys.Door))..": " ..g_i18n:getText("WelgerRP235_9"));
	end;	
	
	
	if self.hudActive then
		g_currentMission:addExtraPrintText("Key "..string.upper(string.char(self.keys.PDA))..": " ..g_i18n:getText("WelgerRP235_8"));
	else
		g_currentMission:addExtraPrintText("Key "..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.915 - 0.007;
		end; 
		if self.counter >= 100 then
			self.hudBasePoxX = 0.915 - 0.015;
		end; 
		if self.counter >= 1000 then
			self.hudBasePoxX = 0.915 - 0.023;
		end; 
		if self.counter >= 10000 then
			self.hudBasePoxX = 0.915 - 0.030;
		end; 
		if self.counter >= 100000 then
			self.hudBasePoxX = 0.915 - 0.038;
		end; 
		if self.counter >= 1000000 then
			self.hudBasePoxX = 0.915 - 0.045;
		end; 
		renderText(self.hudBasePoxX, self.hudBasePoxY, 0.020, 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)
end;

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

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




