--
-- FruitCollect specialization
-- author: Burner
--

FruitCollect = {};

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

function FruitCollect:load(xmlFile)
	self.setCollectFruits = SpecializationUtil.callSpecializationsFunction("setCollectFruits");	
	self.collectFruits = false;
	
	self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1);
	
	self.collectTypes = {};
	self.collectTypes[Fillable.FILLTYPE_UNKNOWN] = true;
	local collectTypes = getXMLString(xmlFile, "vehicle.collectTypes#fruitTypes");
	if collectTypes ~= nil then
		local types = Utils.splitString(" ", collectTypes);
		for k,v in pairs(types) do
			local collectType = Fillable.fillTypeNameToInt[v];
			if collectType ~= nil then
				self.collectTypes[collectType] = true;
			end;
		end;
	end;
	
	local numCuttingExtraAreas = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.cuttingExtraAreas#count"), 0);
	self.cuttingExtraAreas = {}
	for i=1, numCuttingExtraAreas do
		self.cuttingExtraAreas[i] = {};
		local areanamei = string.format("vehicle.cuttingExtraAreas.cuttingExtraArea%d", i);
		self.cuttingExtraAreas[i].start = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#startIndex"));
		self.cuttingExtraAreas[i].width = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#widthIndex"));
		self.cuttingExtraAreas[i].height = Utils.indexToObject(self.components, getXMLString(xmlFile, areanamei .. "#heightIndex"));
	end;
end;

function FruitCollect:readStream(streamId, connection)
    self:setCollectFruits(streamReadBool(streamId), true);
end;

function FruitCollect:writeStream(streamId, connection)
    streamWriteBool(streamId, self.collectFruits);
end;

function FruitCollect:delete()
end;

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

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

function FruitCollect:update(dt)
	if self:getIsActiveForInput() then
        if InputBinding.hasEvent(InputBinding.D50_COLLECTFRUITS) then
			self:setCollectFruits(not self.collectFruits);
        end;
	end;
	if self.collectFruits and self.fillLevel < self.capacity then
		local area = 0;
		for k, cuttingExtraArea in pairs(self.cuttingExtraAreas) do
			local x,y,z = getWorldTranslation(cuttingExtraArea.start);
			local x1,y1,z1 = getWorldTranslation(cuttingExtraArea.width);
			local x2,y2,z2 = getWorldTranslation(cuttingExtraArea.height);
               for collectType,v in pairs(self.collectTypes) do
                   if collectType ~= Fillable.FILLTYPE_UNKNOWN then
					if self.currentFillType == collectType or self.currentFillType == Fillable.FILLTYPE_UNKNOWN then
						local fruitType = FruitUtil.fillTypeToFruitType[collectType];
						local area = Utils.updateFruitCutLongArea(fruitType, x, z, x1, z1, x2, z2, 0);
						area = area + Utils.updateFruitWindrowArea(fruitType, x, z, x1, z1, x2, z2, 0);
						if area > 0 then
							self.currentFruitType = fruitType;
							if self.currentFruitType == FruitUtil.FRUITTYPE_GRASS or self.currentFruitType == FruitUtil.FRUITTYPE_DRYGRASS then
								literPerSqm = g_strawLitersPerSqm*2;
							else
								literPerSqm = FruitUtil.fruitIndexToDesc[self.currentFruitType].literPerSqm; --* (1 + 0.50 * (3 - g_currentMission.missionStats.difficulty));
							end;
							local pixelToSqm = g_currentMission:getFruitPixelsToSqm();
							local sqm = area*pixelToSqm;
							local deltaLevel = sqm*literPerSqm*self.fillScale;
							self:setFillLevel(self.fillLevel+deltaLevel, collectType);
						end;
					end;
				end;
			end;
		end;
		if self.fillLevel == 0 then
			self.currentFruitType = FruitUtil.FRUITTYPE_UNKNOWN;
		end;
	else
		self.collectFruits = false;
	end;
end;

function FruitCollect:draw()
    if self.collectFruits then
        g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_off_OBJECT"), g_i18n:getText("D50_collectFruits")), InputBinding.D50_COLLECTFRUITS);
    else
        g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_on_OBJECT"), g_i18n:getText("D50_collectFruits")), InputBinding.D50_COLLECTFRUITS);
    end;
end;

function FruitCollect:setCollectFruits(collectFruits, noEventSend)
	SetCollectFruitsEvent.sendEvent(self, collectFruits, noEventSend)
    self.collectFruits = collectFruits;
end;

-- events
SetCollectFruitsEvent = {};
SetCollectFruitsEvent_mt = Class(SetCollectFruitsEvent, Event);

InitEventClass(SetCollectFruitsEvent, "SetCollectFruitsEvent");

function SetCollectFruitsEvent:emptyNew()
    local self = Event:new(SetCollectFruitsEvent_mt);
    self.className="SetCollectFruitsEvent";
    return self;
end;

function SetCollectFruitsEvent:new(vehicle, collectFruitsState)
    local self = SetCollectFruitsEvent:emptyNew()
    self.vehicle = vehicle;
	self.collectFruitsState = collectFruitsState;
    return self;
end;

function SetCollectFruitsEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.collectFruitsState = streamReadBool(streamId);
    self.vehicle = networkGetObject(id);
    self:run(connection);
end;

function SetCollectFruitsEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.collectFruitsState);
end;

function SetCollectFruitsEvent:run(connection)   
	self.vehicle:setCollectFruits(self.collectFruitsState, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(SetCollectFruitsEvent:new(self.vehicle, self.collectFruitsState), nil, connection, self.vehicle);
    end;
end;

function SetCollectFruitsEvent.sendEvent(vehicle, collectFruitsState, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetCollectFruitsEvent:new(vehicle, collectFruitsState), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetCollectFruitsEvent:new(vehicle, collectFruitsState));
		end;
	end;
end;