AutomaticCarWash = {}

function AutomaticCarWash.prerequisitesPresent(specializations)
    return true
end

function AutomaticCarWash.initSpecialization()
    local schema = Placeable.xmlSchema
    schema:setXMLSpecializationType("AutomaticCarWash")
    
    local baseXmlPath = "placeable.automaticCarWash"
    
    schema:register(XMLValueType.NODE_INDEX, baseXmlPath .. "#triggerNode", "Trigger node for start automatic")

    schema:setXMLSpecializationType()
end

function AutomaticCarWash.registerFunctions(placeableType)
	SpecializationUtil.registerFunction(placeableType, "onTriggerCallback", AutomaticCarWash.onTriggerCallback)
	SpecializationUtil.registerFunction(placeableType, "CleanCar", AutomaticCarWash.CleanCar)
	SpecializationUtil.registerFunction(placeableType, "getDirtPercForObject", AutomaticCarWash.getDirtPercForObject)
	SpecializationUtil.registerFunction(placeableType, "calcPercentage", AutomaticCarWash.calcPercentage)
end

function AutomaticCarWash.registerEventListeners(placeableType)
    SpecializationUtil.registerEventListener(placeableType, "onLoad", AutomaticCarWash)
    SpecializationUtil.registerEventListener(placeableType, "onFinalizePlacement", AutomaticCarWash)
	SpecializationUtil.registerEventListener(placeableType, "onDelete", AutomaticCarWash)
end

function AutomaticCarWash:onLoad(savegame)

    local baseXmlPath = "placeable.automaticCarWash"
            
    -- hier für server und client
    self.spec_automaticCarWash = {}
    local spec = self.spec_automaticCarWash
    spec.available = false;
    spec.vehicleInTrigger = {};
    spec.washPerSecond = 5; -- should be percentage of washing
    spec.activated = false;
    
    spec.triggerNode = self.xmlFile:getValue(baseXmlPath.."#triggerNode", nil, self.components, self.i3dMappings);
    if spec.triggerNode ~= nil then
        addTrigger(spec.triggerNode, "onTriggerCallback", self);
    else
        print("Triggernode missing");
    end
    
    spec.initialized = true;
end

function AutomaticCarWash:onFinalizePlacement()
    local spec = self.spec_automaticCarWash
    -- if spec.triggerNode ~= nil then
        -- addTrigger(spec.triggerNode, "onTriggerCallback", self);
    -- else
        -- print("triggerNode missing");
    -- end
end

function AutomaticCarWash:onDelete()
    local spec = self.spec_automaticCarWash
	if spec.triggerNode ~= nil then
		removeTrigger(spec.triggerNode)
	end
end

function AutomaticCarWash:onTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay)
    local spec = self.spec_automaticCarWash
	local vehicle = g_currentMission:getNodeObject(otherId);
	if vehicle ~= nil then
		if onEnter then
            local foundInTable = false;
			for i=0, table.getn(spec.vehicleInTrigger) do
				if spec.vehicleInTrigger[i] ~= nil and spec.vehicleInTrigger[i] == otherId then
					foundInTable = true;
				end
			end
            if not foundInTable then
                table.insert(spec.vehicleInTrigger,otherId);
            end
		end
		if onLeave then
			for i=0, table.getn(spec.vehicleInTrigger) do
				if spec.vehicleInTrigger[i] ~= nil and spec.vehicleInTrigger[i] == otherId then
					table.remove(spec.vehicleInTrigger, i);
				end
			end
		end
	end
    self:CleanCar();    
end

function AutomaticCarWash:CleanCar()
    local spec = self.spec_automaticCarWash
	if table.getn(spec.vehicleInTrigger) > 0 then

		local overallDirt = 0;
	
		for _,vehicle in pairs(spec.vehicleInTrigger) do
			local vehicle = g_currentMission.nodeToObject[vehicle];
			spec.foundVehicle = vehicle
			spec.farmId = spec.foundVehicle:getOwnerFarmId()
			if AutomaticCarWash:getDirtPercForObject(vehicle) > 0 then
                local washPercentage = ((spec.washPerSecond*1000) / spec.foundVehicle:getWashDuration())
				spec.foundVehicle:addDirtAmount(-washPercentage)
				overallDirt = overallDirt + AutomaticCarWash:getDirtPercForObject(vehicle)
			end
		end;

		if overallDirt <= 0 then
			--g_currentMission:showBlinkingWarning("Alles sauber" , 1300)
			-- clean, remove timer
            spec.timerId = nil;
        else
            -- not clean, use timer
            if spec.timerId ~= nil then
                return true;
            else
                spec.timerId = addTimer(1000, "CleanCar", self);
            end        
		end
	else
        -- no vehicle, remove timer
        spec.timerId = nil;
    end
end

function AutomaticCarWash:getDirtPercForObject(obj)
	if obj ~= nil then
		if obj.spec_washable ~= nil then
			local nodeCount = 0;
			local dirtAmount = 0;
			for _, node in pairs(obj.spec_washable.washableNodes) do
				dirtAmount = dirtAmount + node.dirtAmount;
				nodeCount = nodeCount + 1;
			end
			return AutomaticCarWash:calcPercentage(dirtAmount / nodeCount, 1);
		else
			return nil;
		end
	else
		return nil;
	end
end

function AutomaticCarWash:calcPercentage(curVal, maxVal)
	local per = curVal / maxVal * 100;
	return (math.floor(per * 10)/10);
end