--
-- KroneZX
-- This is the specialization for Ladewagen
--
-- M@D Author  Headshot XXL
-- M@D date  06.12.2009
--
-- > Copyright (C) Headshot XXL - www.planet-ls.de < --

KroneZX = {};

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

function KroneZX:load(xmlFile)

	self.setHydraulicDirection = SpecializationUtil.callSpecializationsFunction("setHydraulicDirection");

    local forageWgnSound = getXMLString(xmlFile, "vehicle.forageWgnSound#file");
    if forageWgnSound ~= nil and forageWgnSound ~= "" then
        forageWgnSound = Utils.getFilename(forageWgnSound, self.baseDirectory);
        self.forageWgnSound = createSample("forageWgnSound");
        self.forageWgnSoundEnabled = false;
        loadSample(self.forageWgnSound, forageWgnSound, false);
        self.forageWgnSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.forageWgnSound#pitchOffset"), 1);
        self.forageWgnSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.forageWgnSound#volume"), 1.0);
    end;
	
	local rollsCount = getXMLInt(xmlFile, "vehicle.rolls#count");
	self.rolls = {}
	if rollsCount ~= nil then		
		for i=1, rollsCount do
			local entry = {};
			local rollPartname = string.format("vehicle.rolls.roll" .. "%d", i);
			entry.index = Utils.indexToObject(self.components, getXMLString(xmlFile, rollPartname .. "#index"));
			entry.speedScale = Utils.getNoNil(getXMLInt(xmlFile, rollPartname .. "#speedScale"), 1)/1000;
			table.insert(self.rolls, entry);
		end;
	end;
	
	local deichselNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.deichsel#index"));
    if deichselNode ~= nil then
        self.deichsel = {};
        self.deichsel.node = deichselNode;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.deichsel#minRot"));
        self.deichsel.minRot = {};
        self.deichsel.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.deichsel.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.deichsel.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.deichsel#maxRot"));
        self.deichsel.maxRot = {};
        self.deichsel.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.deichsel.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.deichsel.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.deichsel.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.deichsel#rotTime"), 2)*1000;
        self.deichsel.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.deichsel#touchRotLimit"), 10));
    end;	
	
	self.jointmove = false;
	
	local ladeklappeNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.ladeklappe#index"));
    if ladeklappeNode ~= nil then
        self.ladeklappe = {};
        self.ladeklappe.node = ladeklappeNode;

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.ladeklappe#minRot"));
        self.ladeklappe.minRot = {};
        self.ladeklappe.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.ladeklappe.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.ladeklappe.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.ladeklappe#maxRot"));
        self.ladeklappe.maxRot = {};
        self.ladeklappe.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.ladeklappe.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.ladeklappe.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        self.ladeklappe.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.ladeklappe#rotTime"), 2)*1000;
        self.ladeklappe.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.ladeklappe#touchRotLimit"), 10));
    end;
	
	self.pickupFruitPlane = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pickupFruitPlane#index"));
	setVisibility(self.pickupFruitPlane, false);
	local x,y,z = getScale(self.pickupFruitPlane);
	self.pickupFruitPlaneScale = {x,y,z};
	self.pickupFruitPlaneBackupScale = {x,y,z}

    self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1);
    self.wasToFast = false;
    self.isTurnedOn = false;
	self.PickupDown = false;
	self.currentFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
	
	self.currentRotLimit = {0,0,0};

end;

function KroneZX:delete()
    if self.forageWgnSound ~= nil then
        delete(self.forageWgnSound);
    end;
end;

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

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

function KroneZX:update(dt)

    if self:getIsActiveForInput() then
	
        if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
            self.isTurnedOn = not self.isTurnedOn;
        end;
		
		if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then
            self.PickupDown = not self.PickupDown;
        end;
		
		self.jointmove = false;	   	    
		if InputBinding.isPressed(InputBinding.KRONEZX_DEICHSELUP) then
	    	self.jointmove = true;
			local x, y, z = getRotation(self.deichsel.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.deichsel.maxRot, self.deichsel.minRot, 3, self.deichsel.rotTime*2, dt, false);
			setRotation(self.deichsel.node, unpack(newRot));
		end;		
		if InputBinding.isPressed(InputBinding.KRONEZX_DEICHSELDOWN) then
	    	self.jointmove = true;
			local x, y, z = getRotation(self.deichsel.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.deichsel.maxRot, self.deichsel.minRot, 3, self.deichsel.rotTime*2, dt, true);
			setRotation(self.deichsel.node, unpack(newRot));
		end;		
	    if InputBinding.isPressed(InputBinding.KRONEZX_KLAPPEUP) then
			local x, y, z = getRotation(self.ladeklappe.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.ladeklappe.maxRot, self.ladeklappe.minRot, 3, self.ladeklappe.rotTime*2, dt, true);
			setRotation(self.ladeklappe.node, unpack(newRot));
		end;
		if InputBinding.isPressed(InputBinding.KRONEZX_KLAPPEDOWN) then
			local x, y, z = getRotation(self.ladeklappe.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.ladeklappe.maxRot, self.ladeklappe.minRot, 3, self.ladeklappe.rotTime*2, dt, false);
			setRotation(self.ladeklappe.node, unpack(newRot));
		end;
		
    end;	

	
    if self:getIsActive() then
	
        if self.isTurnedOn and self.fillLevel <= self.capacity and not self.pickupPlugged then
			
			if self.PickupDown then
				local area =0;
				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
							if self.currentFruitType == fruitType or self.currentFruitType == FruitUtil.FRUITTYPE_UNKNOWN then
								local area = Utils.updateFruitWindrowArea(fruitType, x, z, x1, z1, x2, z2, 0)*g_currentMission.windrowCutLongRatio;
								area = area + Utils.updateFruitCutLongArea(fruitType, x, z, x1, z1, x2, z2, 0);
								if area > 0 then
									self.currentFruitType = fruitType;
									if self.attacherVehicle.lastSpeed*3600 > 20 then
										self.pickupPlugged = true;
										setVisibility(self.pickupFruitPlane, true);
										setScale(self.pickupFruitPlane, unpack(self.pickupFruitPlaneBackupScale));
									end;
								end;
								local pixelToQm = 2048 / 4096 * 2048 / 4096  / g_currentMission.maxFruitValue; -- 4096px are mapped to 2048m
								local literPerQm = FruitUtil.fruitIndexToDesc[fruitType].literPerQm * (1 + 0.5 * (3 - g_currentMission.missionStats.difficulty));
								local qm = area*pixelToQm;
								local deltaLevel = qm*literPerQm * self.fillScale;
								self:setFillLevel(self.fillLevel+deltaLevel, self.currentFruitType);
							end;
						end;
					end;
				end;	
				if self.fillLevel == 0 then
					self.currentFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
				end;	
			end;
		
			self.allowFillFromAir = false;
			
            if not self.forageWgnSoundEnabled and self:getIsActiveForSound() then
                playSample(self.forageWgnSound, 0, self.forageWgnSoundVolume, 0);
                setSamplePitch(self.forageWgnSound, self.forageWgnSoundPitchOffset);
                self.forageWgnSoundEnabled = true;
            end;
			
			if self.rolls~= nil then							
				rotate(self.rolls[1].index, dt*self.rolls[1].speedScale*self.attacherVehicle.lastSpeed*3600 , 0, 0);
				rotate(self.rolls[2].index, dt*self.rolls[2].speedScale , 0, 0);
			end;
			
		else
			self.allowFillFromAir = true;
        end;

        if self.forageWgnSoundEnabled and not self.isTurnedOn then
            stopSample(self.forageWgnSound);
            self.forageWgnSoundEnabled = false;
        end;
				
		
		local newRotLimit = {0,0,0};
		newRotLimit = Utils.getMovedLimitedValues(self.currentRotLimit, {0,0,0}, {30,0,0}, 3, 1000, dt, self.PickupDown);
		if math.abs(newRotLimit[1] - self.currentRotLimit[1]) > 0.001 then
			setJointRotationLimit(self.componentJoints[3].jointIndex, 0, true, Utils.degToRad(0), Utils.degToRad(newRotLimit[1]));
		end;			
		self.currentRotLimit = newRotLimit;	
		
		if self.attacherVehicle ~= nil and self.jointmove then
			for k, implement in pairs(self.attacherVehicle.attachedImplements) do
				local jointDesc = self.attacherVehicle.attacherJoints[implement.jointDescIndex];
				if k == self.attacherVehicle.selectedImplement  then
					setJointFrame(jointDesc.jointIndex, 1, self.attacherJoint.node);
				end;
			end;
		end;
		
    end;
	
	if self.pickupPlugged then
		local nearestDistance = 4.0;
		local px, py, pz = getWorldTranslation(self.pickupFruitPlane);
		local vx, vy, vz = getWorldTranslation(Player.rootNode);
		local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);
		if distance < nearestDistance then
			g_currentMission:addExtraPrintText("Taste "..InputBinding.getButtonKeyName(InputBinding.KRONEZX_PLUGGEDPICKUP).." : Verstopfung beseitigen");
			if InputBinding.isPressed(InputBinding.KRONEZX_PLUGGEDPICKUP) then
				local x,y,z = getScale(self.pickupFruitPlane);
				setScale(self.pickupFruitPlane, x, y-0.01, z);				
				if y < 0.2 then
					self.pickupPlugged = false;
					setVisibility(self.pickupFruitPlane, false);
				end;
			end;			
		end;	
	end;

end;

function KroneZX:draw()

    if self.pickupPlugged then
        g_currentMission:addWarning("Pickup verstopft: Aussteigen und Verstopfung beseitigen", 0.07+0.022, 0.019+0.029);
    end;
    if self.isTurnedOn then
        g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_off_OBJECT"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA);
    else
        g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_on_OBJECT"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA);
    end;
	if self.PickupDown then
		g_currentMission:addHelpButtonText(string.format(g_i18n:getText("KRONEZX_PICKUPUP"), self.typeDesc), InputBinding.LOWER_IMPLEMENT);
    else
        g_currentMission:addHelpButtonText(string.format(g_i18n:getText("KRONEZX_PICKUPDOWN"), self.typeDesc), InputBinding.LOWER_IMPLEMENT);
    end;
	g_currentMission:addExtraPrintText("Tasten "..InputBinding.getButtonKeyName(InputBinding.KRONEZX_DEICHSELUP).." und "..InputBinding.getButtonKeyName(InputBinding.KRONEZX_DEICHSELDOWN)..": KroneZX Knickdeichsel auf / ab");
	g_currentMission:addExtraPrintText("Tasten "..InputBinding.getButtonKeyName(InputBinding.KRONEZX_KLAPPEDOWN).." und "..InputBinding.getButtonKeyName(InputBinding.KRONEZX_KLAPPEUP)..": KroneZX Ladeklappe auf / zu");
	
end;

function KroneZX:onDetach()
    if self.deactivateOnDetach then
        KroneZX.onDeactivate(self);
    else
        KroneZX.onDeactivateSounds(self);
    end;
end;

function KroneZX:onLeave()
    if self.deactivateOnLeave then
        KroneZX.onDeactivate(self);
    else
        KroneZX.onDeactivateSounds(self);
    end;
end;

function KroneZX:onDeactivate()
    --self.isTurnedOn = false;
    KroneZX.onDeactivateSounds(self);
end;

function KroneZX:onDeactivateSounds()
    if self.forageWgnSoundEnabled then
        stopSample(self.forageWgnSound);
        self.forageWgnSoundEnabled = false;
    end;
end;


