--[[
 regFruitTypeConverters

  @author: Ifko[nator]
  @date: 20.08.2017
  @version: 1.5
  
  @history: v1.0 @08.08.2017 - initial release in FS 17
			v1.5 @20.08.2017 - removed support to cut grass for not prepared vehicles 

]]

local newFillTypes = {};
local debugPriority = 0;

local function printDebug(debugMessage, priority, addStringDebug)
    if debugPriority >= priority then
        local prefix = "";
        
        if addStringDebug then
            prefix = "Debug from the regFruitTypeConverters.lua: ";
        end;
        
        print(prefix .. tostring(debugMessage));
    end;
end;

local function printError(errorMessage, isWarning, isInfo)
    local prefix = "Error ";
    
    if isWarning then
        prefix = "Warning ";
    end;
    
    if isInfo then
        prefix = "Info ";
    end;
    
    print(prefix .. "from the regFruitTypeConverters.lua: " .. tostring(errorMessage));
end;

local modDesc = loadXMLFile("modDescXML", g_currentModDirectory .. "modDesc.xml");
local key = "modDesc.regFruitTypeConverters";

local newFruitTypeConverters = Utils.splitString(" ", Utils.getNoNil(getXMLString(modDesc, key .. "#newFruitTypeConverters"), ""));

for _, newFruitTypeConverter in pairs(newFruitTypeConverters) do
    if FruitUtil["FRUITTYPE_CONVERTER_" .. string.upper(newFruitTypeConverter)] == nil then
        if newFruitTypeConverter ~= "" then
            FruitUtil.registerFruitTypeConverter(newFruitTypeConverter);
            
            printDebug("Register fruitType converter '" .. newFruitTypeConverter .. "' successfully.", 1, true);
        end;
    else
        printError("The converter: '" .. newFruitTypeConverter .. "' are allready exists!. Aborting register this converter now!", false, true);
    end;
end;

local newFruitTypeConverterNumber = 0;

local categoryCombineGrass = FillUtil.registerFillTypeCategory("combine_grass");
local categoryGrainHeaderGrass = FruitUtil.registerFruitTypeCategory("grainHeader_grass");
	
while true do
    local newFruitTypeConverterKey = key .. ".fruitTypeConverter(" .. tostring(newFruitTypeConverterNumber) .. ")";
    
    if not hasXMLProperty(modDesc, newFruitTypeConverterKey) then
    	break;
    end;
    
    local fruitTypeConverterName = getXMLString(modDesc, newFruitTypeConverterKey .. "#converterName");
    local fruitTypeName = getXMLString(modDesc, newFruitTypeConverterKey .. "#fruitTypeName");
    local tragetFillType = getXMLString(modDesc, newFruitTypeConverterKey .. "#tragetFillType");
    local conversationsFactor = Utils.getNoNil(getXMLFloat(modDesc, newFruitTypeConverterKey .. "#conversationsFactor"), 1);
    
    if fruitTypeConverterName ~= nil and fruitTypeName ~= nil and tragetFillType ~= nil then
        if FillUtil["FILLTYPE_" .. string.upper(tragetFillType)] ~= nil then	
            printDebug("Add fillType '" .. tragetFillType .. "' to fruitType converter '" .. fruitTypeConverterName .. "' successfully.", 1, true);
            
            FruitUtil.addFruitToFillTypeConversion(FruitUtil["FRUITTYPE_CONVERTER_" .. string.upper(fruitTypeConverterName)], FruitUtil["FRUITTYPE_" .. string.upper(fruitTypeName)], FillUtil["FILLTYPE_" .. string.upper(tragetFillType)], conversationsFactor);
            
            printDebug("Add fillType '" .. tragetFillType .. "' to fillType category 'combine_grass' successfully.", 1, true);
         
            FillUtil.addFillTypeToCategory(categoryCombineGrass, FillUtil["FILLTYPE_" .. string.upper(tragetFillType)]);
            
            printDebug("Add fillType '" .. fruitTypeName .. "' to fillType category 'combine_grass' successfully.", 1, true);

            FillUtil.addFillTypeToCategory(categoryCombineGrass, FillUtil["FILLTYPE_" .. string.upper(fruitTypeName)]);
			
            printDebug("Add fruitType '" .. fruitTypeName .. "' to fruitType category 'grainHeader_grass' successfully.", 1, true);

            FruitUtil.addFruitTypeToCategory(categoryGrainHeaderGrass, FruitUtil["FRUITTYPE_" .. string.upper(fruitTypeName)]);
            
            table.insert(newFillTypes, tragetFillType);
        else
            printError("Can't find fillType '" .. tragetFillType .. "'!", false, false);
        end;
    else
        if fruitTypeConverterName == nil then
            printError("Missing fruitTypeConverterName!", false, false);
        end;
        
        if fruitTypeName == nil then
            printError("Missing fruitTypeName!", false, false);
        end;
        
        if tragetFillType == nil then
            printError("Missing tragetFillType!", false, false);
        end;
    end;
    
    newFruitTypeConverterNumber = newFruitTypeConverterNumber + 1;
end;

local originalSowingMachineLoad = SowingMachine.load;

function SowingMachine.load(self, savegame)
    originalSowingMachineLoad(self, savegame);
    
    for _, newFillType in pairs(newFillTypes) do
        if string.find(newFillType, "seed") and self.fillUnits[self.sowingMachine.fillUnitIndex].fillTypes[FillUtil["FILLTYPE_" .. string.upper(newFillType)]] == nil then
            --## the fillType will only added to an sowing machine, when the script find 'seed' in his name
            
            self.fillUnits[self.sowingMachine.fillUnitIndex].fillTypes[FillUtil["FILLTYPE_" .. string.upper(newFillType)]] = true;
            
            printDebug("Insert '" .. newFillType .. "' to sowing machine successfully.", 1, true);
        end;
    end;
end;

function CombineUpdateTick(self, dt)
    printDebug("Hook function cutter update tick successfully.", 2, true);
	
    if self.isServer then
        self.lastArea = self.lastCuttersArea;
        self.lastAreaZeroTime = self.lastAreaZeroTime + dt;
		
        if self.lastArea > 0 then
            self.lastAreaZeroTime = 0;
            self.lastAreaNonZeroTime = g_currentMission.time;
        end;
		
        self.lastInputFruitType = self.lastCuttersInputFruitType;
        self.lastCuttersArea = 0;
        self.lastCuttersInputFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
        self.lastCuttersFruitType = FruitUtil.FRUITTYPE_UNKNOWN;

        if self.lastInputFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
            self.lastValidInputFruitType = self.lastInputFruitType;
        end;

        if self:getIsActive() then
           self.strawBufferCheckTimer = (#self.strawBuffer + 2) * self.strawBufferDuration;

           if self.lastAreaZeroTime > 500 then
                if self.combineFillDisableTime == nil then
                    self.combineFillDisableTime = g_currentMission.time + self.combineFillToggleTime;
                end;
            end;
			
            if self.combineFillEnableTime ~= nil and self.combineFillEnableTime <= g_currentMission.time then
                self:setCombineIsFilling(true, false, false);
                self.combineFillEnableTime = nil;
            end;
			
            if self.combineFillDisableTime ~= nil and self.combineFillDisableTime <= g_currentMission.time then
                self:setCombineIsFilling(false, false, false);
                self.combineFillDisableTime = nil;
            end;

            if self:getIsTurnedOn() then
                g_currentMission.missionStats:updateStats("threshedTime", dt/(1000*60));
                g_currentMission.missionStats:updateStats("workedTime", dt/(1000*60));
            end;
        else
            if self.strawBufferCheckTimer >= 0 then
                self.strawBufferCheckTimer = self.strawBufferCheckTimer - dt;
            end;
        end;

        if self.strawBufferCheckTimer >= 0 then
            self.strawBufferFillIndexTimer = self.strawBufferFillIndexTimer - dt;
			
            if self.strawBufferFillIndexTimer < 0 then
                self.strawBufferFillIndex = self.strawBufferFillIndex + 1;
				
                if self.strawBufferFillIndex > #self.strawBuffer then
                    self.strawBufferFillIndex = 1;
                end;
				
                self.strawBufferFillIndexTimer = self.strawBufferDuration;

                self.strawBufferDropIndex = self.strawBufferDropIndex + 1;
                if self.strawBufferDropIndex > #self.strawBuffer then
                    self.strawBufferDropIndex = 1;
                end;
				
                self.strawBufferDropValue = self.strawBuffer[self.strawBufferDropIndex];
            end;

            local isStrawEffectEnabled = false;
            local isChopperEffectEnabled = false;

            if self:getUnitLastValidFillType(self.overloading.fillUnitIndex) ~= FillUtil.FILLTYPE_UNKNOWN then
                local litersPerFrame = math.min(self.strawBufferDropValue * (dt/self.strawBufferDuration), self.strawBuffer[self.strawBufferDropIndex]);

                if self.isStrawEnabled then
                    local literToDrop = litersPerFrame + self.strawToDrop;
					local fruitIndex = FruitUtil.fillTypeToFruitType[self:getUnitLastValidFillType(self.overloading.fillUnitIndex)];
					local fruitDesc = FruitUtil.fruitIndexToDesc[fruitIndex];
					
                    --## The following code is hardcoded to grass_seed!
                    if self:getUnitLastValidFillType(self.overloading.fillUnitIndex) == FillUtil["FILLTYPE_GRASS_SEED"] then
                        fruitDesc = FruitUtil.fruitIndexToDesc[FillUtil["FILLTYPE_GRASS"]];
                    	
                        printDebug("change windrow fillType to '" .. FruitUtil.fruitTypeToWindrowFillType[fruitDesc.index] .. "'.", 2, true);
                    end;
                    
                    if fruitDesc ~= nil and fruitDesc.windrowLiterPerSqm ~= nil then
                        local windrowFillType = FruitUtil.fruitTypeToWindrowFillType[fruitDesc.index];

                        printDebug("fruitDesc = '" .. fruitDesc.name .. "'.", 2, true);
	
                        if literToDrop > 0 and windrowFillType ~= nil then
                            isStrawEffectEnabled = litersPerFrame > 0;
                            local typedWorkAreas = self:getTypedWorkAreas(WorkArea.AREATYPE_COMBINE);
                            local value = literToDrop/ #typedWorkAreas;
                            
                            for _, workArea in pairs(typedWorkAreas) do
                                local sx,sy,sz = getWorldTranslation(workArea.start);
                                local ex,ey,ez = getWorldTranslation(workArea.width);
                                local dropped, lineOffset = TipUtil.tipToGroundAroundLine(self, value, windrowFillType, sx,sy,sz, ex,ey,ez, 0, nil, self.combineLineOffset, false, nil, false);
                                self.combineLineOffset = lineOffset;
                                self.strawToDrop = value-dropped;
                            end;
                        end;
                    end;	
                else
                    isChopperEffectEnabled = litersPerFrame > 0;
                end;

                -- remove straw from buffer if chopper is active to allow instant switch to straw
                self.strawBuffer[self.strawBufferDropIndex] = self.strawBuffer[self.strawBufferDropIndex] - litersPerFrame;
            end;

            local currentDropIndex = self.strawBufferDropIndex;
			
            for i = 1, 2 do
                currentDropIndex = currentDropIndex + 1;
				
                if currentDropIndex > #self.strawBuffer then
                    currentDropIndex = 1;
                end;
				
                if self.strawBuffer[currentDropIndex] > 0 then
                    if self.chopperPSenabled and not self.isStrawEnabled and not isChopperEffectEnabled then
                        isChopperEffectEnabled = true;
                    end;
					
                    if self.strawPSenabled and self.isStrawEnabled and not isStrawEffectEnabled then
                        isStrawEffectEnabled = true;
                    end;
                end;
            end;

            self:setChopperPSEnabled(isChopperEffectEnabled, false, false);
            self:setStrawPSEnabled(isStrawEffectEnabled, false, false);
        end;

        if self:getUnitCapacity(self.overloading.fillUnitIndex) <= 0 then
            local fillLevel = self:getUnitFillLevel(self.overloading.fillUnitIndex);
			
            self.lastLostFillLevel = fillLevel;
			
            if fillLevel > 0 then
                self:setUnitFillLevel(self.overloading.fillUnitIndex, 0, self:getUnitFillType(self.overloading.fillUnitIndex), false);
            end;
        end;

        if  self.combineIsFilling ~= self.sentCombineIsFilling or
            self.chopperPSenabled ~= self.sentChopperPSenabled or
            self.strawPSenabled ~= self.sentStrawPSenabled
        then
            self:raiseDirtyFlags(self.combineDirtyFlag);
            self.sentCombineIsFilling = self.combineIsFilling;
            self.sentChopperPSenabled = self.chopperPSenabled;
            self.sentStrawPSenabled = self.strawPSenabled;
        end;
    end;
end;

Combine.updateTick = CombineUpdateTick;

TipTriggerExtension = {};

function TipTriggerExtension:loadMap(name)	
    for _, tipTrigger in pairs(g_currentMission.tipTriggers) do
        for fillTypeInt, _ in pairs(tipTrigger.acceptedFillTypes) do
            fillTypeName = FillUtil.fillTypeIntToName[fillTypeInt];
            
            if fillTypeName == "wheat" or fillTypeName == "silage" then
                local allowedToolTypes = {TipTrigger.TOOL_TYPE_TRAILER,TipTrigger.TOOL_TYPE_SHOVEL, TipTrigger.TOOL_TYPE_PIPE, TipTrigger.TOOL_TYPE_PALLET};
                
                for _, newFillType in pairs(newFillTypes) do
                    local price = FillUtil.fillTypeIndexToDesc[FillUtil["FILLTYPE_" .. string.upper(newFillType)]].pricePerLiter * 1.2;
                    local fillType = FillUtil["FILLTYPE_" .. string.upper(newFillType)];
                    
                    tipTrigger:addAcceptedFillType(fillType, price, true, false, allowedToolTypes);
                    tipTrigger:initPricingDynamics();
                    
                    local triggerName = tipTrigger.stationName;
                    
                    if g_i18n:hasText(triggerName) then
                    	triggerName = g_i18n:getText(triggerName);
                    end;
                    
                    printDebug("Insert '" .. newFillType .. "' to tipTrigger '" .. triggerName .. "' successfully.", 1, true);
                end;
            end;
        end;
    end;
end;

function TipTriggerExtension:deleteMap()end;
function TipTriggerExtension:mouseEvent(posX, posY, isDown, isUp, button)end;
function TipTriggerExtension:keyEvent(unicode, sym, modifier, isDown)end;
function TipTriggerExtension:update(dt)end;
function TipTriggerExtension:draw()end;

addModEventListener(TipTriggerExtension);