--
-- Advance Thresher Specialization for Vehicles
-- V.1.0
-- @author  Knagsted
-- @date  16/07/10

-- Do not edit without my permission


advancedThresher = {};

advancedThresher.SHORT_GRAIN_INDEX = 1;
advancedThresher.LONG_GRAIN_INDEX = 2;
advancedThresher.BIG_ROUND_GRAIN_INDEX = 3;
advancedThresher.SMALL_ROUND_GRAIN_INDEX = 4;

function advancedThresher.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Combine, specializations);
end;

function advancedThresher:load(xmlFile)
	self.calculateSpill = SpecializationUtil.callSpecializationsFunction("calculateSpill");
	
	self.grainTypeSwitch = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.grainTypeSwitch#index"));
	self.threasherGrainTypeSelection = 1;
	
	self.shortGrainTypes = {};
    self.shortGrainTypes[FruitUtil.FRUITTYPE_UNKNOWN] = true;
	self.shortGrainTypes.optimalThreasherSpeed = getXMLString(xmlFile, "vehicle.shortGrainTypes#optimalThreasherSpeed");

    local fruitTypes = getXMLString(xmlFile, "vehicle.shortGrainTypes#fruitTypes");
    if fruitTypes ~= nil then
        local types = Utils.splitString(" ", fruitTypes);
        for k,v in pairs(types) do
            local desc = FruitUtil.fruitTypes[v];
            if desc ~= nil then
                self.shortGrainTypes[desc.index] = v;
            end;
        end;
    end;
	
	
	self.longGrainTypes = {};
    self.longGrainTypes[FruitUtil.FRUITTYPE_UNKNOWN] = true;
	self.longGrainTypes.optimalThreasherSpeed = getXMLString(xmlFile, "vehicle.longGrainTypes#optimalThreasherSpeed");

    local fruitTypes = getXMLString(xmlFile, "vehicle.longGrainTypes#fruitTypes");
    if fruitTypes ~= nil then
        local types = Utils.splitString(" ", fruitTypes);
        for k,v in pairs(types) do
            local desc = FruitUtil.fruitTypes[v];
            if desc ~= nil then
                self.longGrainTypes[desc.index] = v;
            end;
        end;
    end;
	
	self.bigRoundGrainTypes = {};
    self.bigRoundGrainTypes[FruitUtil.FRUITTYPE_UNKNOWN] = true;
	self.bigRoundGrainTypes.optimalThreasherSpeed = getXMLString(xmlFile, "vehicle.bigRoundGrainTypes#optimalThreasherSpeed");
	
    local fruitTypes = getXMLString(xmlFile, "vehicle.bigRoundGrainTypes#fruitTypes");
    if fruitTypes ~= nil then
        local types = Utils.splitString(" ", fruitTypes);
        for k,v in pairs(types) do
            local desc = FruitUtil.fruitTypes[v];
            if desc ~= nil then
                self.bigRoundGrainTypes[desc.index] = v;
            end;
        end;
    end;
	
	self.smallRoundGrainTypes = {};
    self.smallRoundGrainTypes[FruitUtil.FRUITTYPE_UNKNOWN] = true;
	self.smallRoundGrainTypes.optimalThreasherSpeed = getXMLString(xmlFile, "vehicle.smallRoundGrainTypes#optimalThreasherSpeed");

    local fruitTypes = getXMLString(xmlFile, "vehicle.smallRoundGrainTypes#fruitTypes");
    if fruitTypes ~= nil then
        local types = Utils.splitString(" ", fruitTypes);
        for k,v in pairs(types) do
            local desc = FruitUtil.fruitTypes[v];
            if desc ~= nil then
                self.smallRoundGrainTypes[desc.index] = v;
            end;
        end;
    end;
	
	local rotationPartNodeSpillnadel = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rotationPartSpillnadel#index"));
    if rotationPartNodeSpillnadel ~= nil then
        self.rotationPartSpillnadel = {};
        self.rotationPartSpillnadel.node = rotationPartNodeSpillnadel;

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

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

        self.rotationPartSpillnadel.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartSpillnadel#rotTime"), 2)*1000;
        self.rotationPartSpillnadel.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartSpillnadel#touchRotLimit"), 10));
    end;
	
	self.spillValue = 0;
	self.lastSpill = 0;
	self.rawSpillValue = 0;
	self.lastRawSpillValue = 0;	
end;

function advancedThresher:delete()
end;

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

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

function advancedThresher:update(dt)
	--renderText(0.5, 0.65, 0.040, string.format(self.shortGrainTypes.optimalThreasherSpeed));
	if self.isEntered then
		if InputBinding.hasEvent(InputBinding.SELECTGRAINTYPE_CIH5130) then
			self.threasherGrainTypeSelection = self.threasherGrainTypeSelection + 1;
			if self.threasherGrainTypeSelection > 4 then
				self.threasherGrainTypeSelection = 1;
			end;
		end;
		
		if self.grainTypeSwitch ~= nil then
			setRotation(self.grainTypeSwitch, Utils.degToRad(-180), Utils.degToRad((self.threasherGrainTypeSelection * 65)), 0);
		end;
	end;
	self:calculateSpill(dt);
	
	--Adjust the harvest outcome based on spill
	self.lastRawSpillValue = (self.lastRawSpillValue + self.rawSpillValue)/2;
	self.threshingScale = (100 - self.rawSpillValue) * 0.01;
	--renderText(0.5, 0.65, 0.040, string.format(self.threshingScale * 100));
end;

function advancedThresher:draw()
	if self.isEntered then
		if self.HUDActive then
			if self.isMotorStarted then
				setTextBold(true);
				setTextColor(200, 0, 0, 1.0);
				renderText(0.974, 0.885, 0.020, string.format("%d ",self.lastRawSpillValue));
			end;
		end;
	end;
end;

function advancedThresher:calculateSpill(dt)
	local spill = -1;
	
	if self.lastArea > 0 then
		if self.threasherGrainTypeSelection == advancedThresher.SHORT_GRAIN_INDEX then
			for k,v in pairs(self.shortGrainTypes) do
				if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
					spill = 1;
					if self.actualRotorSpeedValue ~= nil then
						spill = spill * ((self.actualRotorSpeedValue - self.shortGrainTypes.optimalThreasherSpeed) * 0.08);
						if spill < 0 then
							spill = -1 * spill;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a long grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.longGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 30;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.longGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a big round grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.bigRoundGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 50;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.bigRoundGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a small round grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.smallRoundGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 10;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.smallRoundGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
		elseif self.threasherGrainTypeSelection == advancedThresher.LONG_GRAIN_INDEX then
			for k,v in pairs(self.longGrainTypes) do
				if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
					spill = 1;
					if self.actualRotorSpeedValue ~= nil then
						spill = spill * ((self.actualRotorSpeedValue - self.longGrainTypes.optimalThreasherSpeed) * 0.08);
						if spill < 0 then
							spill = -1 * spill;
						end;
					end;
				end;
			end;

			--Check if we are harvesting a short grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.shortGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 10;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.shortGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a big round grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.bigRoundGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 30;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.bigRoundGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a small round grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.smallRoundGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 40;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.smallRoundGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;

		elseif self.threasherGrainTypeSelection == advancedThresher.BIG_ROUND_GRAIN_INDEX then
			for k,v in pairs(self.bigRoundGrainTypes) do
				if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
					spill = 1;
					if self.actualRotorSpeedValue ~= nil then
						spill = spill * ((self.actualRotorSpeedValue - self.bigRoundGrainTypes.optimalThreasherSpeed) * 0.08);
						if spill < 0 then
							spill = -1 * spill;
						end;
					end;
				end;
			end;

			--Check if we are harvesting a short grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.shortGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 20;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.shortGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a long grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.longGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 30;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.longGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a small round grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.smallRoundGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 20;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.smallRoundGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;

		elseif self.threasherGrainTypeSelection == advancedThresher.SMALL_ROUND_GRAIN_INDEX then
			for k,v in pairs(self.smallRoundGrainTypes) do
				if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
					spill = 1;
					if self.actualRotorSpeedValue ~= nil then
						spill = spill * ((self.actualRotorSpeedValue - self.smallRoundGrainTypes.optimalThreasherSpeed) * 0.08);
						if spill < 0 then
							spill = -1 * spill;
						end;
					end;
				end;
			end;

			--Check if we are harvesting a short grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.shortGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 30;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.shortGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a long grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.longGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 40;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.longGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
			
			--Check if we are harvesting a big round grain type and adjust spill accordingly compared to our threasher setting
			if spill == -1 then
				--Different spills acording to grain type
				for k,v in pairs(self.bigRoundGrainTypes) do
					if FruitUtil.fruitIndexToDesc[self.currentFillType] ~= nil and FruitUtil.fruitIndexToDesc[self.currentFillType].name == v then
						spill = 60;
						if self.actualRotorSpeedValue ~= nil then
							spill = spill * ((self.actualRotorSpeedValue - self.bigRoundGrainTypes.optimalThreasherSpeed) * 0.08);
							if spill < 0 then
								spill = -1 * spill;
							end;
						end;
					end;
				end;
			end;
		end;
				
		if spill == -1 then
			spill = 0;
		end;
	else
		spill = 0;
	end;
	
	if spill > 99 then
		spill = 99;
	end;
	
	self.rawSpillValue = spill;
	
	local adjustedSpill = 0;
	if spill > 0 then
		adjustedSpill = spill + 45;
	end;
	
	if self.lastSpill < adjustedSpill then
		self.spillValue = self.lastSpill + 0.1 * dt;
	elseif self.lastSpill > adjustedSpill then
		self.spillValue = self.lastSpill - 0.1 * dt;
	elseif adjustedSpill == 0 then
		self.spillValue = 0;
	end;
	
	self.lastSpill = self.spillValue;
	--renderText(0.5, 0.65, 0.040, string.format(adjustedSpill));
	--renderText(0.5, 0.75, 0.040, string.format(self.spillValue));
	if self.rotationPartSpillnadel ~= nil then
		local x, y, z = getRotation(self.rotationPartSpillnadel.node);
		z = ((self.rotationPartSpillnadel.maxRot[3] - self.rotationPartSpillnadel.minRot[3]) / 100) * self.spillValue + self.rotationPartSpillnadel.minRot[3];
		--renderText(0.5, 0.55, 0.040, string.format(((y/3.14)*180)));
		setRotation(self.rotationPartSpillnadel.node, x, y ,z);
	end;
end;