local metadata = {
"## Interface: FS15 1.1.0.0 RC12",
"## Title: Cargo",
"## Notes: Specialization für Anhänger um Stückgut einzeln zu entladen",
"## Author: Marhu",
"## Version: 3.5.3-41",
"## Date: 06.07.2015",
"## Web: http://Marhu.net"
}

local FillTypeIsCargo ={}

Cargo = {};
Cargo.ModDir = g_currentModDirectory;

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

function Cargo:load(xmlFile)
	
	if g_currentMission.husbandries then
		for k,t in pairs(g_currentMission.husbandries) do
			local fillType = Fillable.fillTypeNameToInt[k]
			if fillType ~= nil then
				FillTypeIsCargo[fillType] = true;
			end
		end;
	end;
	
	
	local fillTypes = getXMLString(xmlFile, "vehicle.CargoFillTypes#fillTypes")
	if fillTypes ~= nil then
		local types = Utils.splitString(" ", fillTypes)
		for k,v in pairs(types) do
			local fillType = Fillable.fillTypeNameToInt[v]
			if fillType ~= nil then
				FillTypeIsCargo[fillType] = true
			 end
		end
	end
	
	self.updateTipping = Utils.overwrittenFunction(self.updateTipping, Cargo.updateTipping);
	self.getCanTip = Utils.overwrittenFunction(self.getCanTip, Cargo.getCanTip);
	
	self.CargoCapacity = {}
	self.CargoCapacity["default"] = self.capacity;
	local key0 = "vehicle.CargoCapacity.capacity(%d)"
	local num = 0;
	while hasXMLProperty(xmlFile, string.format(key0, num)) do
		local key1 = string.format(key0, num)
		local fillType = Fillable.fillTypeNameToInt[getXMLString(xmlFile, key1.."#fillType")]
		if fillType ~= nil then
			self.CargoCapacity[fillType] = Utils.getNoNil(getXMLFloat(xmlFile, key1.."#value"),0)
		end;
		num = num + 1;
	end
		
	self.CargoUnloadTimes = {}
	self.CargoUnloadTime = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.CargoUnloadTimes#value"), 1000);
	self.CargoUnloadTimes["default"] = self.CargoUnloadTime
	local key0 = "vehicle.CargoUnloadTimes.UnloadTime(%d)"
	local num = 0;
	while hasXMLProperty(xmlFile, string.format(key0, num)) do
		local key1 = string.format(key0, num)
		local fillType = Fillable.fillTypeNameToInt[getXMLString(xmlFile, key1.."#fillType")]
		if fillType ~= nil then
			self.CargoUnloadTimes[fillType] = Utils.getNoNil(getXMLFloat(xmlFile, key1.."#value"),0)
		end
		num = num + 1;
	end
		
	self.fillSounds = {};
	local fillSounds = getXMLString(xmlFile, "vehicle.fillSound#file")
    if fillSounds ~= nil and fillSounds ~= "" then
		self.fillSoundFile = fillSounds
		self.fillSounds["default"]={}
		self.fillSounds["default"].file = fillSounds
		self.fillSounds["default"].PitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillSounds#pitchOffset"), 1.0);
		self.fillSounds["default"].Volume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillSounds#volume"), 1.0);
		local key0 = "vehicle.fillSound.Sound(%d)"
		local num = 0;
		while hasXMLProperty(xmlFile, string.format(key0, num)) do
			local key1 = string.format(key0, num)
			local fillType = Fillable.fillTypeNameToInt[getXMLString(xmlFile, key1.."#fillType")]
			if fillType ~= nil then
				self.fillSounds[fillType] = {}
				self.fillSounds[fillType].file = getXMLString(xmlFile, key1.."#file")
				if self.fillSounds[fillType].file ~= nil and self.fillSounds[fillType].file ~= "" then
					self.fillSounds[fillType].PitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, key1.."#pitchOffset"), 1.0);
					self.fillSounds[fillType].Volume = Utils.getNoNil(getXMLFloat(xmlFile, key1.."#volume"), 1.0);
				else
					self.fillSounds[fillType] = nil
				end;
			end
			num = num + 1
		end
	end	
	
	for k,v in pairs(self.fillTypes) do
		if FillTypeIsCargo[k] then
			if not self.CargoCapacity[k] then
				self.CargoCapacity[k] = self.CargoCapacity["default"]
			end
			if not self.CargoUnloadTimes[k] then
				self.CargoUnloadTimes[k] = self.CargoUnloadTimes["default"]
			end
			if self.fillSounds["default"] and not self.fillSounds[k] then
				self.fillSounds[k] = self.fillSounds["default"]
			end
		end;
	end;
	
	self.babyHud = Overlay:new("hudFillTypeBaby", Cargo.ModDir.."BabyHud.dds",g_currentMission.fruitSymbolX ,g_currentMission.fruitSymbolY, g_currentMission.fruitSymbolSizeX/4, g_currentMission.fruitSymbolSizeY/4)
	
	self.isSoundReinitDone = false;
	self.LoadChildSupport = true;
	
end;

function Cargo:delete()
end;

function Cargo:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'LoadChild="'.. tostring(self.LoadChild and true or false)..'"';
    local nodes = "";
	return attributes,nodes;
end

function Cargo:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	local LoadChild = getXMLBool(xmlFile, key .. "#LoadChild")
	self.LoadChild = LoadChild and true or nil;
	return BaseMission.VEHICLE_LOAD_OK;
end

function Cargo:readStream(streamId, connection)
    if connection:getIsServer() then
		self.LoadChild = streamReadBool(streamId);
    end;
end;

function Cargo:writeStream(streamId, connection)
    if not connection:getIsServer() then
		streamWriteBool(streamId,self.LoadChild);
    end;
end;

function Cargo:readUpdateStream(streamId, timestamp, connection)
	if connection:getIsServer() then
		self.LoadChild = streamReadBool(streamId);
		self.showChildNotAcceptMsg = streamReadBool(streamId);
	end
end;

function Cargo:writeUpdateStream(streamId, connection, dirtyMask)
	if not connection:getIsServer() then
		streamWriteBool(streamId,self.LoadChild);
		streamWriteBool(streamId,self.showChildNotAcceptMsg);
		self.showChildNotAcceptMsg = nil;
	end
end;

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

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

function Cargo:update(dt)
	if self:getIsActive() then
		local reinitSound = false;
		if self.fillLevel > 0 then
			if self.isSoundReinitDone == false then
				self.capacity = self.CargoCapacity[self.currentFillType] or self.CargoCapacity["default"];
				self.CargoUnloadTime = self.CargoUnloadTimes[self.currentFillType] or self.CargoUnloadTimes["default"];
				self:setFillLevel(self:getFillLevel(self.currentFillType), self.currentFillType, false);
				reinitSound = true;
			end;
		else
			self.isSoundReinitDone = false;
		end;
		if reinitSound then
			if self.fillSoundFile then
				local soundFile = self.fillSounds[self.currentFillType] or self.fillSounds["default"]
				if self.fillSoundFile ~= soundFile then
					self.fillSoundFile = soundFile
					if self.fillSound ~= nil then
						delete(self.fillSound);
					end;
					local fillSound  = Utils.getFilename(self.fillSounds[self.currentFillType].file, self.baseDirectory);
					self.sampleFillSound.sample = createSample("fillSound");
					loadSample(self.sampleFillSound.sample, fillSound, false);
					self.sampleFillSound.pitchOffset = self.fillSounds[self.currentFillType].PitchOffset;
					setSamplePitch(self.sampleFillSound.sample, self.sampleFillSound.pitchOffset);
					self.sampleFillSound.duration = getSampleDuration(self.sampleFillSound.sample);
					self.sampleFillSound.volume = self.fillSounds[self.currentFillType].Volume;
					self.sampleFillSound.isPlaying = false;
				end;
			end;
			self.isSoundReinitDone = true;
		end;
	end;
end;

function Cargo:updateTipping(superFunc, dt)
	if not self.isServer then
		return;
	end;
	if self:getCanTip() then
		local fillType = self.currentFillType;
		if FillTypeIsCargo[fillType] == nil then
			return superFunc(self,dt)
		end;
		local fillDelta = -self.fillLevel;
		if self.currentTipReferencePointIndex ~= nil then
			local animation = self.tipAnimations[self.currentTipReferencePointIndex];
			if animation ~= nil and animation.dischargeEndTime > animation.dischargeStartTime then
				if self:getCurrentTipAnimationTime() >= animation.dischargeStartTime then
					local m = self.capacity/((animation.dischargeEndTime-animation.dischargeStartTime)/animation.animationOpenSpeedScale);
					fillDelta = -m * dt;
				else
					fillDelta = 0;
				end
			end
		end
	   
		if fillDelta < 0 then
			fillDelta = -1
			self.LoadTime = (self.LoadTime or 0) + dt
			if self.LoadTime >= self.CargoUnloadTimes[fillType] then
				self.LoadTime = 0
				local curFill = self.fillLevel;
				self:setFillLevel(self.fillLevel + fillDelta, fillType);
				local fillDelta = self.fillLevel - curFill;
				self.lastFillDelta = fillDelta;
		   
				if self.currentTipTrigger ~= nil then
					if self.currentTipTrigger.updateTrailerTipping ~= nil then
						self.currentTipTrigger:updateTrailerTipping(self, fillDelta, fillType);
					end
				elseif self:getCanTipToGround() then
					if fillDelta < 0 then
						local x, _,z = getWorldTranslation(self.groundDropArea.start);
						local x1,_,z1 = getWorldTranslation(self.groundDropArea.width);
						local x2,_,z2 = getWorldTranslation(self.groundDropArea.height);
		   
						local area = {x,z,x1,z1,x2,z2, -fillDelta*self.fillLevelToTippedFillLevel};
						local area, bitType, valueAccumulation = TrailerTipAreaEvent.runLocally(area, fillType, self.groundAmountAccumulation)
						if area ~= nil then
							g_server:broadcastEvent(TrailerTipAreaEvent:new(area, bitType, fillType));
						end;
						if valueAccumulation ~= nil then
							self.groundAmountAccumulation = valueAccumulation;
						end;
					end;
				end;
			end;
		end;
	else
		self:onEndTip();
	end;
end

function Cargo:getCanTip(superFunc)
	if self.LoadChild and self.currentTipTrigger ~= nil and not self.currentTipTrigger.LoadChildSupport then
		self.showChildNotAcceptMsg = true;
		return false
	end;
	return superFunc(self)
end

function Cargo:draw()
	if self.LoadChild and self.fillLevel > 0 and g_currentMission.showVehicleSchema then
		self.babyHud:render()
	end
	if self.showChildNotAcceptMsg then
		self.showChildNotAcceptMsg = false;
		local text = g_i18n:getText("Child").." " .. g_i18n:getText("notAcceptedHere")
		g_currentMission:showBlinkingWarning(text)
	end
end;
