--
-- New StrawMod script for small bales
-- version 2.2
-- @author: Burner
--

StrawMod = {};

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

function StrawMod:load(xmlFile)
	self.setIsCollectingBales = SpecializationUtil.callSpecializationsFunction("setIsCollectingBales");
	self.onStartTip = Utils.prependedFunction(self.onStartTip, StrawMod.onStartTip);
	self.onEndTip = Utils.prependedFunction(self.onEndTip, StrawMod.onEndTip);
	self.objectInRange = StrawMod.objectInRange;
	
    self.wasToFast = false;
    self.isCollectingBales = false;
	
    local strawBalesIndex = getXMLString(xmlFile, "vehicle.strawBales#index");
    self.strawBalesCount = getXMLInt(xmlFile, "vehicle.strawBales#count");
    self.strawBalesRootNode = Utils.indexToObject(self.components, strawBalesIndex);
	
    local hayBalesIndex = getXMLString(xmlFile, "vehicle.hayBales#index");
    self.hayBalesCount = getXMLInt(xmlFile, "vehicle.hayBales#count");
    self.hayBalesRootNode = Utils.indexToObject(self.components, hayBalesIndex);

	self.baleSearchNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.baleSearchNode#index"));
	self.freezeTipAnimation = false;
	self.tipAnimationsBackup = {};
	for k,v in pairs(self.tipAnimations) do
		self.tipAnimationsBackup[k] = {};
		self.tipAnimationsBackup[k].dischargeStartTime = self.tipAnimations[k].dischargeStartTime;
	end;
end;

function StrawMod:delete()
end;

function StrawMod:readStream(streamId, connection)
    self:setIsCollectingBales(streamReadBool(streamId), true);
end;

function StrawMod:writeStream(streamId, connection)
	streamWriteBool(streamId, self.isCollectingBales);
end;

function StrawMod:readUpdateStream(streamId, timestamp, connection)
end;

function StrawMod:writeUpdateStream(streamId, connection, dirtyMask)
end;

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

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

function StrawMod:update(dt)
    if self:getIsActiveForInput() then
        if InputBinding.hasEvent(InputBinding.STRAWMODV2_CollectBales) and (self.currentFillType == Fillable.FILLTYPE_UNKNOWN or self.currentFillType == Fillable.FILLTYPE_WHEAT_WINDROW or self.currentFillType == Fillable.FILLTYPE_DRYGRASS_WINDROW) then
            self:setIsCollectingBales(not self.isCollectingBales);
        end;
    end;
end;

function StrawMod:updateTick(dt)
	self.baleFillValue = self.capacity/self.strawBalesCount;
    self.wasToFast = false;
    --if self:getIsActive() then
        if self.isCollectingBales and self.capacity > self.fillLevel then
            local toFast = self:doCheckSpeedLimit() and self.attacherVehicle.lastSpeed*3600 > 29;
            if self.isServer then
                if not toFast then
					if self:allowFillType(Fillable.FILLTYPE_WHEAT_WINDROW, false) or self:allowFillType(Fillable.FILLTYPE_DRYGRASS_WINDROW, false) then
						local bale = self:objectInRange(self.baleSearchNode);
						if bale ~= nil then
							baleId = networkGetObjectId(bale);
							bale = networkGetObject(baleId);
							if getUserAttribute(bale.nodeId, "isStrawbale") then
								if self.currentFillType == Fillable.FILLTYPE_UNKNOWN or self.currentFillType == Fillable.FILLTYPE_WHEAT_WINDROW then
									fillType = Fillable.FILLTYPE_WHEAT_WINDROW;
								elseif self.currentFillType == Fillable.FILLTYPE_DRYGRASS_WINDROW then
									fillType = Fillable.FILLTYPE_DRYGRASS_WINDROW;
								end;
								bale:delete();
								self:setFillLevel(self.fillLevel+self.baleFillValue, fillType)
							elseif getUserAttribute(bale.nodeId, "isHaybale") then
								if self.currentFillType == Fillable.FILLTYPE_UNKNOWN or self.currentFillType == Fillable.FILLTYPE_DRYGRASS_WINDROW then
									fillType = Fillable.FILLTYPE_DRYGRASS_WINDROW;
								elseif self.currentFillType == Fillable.FILLTYPE_WHEAT_WINDROW then
									fillType = Fillable.FILLTYPE_WHEAT_WINDROW;
								end;
								bale:delete();
								self:setFillLevel(self.fillLevel+self.baleFillValue, fillType)
							end;
						end;
					end;
                end;
            end;
            self.wasToFast = toFast;
        end;
    --end;
	
	setVisibility(self.hayBalesRootNode, true); 
	setVisibility(self.strawBalesRootNode, true); 
	
	for i=1, self.strawBalesCount do
		local strawBale = getChildAt(self.strawBalesRootNode, i-1);
		setVisibility(strawBale, false);
	end;
	
	for i=1, self.hayBalesCount do
		local hayBale = getChildAt(self.hayBalesRootNode, i-1);
		setVisibility(hayBale, false);
	end;
	
	percentDecimal = self.fillLevel/self.capacity;
	
	if self.currentFillType == Fillable.FILLTYPE_WHEAT_WINDROW then
		self.strawBalesToShow = math.ceil(self.strawBalesCount*percentDecimal);
		for i=1, self.strawBalesToShow do
			local strawBale = getChildAt(self.strawBalesRootNode, i-1);
			setVisibility(strawBale, true);
		end;
	end;
	if self.currentFillType == Fillable.FILLTYPE_DRYGRASS_WINDROW then
		self.hayBalesToShow = math.ceil(self.hayBalesCount*percentDecimal);
		for i=1, self.hayBalesToShow do
			local hayBale = getChildAt(self.hayBalesRootNode, i-1);
			setVisibility(hayBale, true);
		end;
	end;
	
	if self.fillLevel >= self.capacity then
		self.isCollectingBales = false;
	end;
end;

function StrawMod:draw()
    if self.wasToFast then
        g_currentMission:addWarning(g_i18n:getText("Dont_drive_to_fast") .. "\n" .. string.format(g_i18n:getText("Cruise_control_levelN"), "2", InputBinding.getKeyNamesOfDigitalAction(InputBinding.SPEED_LEVEL2)), 0.07+0.022, 0.019+0.029);
    end;
	if self.currentFillType == Fillable.FILLTYPE_UNKNOWN or self.currentFillType == Fillable.FILLTYPE_WHEAT_WINDROW or self.currentFillType == Fillable.FILLTYPE_DRYGRASS_WINDROW then
		if self.isCollectingBales then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_off_OBJECT"), g_i18n:getText("STRAWMODV2_collectBales")), InputBinding.STRAWMODV2_CollectBales);
		else
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("turn_on_OBJECT"), g_i18n:getText("STRAWMODV2_collectBales")), InputBinding.STRAWMODV2_CollectBales);
		end;
	end;
end;

function StrawMod:onDetach()
    if self.deactivateOnDetach then
        StrawMod.onDeactivate(self);
    end;
	self.isCollectingBales = false;
end;

function StrawMod:onLeave()
    if self.deactivateOnLeave then
        StrawMod.onDeactivate(self);
    end;
end;

function StrawMod:onDeactivate()
	--self.isCollectingBales = false;
end;

function StrawMod:setIsCollectingBales(collectingBales, noEventSend)
    SetCollectingBales.sendEvent(self, collectingBales, noEventSend)
    self.isCollectingBales = collectingBales;
end;

function StrawMod:objectInRange(refNode)
    local nearestDistance = 8;
    local nearestBale = nil;
    local px, py, pz = getWorldTranslation(refNode);
	for index, item in pairs(g_currentMission.itemsToSave) do
	    itemNode = item.item.nodeId;
	    if getParent(item.item.nodeId) == getRootNode() then
			if getUserAttribute(itemNode, "isStrawbale") or getUserAttribute(itemNode, "isHaybale") then
				local vx, vy, vz = getWorldTranslation(itemNode);
				local distance = Utils.vector3Length(px-vx, py-vy, pz-vz);
				if distance < nearestDistance then
					index = index;
					nearestBale = item.item;
					nearestObject = itemNode;
					nearestDistance = distance;
				end;
			end;
		end;
	end;	
    return nearestBale;
end;

function StrawMod:onStartTip(currentTipTrigger, noEventSend)
	if self.currentFillType == Fillable.FILLTYPE_WHEAT_WINDROW or self.currentFillType == Fillable.FILLTYPE_DRYGRASS_WINDROW then
		self.freezeTipAnimation = true;
		for k,v in pairs(self.tipAnimations) do
			for x,z in pairs(self.tipAnimations[k]) do
				self.tipAnimations[k].dischargeStartTime = 0;
				if self.tipAnimations[k].animationName ~= nil then
					self:stopAnimation(self.tipAnimations[k].animationName);
				elseif self.tipAnimations[k].animationCharSet ~= nil then
					disableAnimTrack(self.tipAnimations[k].animationCharSet, 0);
					setAnimTrackTime(self.tipAnimations[k].animationCharSet, 0, 0, true);
				end;
			end;
		end;
	end;
end;
 
function StrawMod:onEndTip(noEventSend)
	if self.freezeTipAnimation then
		disableAnimTrack(self.tipAnimCharSet, 0);
		setAnimTrackTime(self.tipAnimCharSet, 0, 0, true);
		for k,v in pairs(self.tipAnimations) do
			self.tipAnimations[k].dischargeStartTime = self.tipAnimationsBackup[k].dischargeStartTime;
		end;
		self.freezeTipAnimation = false;
	end;
end;