--
-- ClaasQuantum for CLAAS MOD, by Ls-ModSource.com
-- Specialization for ClaasQuantum functionality
--
-- LS-Modsource
-- @author  Manuel Leithner/Geri-G
-- @date  12/08/09
--

ClaasQuantum = {};

function ClaasQuantum.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(TowBall, specializations);
end;

function ClaasQuantum:load(xmlFile)

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

	local hydraulicsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hydraulics#count"), 0);	
	self.hydraulics = {};	
	for i=1, hydraulicsCount do
		local hydraulicName = string.format("vehicle.hydraulics.hydraulic%d", i);		
		self.hydraulics[i] = {};		
		self.hydraulics[i].node = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#index"));
		self.hydraulics[i].punch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punch"));
		self.hydraulics[i].translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punchFixpoint"));
		self.hydraulics[i].fixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#fixpoint"));	
		local ax, ay, az;		
		if self.hydraulics[i].punch ~= nil then
			ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
		else
			ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		end;
		if self.hydraulics[i].translationPunch ~= nil then
			local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);		
			self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		end;
	end;
	
	self.leftWheelSteeringIndex = 5;
	self.rightWheelSteeringIndex = 4;
	
	self.leftGuideRoller = {};
	local Quot = 16/9;

	local counterpath = Utils.getFilename("Panel.png", self.baseDirectory);
	local counterpath2 = Utils.getFilename("counterWarning.png", self.baseDirectory);
	local counterpath3 = Utils.getFilename("counterfill.png", self.baseDirectory);
	local hudPDAPoxX = 0.0;
    local hudPDAPoxY = 0.0; 
    local hudPDAHeight = 0.420;
    local hudPDAWidth = hudPDAHeight/Quot
	local PosX = 0.1540;
	local PosY = 0.1420;
	self.BHeight = 0.1080;
	local BWidth = 0.0203;

	self.hudBasePoxX = {};
	self.hudBasePoxY = {};
	self.hudBasePoxX[0] = hudPDAPoxX+0.0835;
	self.hudBasePoxY[0] = hudPDAPoxY+0.1800;	
	self.hudBasePoxX[1] = hudPDAPoxX+0.0000;
	self.hudBasePoxY[1] = hudPDAPoxY+0.0845;
	self.hudBasePoxX[1] = hudPDAPoxX+0.0360;
	self.hudBasePoxY[1] = hudPDAPoxY+0.2320;
	self.hudBasePoxX[2] = hudPDAPoxX+0.0360;
	self.hudBasePoxY[2] = hudPDAPoxY+0.2035;
	self.hudBasePoxX[3] = hudPDAPoxX+0.0365;
	self.hudBasePoxY[3] = hudPDAPoxY+0.1730;
	self.hudBasePoxX[4] = hudPDAPoxX+0.0380;
	self.hudBasePoxY[4] = hudPDAPoxY+0.1440;
	self.hudBasePoxX[5] = hudPDAPoxX+0.0395;
	self.hudBasePoxY[5] = hudPDAPoxY+0.1155;
	self.hudBasePoxX[6] = hudPDAPoxX+0.1890;
	self.hudBasePoxY[6] = hudPDAPoxY+0.2315;
	self.hudBasePoxX[7] = hudPDAPoxX+0.1890;
	self.hudBasePoxY[7] = hudPDAPoxY+0.2025;
	self.hudBasePoxX[8] = hudPDAPoxX+0.1890;
	self.hudBasePoxY[8] = hudPDAPoxY+0.1730;
	self.hudBasePoxX[9] = hudPDAPoxX+0.1870;
	self.hudBasePoxY[9] = hudPDAPoxY+0.1440;
	self.hudBasePoxX[10] = hudPDAPoxX+0.1860;
	self.hudBasePoxY[10] = hudPDAPoxY+0.1155;
    self.hudPDAOverlay = Overlay:new("hudPDAControl", counterpath, hudPDAPoxX, hudPDAPoxY, hudPDAWidth, hudPDAHeight);
    self.hudPDAOverlayL = Overlay:new("hudPDAControl2", counterpath2, hudPDAPoxX, hudPDAPoxY, hudPDAWidth, hudPDAHeight);
    self.hudPDAOverlayB = Overlay:new("hudPDAControl3", counterpath3, PosX, PosY, BWidth, self.BHeight);
	
	self.hayBase = {};
	self.hayBase.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.hayBase#index"));
	self.hayBase.unloadingSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hayBase#unloadingSpeed"), 0.001);
	self.hayBase.loadingSpeed = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hayBase#loadingSpeed"), 0.0005);
	self.hayBase.speed = self.hayBase.loadingSpeed;
	self.hayBase.unloadingDirection = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hayBase#unloadingDirection"), 1);
	self.hayBase.offset = 0;
	setShaderParameter(self.hayBase.node, "movingDirection", 0,0,0,0,false);
	
	self.pickup = {};
	self.pickup.minRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.pickup#minRotLimit"))};
	self.pickup.maxRot = {Utils.degToRad(getXMLFloat(xmlFile, "vehicle.pickup#maxRotLimit"))};
	self.pickup.rotTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pickup#rotTime"),2) * 1000;
	self.pickup.rake = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pickup#rake"));
	self.pickup.drum = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pickup#drum"));
	self.pickup.currentRot = {0};
	self.pickup.movingDirection = 0;
	
	self.drawBar = {};
	self.drawBar.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.drawBar#index"));
	local x = Utils.degToRad(getXMLFloat(xmlFile, "vehicle.drawBar#minRot"));
	self.drawBar.minRot = {x, 0, 0};
	x = Utils.degToRad(getXMLFloat(xmlFile, "vehicle.drawBar#maxRot"));
	self.drawBar.maxRot = {x, 0, 0};
	self.drawBar.rotTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.drawBar#rotTime"), 2) * 1000;
	self.drawBar.isDown = true;
	
	self.setHydraulicTime = 30;
	self.doTractorFixPointSearch = true;
	
	
    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;
	
    self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1);
    self.wasToFast = false;
    self.isTurnedOn = false;
	self.isHayBaseActive = false;
	self.hudActive = true;
end;

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

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

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

function ClaasQuantum:update(dt)	
	self.pickup.movingDirection = 0;
	if self:getIsActive() then
		if self:getIsActiveForInput() then
			if self.vehicleJoint ~= nil then
				if InputBinding.isPressed(InputBinding.LOWER_Quantum) then
					self.pickup.movingDirection = 1;
				end;
				if InputBinding.isPressed(InputBinding.LIFT_Quantum) then
					self.pickup.movingDirection = -1;
				end;			
			end;
			if InputBinding.hasEvent(InputBinding.QuadrantOverlay) then
				self.hudActive = not self.hudActive; 
			end;
			if InputBinding.hasEvent(InputBinding.LOWER_IMPLEMENT) then
				self.pickup.isDown = not self.pickup.isDown;
			end;
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
				self.isTurnedOn = not self.isTurnedOn;
				if not self.isTurnedOn then
					self.isHayBaseActive = false;
				end;
			end;
		end;
	end;
	
	if self.isHayBaseActive then
		self.hayBase.offset = self.hayBase.offset + self.hayBase.speed*dt;
		setShaderParameter(self.hayBase.node, "movingDirection", self.hayBase.unloadingDirection*self.hayBase.offset,0,0,0,false);
	end;	
	
	self.wasToFast = false;
	local pickupIsDown = false;
	
	if self:getIsActive() then
	
		if self.isTurnedOn then
			rotate(self.pickup.rake, -0.6 * dt, 0, 0);
		end;
		
		if self.pickup.currentRot[1] > (self.pickup.maxRot[1] / 2) then
			pickupIsDown = true;
		end;	
	
		self.setHydraulicTime = 30;
		

		
		if self.isTurnedOn  then
            local toFast = false;
			if pickupIsDown then
				toFast = self:doCheckSpeedLimit() and self.attacherVehicle.lastSpeed*3600 > 29;		

				if not toFast and self.capacity > self.fillLevel 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
								if self:allowFillType(fruitType) 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
										totalArea = totalArea+area;
										usedFruitType = fruitType;
									end;
								end;
							end;
						end;
					end;
					
					if totalArea > 0 then
						local pixelToQm = 2048 / 4096 * 2048 / 4096  / g_currentMission.maxFruitValue; -- 4096px are mapped to 2048m
						local literPerQm = FruitUtil.fruitIndexToDesc[usedFruitType].literPerQm * (1 + 0.5 * (3 - g_currentMission.missionStats.difficulty));
	                    local qm = totalArea*pixelToQm;
	                    local deltaLevel = qm*literPerQm * self.fillScale;
	                    self:setFillLevel(self.fillLevel+deltaLevel, usedFruitType);
					end;
				end;			
			end;

            self.wasToFast = toFast;
		end;

		if self.isTurnedOn or self.isHayBaseActive then
			if not self.forageWgnSoundEnabled and self:getIsActiveForSound() then
				playSample(self.forageWgnSound, 0, self.forageWgnSoundVolume, 0);
				setSamplePitch(self.forageWgnSound, self.forageWgnSoundPitchOffset);
				self.forageWgnSoundEnabled = true;
			end;
		end;
		
		
        if self.forageWgnSoundEnabled and (not self.isTurnedOn and not self.isHayBaseActive) then
            stopSample(self.forageWgnSound);
            self.forageWgnSoundEnabled = false;
        end;		
		
		local newRotLimit = Utils.getMovedLimitedValues(self.pickup.currentRot, self.pickup.maxRot, self.pickup.minRot, 1, self.pickup.rotTime, dt, not self.pickup.isDown);
		if math.abs(newRotLimit[1] - self.pickup.currentRot[1]) > 0.001 then	
			setJointRotationLimit(self.componentJoints[1].jointIndex, 0, true, 0, newRotLimit[1]);		
		end;		
		self.pickup.currentRot = newRotLimit;		
		
	
		if self.vehicleJoint ~= nil and self.pickup.movingDirection ~= 0 then
			local x, y, z = getRotation(self.drawBar.node);	
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.drawBar.maxRot, self.drawBar.minRot, 3, self.drawBar.rotTime, dt, self.pickup.movingDirection == 1);
			setRotation(self.drawBar.node, unpack(newRot));		
			
			if math.abs(x-newRot[1]) > 0.001 then
				setJointFrame(self.vehicleJoint.jointIndex, 1, self.attacherJoint.node);
				self:setHydraulicDirection(1);
				if not self.hydraulicSoundEnabled and self.hydraulicSound ~= nil and self:getIsActiveForSound() then
		            playSample(self.hydraulicSound, 0, self.hydraulicSoundVolume, 0);
		            setSamplePitch(self.hydraulicSound, self.hydraulicSoundPitchOffset-0.4);
		            self.hydraulicSoundEnabled = true;   
		        end;
			end;
		else
			if self.tipState ~= RealLoading.TIPSTATE_OPENING and self.tipState ~= RealLoading.TIPSTATE_CLOSING then
				if self.hydraulicSoundEnabled then
					stopSample(self.hydraulicSound);
					self.hydraulicSoundEnabled = false;   
				end;
			end;
		end;
		local FL = self.fillLevel;
		local Cap = self.capacity;
		local percent = (FL*100)/Cap;	
		local Height = (percent* self.BHeight)/100;
		self.hudPDAOverlayB.height = Height;	
	end;
	
	if self.setHydraulicTime > 0 then
		for i=0, 5 do 
			--self:setHydraulicDirection(i);
		end;
		self.setHydraulicTime = self.setHydraulicTime - 1;
	end;
end;

function ClaasQuantum:draw()
---Utils.RenderDevolpmentState("ClaasQuantum",1.1)

	if self.hudActive then
		g_currentMission:addHelpButtonText(g_i18n:getText("ClaasQuantumOverlay"), InputBinding.QuadrantOverlay);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("ClaasQuantumOverlay"), InputBinding.QuadrantOverlay);
	end; 
	if self.hudActive == true then
		self.hudPDAOverlay:render();
		setTextBold(true);
		setTextColor(1, 1, 1, 1.0);
		renderText(self.hudBasePoxX[1], self.hudBasePoxY[1], 0.020, string.format("%s",tostring(InputBinding.getButtonKeyName(InputBinding.LOWER_IMPLEMENT))));
		renderText(self.hudBasePoxX[2], self.hudBasePoxY[2], 0.020, string.format("%s",tostring(InputBinding.getButtonKeyName(InputBinding.IMPLEMENT_EXTRA))));
		renderText(self.hudBasePoxX[3], self.hudBasePoxY[3], 0.020, string.format("%s",tostring(InputBinding.getButtonKeyName(InputBinding.LOWER_Quantum))));
		renderText(self.hudBasePoxX[4], self.hudBasePoxY[4], 0.020, string.format("%s",tostring(InputBinding.getButtonKeyName(InputBinding.LIFT_Quantum))));
		if self.isTurnedOn then		
			self.hudPDAOverlayB:render();
		end;   
		if self.wasToFast then		
			self.hudPDAOverlayL:render();
		end;	
	end;
end;

function ClaasQuantum:setHydraulicDirection(index)
	local hydraulic = self.hydraulics[index];

	if hydraulic.fixPoint ~= nil then
		local ax, ay, az = getWorldTranslation(hydraulic.node);
		local bx, by, bz = getWorldTranslation(hydraulic.fixPoint);
		local x, y, z = worldDirectionToLocal(getParent(hydraulic.node), bx-ax, by-ay, bz-az);
		
		setDirection(hydraulic.node, x, y, z, 0, 1, 0);
		if hydraulic.punch ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(hydraulic.punch, 0, 0, distance-hydraulic.punchDistance);
		end;
	end;
end;


function ClaasQuantum:onAttach(attacherVehicle)
	self.doJointSearch = true;
end;

function ClaasQuantum:onDetach()
	self.vehicleJoint = nil;
	self.doTractorFixPointSearch = true;
	--self.hydraulics[self.leftWheelSteeringIndex].fixPoint = nil;
	--self.hydraulics[self.rightWheelSteeringIndex].fixPoint = nil;
	
	if self.deactivateOnDetach then
        ClaasQuantum.onDeactivate(self);
    else
        ClaasQuantum.onDeactivateSounds(self);
    end;
end;

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

function ClaasQuantum:onDeactivate()
    self.isTurnedOn = false;
	self.isHayBaseActive = false;
    ClaasQuantum.onDeactivateSounds(self);
end;

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