--
-- HaweULW
--
-- @author  Manuel L. (1.LS-Modschmiede)
-- @date  25/09/08
--
-- @Umbau auf LS09 Jack85 (1.LS-Modschmiede)
-- @date 15/04/09

HaweULW = {};

HaweULW.UNLOADING_CLOSED = 0;
HaweULW.UNLOADING_OPENING = 1;
HaweULW.UNLOADING_OPEN = 2;
HaweULW.UNLOADING_CLOSING = 3;

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

function HaweULW:load(xmlFile)

    self.toggleUnloadingState = SpecializationUtil.callSpecializationsFunction("toggleUnloadingState");
    self.onStartUnloading = SpecializationUtil.callSpecializationsFunction("onStartUnloading");
    self.onEndUnloading = SpecializationUtil.callSpecializationsFunction("onEndUnloading");
    self.findTrailerRaycastCallback = Combine.findTrailerRaycastCallback;

    self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1);

    self.pipeParticleSystem = {};
    self.pipeParticleSystemindex = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.pipeParticleSystem#index"));
    Utils.loadParticleSystem(xmlFile, self.pipeParticleSystem, "vehicle.pipeParticleSystem", self.pipeParticleSystemindex, false, nil, self.baseDirectory);

	
	self.unloadingDischargeEndTime = getXMLFloat(xmlFile, "vehicle.unloadingAnimation#endTime");

	local unloadingAnimRootNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.unloadingAnimation#rootNode"));
    self.unloadingAnimCharSet = 0;
    if unloadingAnimRootNode ~= nil and unloadingAnimRootNode ~= 0 then
        self.unloadingAnimCharSet = getAnimCharacterSet(unloadingAnimRootNode);
        if self.unloadingAnimCharSet ~= 0 then
            local clip = getAnimClipIndex(self.unloadingAnimCharSet, getXMLString(xmlFile, "vehicle.unloadingAnimation#clip"));
            assignAnimTrackClip(self.unloadingAnimCharSet, 0, clip);
            setAnimTrackLoopState(self.unloadingAnimCharSet, 0, false);
            self.unloadingAnimSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.unloadingAnimation#speedScale"), 1);
            self.unloadingAnimDuration = getAnimClipDuration(self.unloadingAnimCharSet, clip);
            if self.unloadingDischargeEndTime == nil then
                self.unloadingDischargeEndTime = self.unloadingAnimDuration*2.0;
            end;
        end;
    end;
	self.unloadingState = Trailer.UNLOADING_CLOSED;

    local pipeSound = getXMLString(xmlFile, "vehicle.pipeSound#file");
    if pipeSound ~= nil and pipeSound ~= "" then
        pipeSound = Utils.getFilename(pipeSound, self.baseDirectory); 
        self.pipeSound = createSample("pipeSound");
        loadSample(self.pipeSound, pipeSound, false);
        self.pipeSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipeSound#pitchOffset"), 1);
        self.pipeSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipeSound#pitchScale"), 0);
        self.pipeSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipeSound#pitchMax"), 2.0);
	  self.pipeSoundEnabled = false;
    end;

    local fillSound = getXMLString(xmlFile, "vehicle.fillSound#file");
    if fillSound ~= nil and fillSound ~= "" then
        self.fillSound = createSample("fillSound");
        loadSample(self.fillSound, fillSound, false);
        self.fillSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillSound#pitchOffset"), 1);
        self.fillSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillSound#pitchMax"), 2.0);
        self.fillSoundEnabled = false;
    end;
	
	self.windowGrainPlane = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.windowGrainPlane#index"));

    self.windowGrainPlaneMinY, self.windowGrainPlaneMaxY = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.windowGrainPlane#minMaxY"));
    if self.windowGrainPlaneMinY == nil or self.windowGrainPlaneMaxY == nil then
        local windowGrainAnimCurve = AnimCurve:new(linearInterpolator4);
        local keyI = 0;
        while true do
            local key = string.format("vehicle.windowGrainPlane.key(%d)", keyI);
            local t = getXMLFloat(xmlFile, key.."#time");
            local yValue = getXMLFloat(xmlFile, key.."#y");
            local scaleX,scaleY,scaleZ = Utils.getVectorFromString(getXMLString(xmlFile, key.."#scale"));
            if y == nil or scaleX == nil or scaleY == nil or scaleZ == nil then
                break;
            end;
            windowGrainAnimCurve:addKeyframe({x=scaleX, y=scaleY, z=scaleZ, w=yValue, time = t});
            keyI = keyI +1;
        end;
        if keyI > 0 then
            self.windowGrainAnimCurve = windowGrainAnimCurve;
        end;
        self.windowGrainPlaneMinY = 0;
        self.windowGrainPlaneMaxY = 0;
    end;


	
	self.trailerPosition = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.trailerPosition#index"));
	
	self.grainUnloading = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.grainUnloading"), 10);
	
	self.trailingTruckBackAngle = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.trailingTruck#backAngle"), 25);
	self.trailingTruckFrontAngle = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.trailingTruck#frontAngle"), 12);
	self.trailingTruckActive = true;
	
	
	 self.hudHawepath = Utils.getFilename("haweControl.png", self.baseDirectory);
	self.hudHawePoxX = 0.501;
    self.hudHawePoxY = 1-0.204;
    self.hudHaweWidth = 0.256;
    self.hudHaweHeight = 0.256;
	self.hudBasePoxX = 0.531;
    self.hudBasePoxY = 0.9069; --1-0.094; 0.907 0.001
    self.hudHaweOverlay = Overlay:new("hudHaweControl", self.hudHawepath, self.hudHawePoxX, self.hudHawePoxY, self.hudHaweWidth, self.hudHaweHeight);

	
	self.isExpanded = false;
	self.pipeParticleActivated = false;
	self.isActive = false;
	self.bcActive = false;
	
	self.sowingMachineFound = 0;
	    	local rotationPartNodeklapa = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.klapa#index"));
    if rotationPartNodeklapa ~= nil then
        self.rotationPartklapa = {};
        self.rotationPartklapa.node = rotationPartNodeklapa;

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

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

        self.rotationPartklapa.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.klapa#rotTime"), 2)*1000;
        self.rotationPartklapa.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.klapa#touchRotLimit"), 10));
    end;
end;

function HaweULW:delete()
	if self.hudHaweOverlay ~= nil then
		self.hudHaweOverlay:delete();
	end;
end;

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

function HaweULW:keyEvent(unicode, sym, modifier, isDown)
	
	if self.attacherVehicle ~= nil then
		if isDown and sym == Input.KEY_n then
			self:toggleUnloadingState();
		end;
		if isDown and sym == Input.KEY_k then
			self.trailingTruckActive = not self.trailingTruckActive;
		end;
		if self.trailerFound ~= 0 or self.sowingMachineFound ~= 0 then
			if isDown and sym == Input.KEY_m then
				self.activeUnloading = not self.activeUnloading;
				self.pipeParticleActivated = not self.pipeParticleActivated;
			
			end;
		end;
		if isDown and sym == 48 then -- Key: 0
			self.bcActive = not self.bcActive;
		end;
	end;
end;

function HaweULW:update(dt)
		
	local angle = 0;
	local frontAngle = 0;
	local backAngle = 0;	

		if self.unloadingState == HaweULW.UNLOADING_OPENING then 
            if self.pipeSound ~= nil and not self.pipeSoundEnabled then
                    setSamplePitch(self.pipeSound, self.pipeSoundPitchOffset);
                    playSample(self.pipeSound, 0, 1, 0);
                    self.pipeSoundEnabled = true;
                end;
   		end;

		if self.unloadingState == HaweULW.UNLOADING_OPEN then 
            if self.pipeSound ~= nil and self.pipeSoundEnabled then
                    stopSample(self.pipeSound);
                    self.pipeSoundEnabled = false;
                end;
   		end;

		if self.unloadingState == HaweULW.UNLOADING_CLOSING then 
            if self.pipeSound ~= nil and not self.pipeSoundEnabled then
                    setSamplePitch(self.pipeSound, self.pipeSoundPitchOffset);
                    playSample(self.pipeSound, 0, 1, 0);
                    self.pipeSoundEnabled = true;
                end;
   		end;

		if self.unloadingState == HaweULW.UNLOADING_CLOSED then 
            if self.pipeSound ~= nil and self.pipeSoundEnabled then
                    stopSample(self.pipeSound);
                    self.pipeSoundEnabled = false;
                end;
   		end;

		if self.activeUnloading and self.pipeParticleActivated then
        	if not self.fillSoundEnabled and self.fillLevel > 0 and self.fillSound ~= nil then
            playSample(self.fillSound, 0, self.fillSoundVolume, 0);
            self.fillSoundEnabled = true;   
        end;
	else
        if self.fillSoundEnabled then
            stopSample(self.fillSound);
            self.fillSoundEnabled = false;   
        end;
	
	end;


	
	if self.trailingTruckActive and self.attacherVehicle ~= nil then
		local x1,y1,z1 = localDirectionToWorld(self.attacherVehicle.rootNode, 0, 0, 1);
		local x2,y2,z2 = localDirectionToWorld(self.rootNode, 0, 0, 1);
		--2. skalar produkt, wobei y wert ignorieren
		local dot = x1*x2 + z1*z2;
		--3. durch laengen teilen
		dot = dot / (Utils.vector2Length(x1,z1) * Utils.vector2Length(x2,z2));
		--4. arccosine nehmen
		angle = math.acos(dot);		
		-- y component of cross product
		local cy = z1 * x2 - x1 * z2;		
		if cy < 0 then
			angle = -angle;
		end;		
		frontAngle = (self.trailingTruckFrontAngle * (angle / 50)) * -1;
		backAngle  = self.trailingTruckBackAngle * (angle / 50);				
	end;			
	
	for i=1, table.getn(self.wheels) do
		local x,y,z = getRotation(self.wheels[i].repr);			
		local newX, newY, newZ = getWheelShapePosition(self.wheels[i].node, self.wheels[i].wheelShape);
		setTranslation(self.wheels[i].repr, newX, newY, newZ);
		local axleSpeed = getWheelShapeAxleSpeed(self.wheels[i].node, self.wheels[i].wheelShape)*3.14159/180;
		x = x+axleSpeed*dt/1000.0;
		if i == 1 or i == 4 then
			setWheelShapeProps(self.wheels[i].node, self.wheels[i].wheelShape, 0, 0, frontAngle);
			setRotation(self.wheels[i].repr, x, frontAngle, z);
		elseif i == 3 or i == 6 then
			setWheelShapeProps(self.wheels[i].node, self.wheels[i].wheelShape, 0, 0, backAngle);
			setRotation(self.wheels[i].repr, x, backAngle, z);					
		else
			steeringAngle = 0;
			setRotation(self.wheels[i].repr, x, steeringAngle, z);
		end;
	end;
	
	if self.unloadingState == HaweULW.UNLOADING_OPENING or self.unloadingState == HaweULW.UNLOADING_OPEN then
        if self.unloadingState == HaweULW.UNLOADING_OPENING then
            if getAnimTrackTime(self.unloadingAnimCharSet, 0) > self.unloadingAnimDuration then
                self.unloadingState = HaweULW.UNLOADING_OPEN;
            end;
        end;
    elseif self.unloadingState == HaweULW.UNLOADING_CLOSING then
        if getAnimTrackTime(self.unloadingAnimCharSet, 0) < 0.0 then
            self.unloadingState = HaweULW.UNLOADING_CLOSED;
        end;
    end;
	
	
	self.pipeParticleActivated = false;
	self.trailerFound = 0;
	self.sowingMachineFound = 0;
    if self.unloadingState == HaweULW.UNLOADING_OPEN and self.fillLevel > 0 and self.attacherVehicle ~= nil then
	
        self.pipeParticleActivated = true;
        self.trailerFound = 0;
        local x,y,z = getWorldTranslation(self.trailerPosition);
        raycastAll(x, y, z, 0, -1, 0, "findTrailerRaycastCallback", 10, self);
       
		
        local trailer = g_currentMission.objectToTrailer[self.trailerFound];
		local sowingMachine = nil;
		
		if self.sowingMachineFound ~= 0 then	
			local implements = g_currentMission.attachables;
			for i=0, table.getn(implements) do
				if implements[i] ~= nil then
					if implements[i].rootNode == self.sowingMachineFound then
						sowingMachine = implements[i];
					end;
				end;			
			end;
		end;		
		
        if (self.trailerFound == 0 or not trailer:allowFillType(self.currentFillType)) and (self.sowingMachineFound == 0 or not sowingMachine:allowFillType(sowingMachine.FILLTYPE_WHEAT)) then
            self.pipeParticleActivated = false;
			self.activeUnloading = false;
        else
			if self.activeUnloading then
	           self.rotationMaxklapa = true;
			   local deltaLevel = self.grainUnloading;
				if sowingMachine ~= nil then
					deltaLevel = math.min(deltaLevel, sowingMachine.capacity - sowingMachine.fillLevel);
				elseif trailer ~= nil then
					deltaLevel = math.min(deltaLevel, trailer.capacity - trailer.fillLevel);
				else
					deltaLevel = 0;
				end;

	            self.fillLevel = self.fillLevel-deltaLevel;
	            if self.fillLevel <= 0.0 then
	                deltaLevel = deltaLevel+self.fillLevel;
	                self.fillLevel = 0.0;
	                pipeParticleActivated = false;
	            end;
	            if deltaLevel == 0 then
	                self.pipeParticleActivated = false;
	            end;
	            self:setFillLevel(self.fillLevel, self.currentFillType);
				if sowingMachine ~= nil then
					sowingMachine:setFillLevel(sowingMachine.fillLevel+deltaLevel, sowingMachine.FILLTYPE_WHEAT);
				elseif trailer ~= nil then
					trailer:setFillLevel(trailer.fillLevel+deltaLevel, self.currentFillType);
				end;
			else
				self.pipeParticleActivated = false;
			end;
        end;
	else
		self.activeUnloading = false;	
    end;

	if not self.activeUnloading then
		self.rotationMaxklapa = false;
	end;
		if self.activeUnloading and self.pipeParticleActivated then

		Utils.setEmittingState(self.pipeParticleSystem, true);
		else
		Utils.setEmittingState(self.pipeParticleSystem, false);
		end;
if self.rotationPartklapa ~= nil then
		local x, y, z = getRotation(self.rotationPartklapa.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartklapa.maxRot, self.rotationPartklapa.minRot, 3, self.rotationPartklapa.rotTime, dt, not self.rotationMaxklapa);
		setRotation(self.rotationPartklapa.node, unpack(newRot));
   end;	
end;

function HaweULW:draw()
	if self.attacherVehicle ~= nil then
		if self.unloadingState == HaweULW.UNLOADING_OPEN or self.unloadingState == HaweULW.UNLOADING_OPENING then
			g_currentMission:addExtraPrintText("Wcisnij N: Przekrec Zbiornik");
		else
			g_currentMission:addExtraPrintText("Wcisnij N: Przekrec Zbiornik");
		end;
		if self.unloadingState == HaweULW.UNLOADING_OPEN and (self.trailerFound ~= 0 or self.sowingMachineFound ~= 0) then
			if self.activeUnloading and self.pipeParticleActivated then
				g_currentMission:addExtraPrintText("Wcisnij M: Wyl. Wysypywanie");
			else
				g_currentMission:addExtraPrintText("Wcisnij M: Wl. Wysypywanie");
			end;
		end;
		
		
		
	end;
end;

function HaweULW:onDetach()
end;

function HaweULW:setFillLevel(fillLevel, fillType)
	Trailer.setFillLevel(self, fillLevel, fillType);
    if self.windowGrainPlane ~= nil then
        local yTranslation;
        if self.windowGrainAnimCurve then
            local scaleX, scaleY, scaleZ , yTrans = self.windowGrainAnimCurve:get(self.fillLevel/self.capacity);
            yTranslation = yTrans;
            setScale(self.windowGrainPlane, scaleX, scaleY, scaleZ);
        else
            local m = (self.windowGrainPlaneMaxY - self.windowGrainPlaneMinY) / self.capacity;
            yTranslation = m*self.fillLevel + self.windowGrainPlaneMinY;
        end;
            local xPos, yPos, zPos = getTranslation(self.windowGrainPlane);
        setTranslation(self.windowGrainPlane, xPos, yTranslation, zPos);
        setVisibility(self.windowGrainPlane, self.fillLevel ~= 0);
    end;

end;

function HaweULW:findTrailerRaycastCallback(transformId, x, y, z, distance)
    self.trailerFound = 0;
	self.sowingMachineFound = 0;
    if getUserAttribute(transformId, "vehicleType") == 2 then
        self.trailerFound = transformId;
    end;
	
	if getUserAttribute(transformId, "sowingMachine") then
		self.sowingMachineFound = transformId;
	end;
	
    return false;
end;

function HaweULW:toggleUnloadingState()

    if self.unloadingState == 0 then
        self:onStartUnloading();
    else
        self:onEndUnloading();
    end;
end;

function HaweULW:onStartUnloading()

    if self.unloadingAnimCharSet ~= 0 then
        if getAnimTrackTime(self.unloadingAnimCharSet, 0) < 0.0 then
            setAnimTrackTime(self.unloadingAnimCharSet, 0, 0.0);
        end;
        setAnimTrackSpeedScale(self.unloadingAnimCharSet, 0, self.unloadingAnimSpeedScale);
        enableAnimTrack(self.unloadingAnimCharSet, 0);
    end;
    self.unloadingState = HaweULW.UNLOADING_OPENING;
end;

function HaweULW:onEndUnloading()
    if self.unloadingAnimCharSet ~= 0 then
        if getAnimTrackTime(self.unloadingAnimCharSet, 0) > self.unloadingAnimDuration then
            setAnimTrackTime(self.unloadingAnimCharSet, 0, self.unloadingAnimDuration);
        end;
        setAnimTrackSpeedScale(self.unloadingAnimCharSet, 0, -self.unloadingAnimSpeedScale);
        enableAnimTrack(self.unloadingAnimCharSet, 0);
    end;
    self.unloadingState = HaweULW.UNLOADING_CLOSING;
end;

function HaweULW:toggleTipState()
end;

