RepairVehicle = {
    prerequisitesPresent = function()
        return true
    end,
    Version = "1.0.0.0",
    Name = "RepairVehicle",
    Debug = true
}



function RepairVehicle.DebugText(text, ...)
    if not RepairVehicle.Debug then return end
    print("RepairVehicleDebug: " .. string.format(text, ...));
end

print("init " .. RepairVehicle.Name .. "(Version: " .. RepairVehicle.Version .. ")");

function RepairVehicle.initSpecialization()
    local schema = Vehicle.xmlSchema
    schema:setXMLSpecializationType("DamageModi")

    local baseXmlPath = "vehicle.DamageModi.DamageModiConfigurations.DamageModiConfiguration(?)"

    schema:register(XMLValueType.NODE_INDEX, baseXmlPath .. ".triggerNodes.triggerNode(?)#node", "TriggerNode")
    schema:register(XMLValueType.FLOAT, baseXmlPath .. "#repairPerInterval", "DamagePercent", 0.1)
    schema:register(XMLValueType.INT, baseXmlPath .. "#repairInterval", "milisec", 3000)
    schema:register(XMLValueType.INT, baseXmlPath .. "#repairCostFactor", "factorx", 1)
    schema:register(XMLValueType.INT, baseXmlPath .. "#fillUnitIndex", "FillUnit")
	
   schema:setXMLSpecializationType()
end

function RepairVehicle.registerEventListeners(vehicleType)
    SpecializationUtil.registerEventListener(vehicleType, "onLoad", RepairVehicle);
    SpecializationUtil.registerEventListener(vehicleType, "onDelete", RepairVehicle)
end

function RepairVehicle.registerFunctions(vehicleType)
    SpecializationUtil.registerFunction(vehicleType, "repairTriggerCallback", RepairVehicle.repairTriggerCallback);
    SpecializationUtil.registerFunction(vehicleType, "writeToLog", RepairVehicle.writeToLog);
    SpecializationUtil.registerFunction(vehicleType, "startRepairVehicles", RepairVehicle.startRepairVehicles);
end

function RepairVehicle:onLoad(savegame)
    local DamageModiConfigurationId = Utils.getNoNil(self.configurations["DamageModi"], 1)
    local baseXmlPath = string.format("vehicle.DamageModi.DamageModiConfigurations.DamageModiConfiguration(%d)", DamageModiConfigurationId -1)

    
    self.spec_DamageModi = {};
    local spec = self.spec_DamageModi;
    spec.debug = false;

    if self.isServer then
        spec.triggerNodes = {};
        spec.vehicleInTrigger = {};
        spec.numVehicleInTrigger = 0;

        spec.repairPerInterval = self.xmlFile:getValue(baseXmlPath .. "#repairPerInterval", 0.1);
        spec.repairInterval = self.xmlFile:getValue(baseXmlPath .. "#repairInterval", 3000);
        spec.repairCostFactor = self.xmlFile:getValue(baseXmlPath .. "#repairCostFactor", 0);
        spec.fillUnitIndex = self.xmlFile:getValue(baseXmlPath .. "#fillUnitIndex")

        if spec.fillUnitIndex ~= nil then
            
            spec.fillType = self:getFillUnitFirstSupportedFillType(spec.fillUnitIndex);
            spec.fillTypePricePerLiter = g_currentMission.economyManager:getPricePerLiter(spec.fillType)
        end

        self.xmlFile:iterate(baseXmlPath .. ".triggerNodes.triggerNode",
            function (index, triggerKey)
                local triggerNode = self.xmlFile:getValue(triggerKey .. "#node", nil, self.components, self.i3dMappings);
                table.insert(spec.triggerNodes, triggerNode);
                addTrigger(triggerNode, "repairTriggerCallback", self);
            end
        )

        if #spec.triggerNodes == 0 then
            Logging.xmlError(self.xmlFile, "No valid trigger node found");
        end
    end
end

function RepairVehicle:onDelete()
    local spec = self.spec_DamageModi;
    if spec ~= nil and spec.triggerNodes ~= nil then
        for _, triggerNode in pairs(spec.triggerNodes) do
            removeTrigger(triggerNode);
        end
    end
end

function RepairVehicle:writeToLog(onlyInDebug, value)
    local spec = self.spec_DamageModi;

    if (onlyInDebug and spec.debug)then
        print("Debug: " .. tostring(value));
    end

    if not onlyInDebug then
        print("Info: " .. tostring(value));
    end
end

function RepairVehicle:repairTriggerCallback(triggerId, otherActorId, onEnter, onLeave, onStay, otherShapeId)
    local spec = self.spec_DamageModi;
    self:writeToLog(true, "repairTriggerCallback called");
    self:writeToLog(true, "triggerId:" .. tostring(triggerId) .. " otherActorId:" .. tostring(otherActorId) .. " otherShapeId:" .. tostring(otherShapeId));
    self:writeToLog(true, "onEnter:" .. tostring(onEnter) .. " onLeave:" .. tostring(onLeave) .. " onStay:" .. tostring(onStay));

    local vehicle = g_currentMission:getNodeObject(otherActorId);
    if vehicle ~= nil and vehicle.getDamageAmount ~= nil then
        local vehicleRootNode = otherActorId;
        self:writeToLog(true, "vehicle found:" .. tostring(vehicleRootNode));
        if onEnter then
            local foundInTable = false;
            if spec.vehicleInTrigger[vehicleRootNode] ~= nil then
                foundInTable = true;
                spec.vehicleInTrigger[vehicleRootNode] = spec.vehicleInTrigger[vehicleRootNode] + 1;
            end

            if not foundInTable then
                spec.vehicleInTrigger[vehicleRootNode] = 1;
                spec.numVehicleInTrigger = spec.numVehicleInTrigger + 1;
                if spec.timerId == nil then
                    self:startRepairVehicles();
                end
            end
            self:writeToLog(true, "vehicle counter:" .. tostring(spec.vehicleInTrigger[vehicleRootNode]));
        end
        if onLeave then
            if spec.vehicleInTrigger[vehicleRootNode] ~= nil then
                spec.vehicleInTrigger[vehicleRootNode] = spec.vehicleInTrigger[vehicleRootNode] - 1;
                if spec.vehicleInTrigger[vehicleRootNode] == 0 then
                    spec.vehicleInTrigger[vehicleRootNode] = nil;
                    spec.numVehicleInTrigger = spec.numVehicleInTrigger - 1;
                    self:writeToLog(true, "vehicle removed");
                else
                    self:writeToLog(true, "vehicle counter:" .. tostring(spec.vehicleInTrigger[vehicleRootNode]));
                end
            end
        end
    else
        self:writeToLog(true, "Not a vehicle");
    end
end
function RepairVehicle.DebugTable(text, myTable, maxDepth)
    if not RepairVehicle.Debug then return end
    if myTable == nil then
        print("RepairVehicleDebug: " .. text .. " is nil");
    else
        print("RepairVehicleDebug: " .. text)
        DebugUtil.printTableRecursively(myTable,"_",0, maxDepth or 2);
    end
end
function RepairVehicle:startRepairVehicles()
    local spec = self.spec_DamageModi;
    self:writeToLog(true, "startRepairVehicles called: " .. tostring(spec.numVehicleInTrigger));

    if spec.numVehicleInTrigger > 0 then

        local actionDone = false;
        for vehicleRootNode, vehicleCount in pairs(spec.vehicleInTrigger) do
            local vehicle = g_currentMission.nodeToObject[vehicleRootNode];

            if vehicle ~= nil and vehicle.getDamageAmount ~= nil then
                self:writeToLog(true, "vehicle: " .. tostring(vehicleRootNode));
                local currentDamage = vehicle:getDamageAmount();
                self:writeToLog(true, "currentDamage: " .. tostring(currentDamage));
                if currentDamage >= 0.0001 then
                    
                    local repairStep = math.min(currentDamage, spec.repairPerInterval);
                    self:writeToLog(true, "repairStep: " .. tostring(repairStep));
                    local repairCosts = Wearable.calculateRepairPrice(self:getPrice(), repairStep) * spec.repairCostFactor;
                    self:writeToLog(true, "repairCosts: " .. tostring(repairCosts));

                    if spec.fillUnitIndex ~= nil then
                        
                        self:writeToLog(true, "repair with filltype");

                        local liter = repairCosts / spec.fillTypePricePerLiter;
                        self:writeToLog(true, "needed liter: " .. tostring(liter));
                        
                        if self:getFillUnitFillLevel(spec.fillUnitIndex) >= liter then
                            self:addFillUnitFillLevel(self:getOwnerFarmId(), spec.fillUnitIndex, -liter, spec.fillType, ToolType.UNDEFINED, nil);
                            vehicle:addDamageAmount(repairStep * -1, true);
                            actionDone = true;
                        end
                    elseif g_currentMission:getMoney(self.ownerFarmId) >= repairCosts then
                        
                        self:writeToLog(true, "welded")
                        g_currentMission:addMoney(-repairCosts, self:getOwnerFarmId(), MoneyType.VEHICLE_REPAIR, true, true);
                        vehicle:addDamageAmount(repairStep * -1, true);
                        actionDone = true;
						

if not spec.notificationShown then
    local notification = g_currentMission:addIngameNotification(FSBaseMission.INGAME_NOTIFICATION_CRITICAL, "Nice weld man, She needs it");
    
  spec.notificationShown = true; 
end


                    end
                end
            end
        end

        if spec.timerId ~= nil then
            self:writeToLog(true, "timer restarted")
            return true;
        else
            
            self:writeToLog(true, "timer added")
            spec.timerId = addTimer(spec.repairInterval, "startRepairVehicles", self);
        end
    else
        
        self:writeToLog(true, "timer removed")
        spec.timerId = nil;
    end
end