
-- by "Marhu" 
-- v 1.0
-- Date: 30.03.2013
-- Zum Transport und Verkauf von Milch

source(g_currentModDirectory.."MilchTrailerSetIsFillingEvent.lua");
source(g_currentModDirectory.."MilchTriggerCallbackEvent.lua");

g_MilchTransportDir = g_currentModDirectory;

MilchTransport = {};
			
if MilktruckFillTrigger.triggerCallback ~= nil then
	local orgtriggerCallback = MilktruckFillTrigger.triggerCallback;
	MilktruckFillTrigger.triggerCallback = function(a, triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
		orgtriggerCallback(a, triggerId, otherId, onEnter, onLeave, onStay, otherShapeId);
		local MilkTrailer = g_currentMission.objectToTrailer[otherShapeId];
		if MilkTrailer ~= nil and MilkTrailer.addMilchTrailerFillTrigger ~= nil and MilkTrailer.removeMilchTrailerFillTrigger ~= nil then
			if onEnter then
				MilkTrailer:addMilchTrailerFillTrigger({id = triggerId, fillMilk = true}, g_server ~= nil);
			else -- onLeave
				MilkTrailer:removeMilchTrailerFillTrigger({id = triggerId, fillMilk = true}, g_server ~= nil);
			end;
		end;
	end;
end;
if MilktruckStartTrigger.triggerCallback ~= nil then
	local orgtriggerCallback = MilktruckStartTrigger.triggerCallback;
	MilktruckStartTrigger.triggerCallback = function(a, triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
		orgtriggerCallback(a, triggerId, otherId, onEnter, onLeave, onStay, otherShapeId);
		local MilkTrailer = g_currentMission.objectToTrailer[otherShapeId];
		if MilkTrailer ~= nil and MilkTrailer.addMilchTrailerFillTrigger ~= nil and MilkTrailer.removeMilchTrailerFillTrigger ~= nil then
			if onEnter then
				MilkTrailer:addMilchTrailerFillTrigger({id = triggerId, buyMilk = true}, g_server ~= nil);
			 else -- onLeave
				MilkTrailer:removeMilchTrailerFillTrigger({id = triggerId, buyMilk = true}, g_server ~= nil);
			 end;
		end;
	end;
end;
			
function MilchTransport.prerequisitesPresent(specializations)
    return true
end;

function MilchTransport:load(xmlFile)
	
	self.TriggerCallback = MilchTransport.TriggerCallback;
	
	self.setIsMilchTrailerFilling = SpecializationUtil.callSpecializationsFunction("setIsMilchTrailerFilling");
	self.setIsMilchTrailerBuyMilk = SpecializationUtil.callSpecializationsFunction("setIsMilchTrailerBuyMilk");
    self.setIsZuchtFilling = SpecializationUtil.callSpecializationsFunction("setIsZuchtFilling");
	self.removeMilchTrailerFillTrigger = SpecializationUtil.callSpecializationsFunction("removeMilchTrailerFillTrigger");
    self.addMilchTrailerFillTrigger = SpecializationUtil.callSpecializationsFunction("addMilchTrailerFillTrigger");

    self.isMilchTrailerFilling = false;
	self.isMilchTrailerBuyMilk = false;
    self.isZuchtFilling = false;
	
	self.milchTrailerActivatableAdded = false;
    self.milchTrailerActivatable = MilchTrailerActivatable:new(self);
  
    self.MilchTrailerFillTriggers = {};
 
    self.fillLitersPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillLitersPerSecond"), 500);
  
    local TrailerFillTriggerNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.milkTrailerFillTrigger#index"));
	if TrailerFillTriggerNode ~= nil then
		self.TrailerFillTrigger = TrailerFillTriggerNode;
		addTrigger(self.TrailerFillTrigger, "TriggerCallback", self);
    end;
	
	if not g_currentMission.fillTypeOverlays[Fillable.FILLTYPE_MILK] then
		local ow = g_currentMission.fillTypeOverlays[1];
		g_currentMission.fillTypeOverlays[Fillable.FILLTYPE_MILK] = Overlay:new("milk", g_MilchTransportDir.."milk.dds", ow.x, ow.y, ow.width, ow.height);
	end
	
	if not g_currentMission.husbandries.cow.fillLevelMilk and
		   g_currentMission.husbandries.cow.fillLevels and
		   g_currentMission.husbandries.cow.fillLevels[Fillable.FILLTYPE_MILK] then
		self.NoPatch = true
	end
end;

function MilchTransport:delete()
	if self.TrailerFillTrigger then
		removeTrigger(self.TrailerFillTrigger)
		self.TrailerFillTrigger = nil
	end
	if self.milchTrailerActivatableAdded then
		g_currentMission:removeActivatableObject(self.milchTrailerActivatable);
		self.milchTrailerActivatableAdded = false;
	end;
end;

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

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

function MilchTransport:update(dt)
end;

function MilchTransport:updateTick(dt)
	
	if self:getIsActive() or self.isMilchTrailerFilling or self.isMilchTrailerBuyMilk or self.isZuchtFilling then
        
		self.isNearMilktruckFillTrigger = nil
		self.isNearBuyMilkTrigger = nil
		self.isNearZuchtTrigger = nil
        for i=1, table.getn(self.MilchTrailerFillTriggers) do
			local trigger = self.MilchTrailerFillTriggers[i];
			if trigger.fillMilk then
				self.isNearMilktruckFillTrigger = true;
			elseif trigger.buyMilk then 
				self.isNearBuyMilkTrigger = true;
			elseif trigger.Zucht then 
				self.isNearZuchtTrigger = trigger.Zucht;
			end
			break;
		end

          if self.isNearMilktruckFillTrigger or self.isNearBuyMilkTrigger or self.isNearZuchtTrigger then
              if not self.milchTrailerActivatableAdded then
                  g_currentMission:addActivatableObject(self.milchTrailerActivatable);
                  self.milchTrailerActivatableAdded = true;
              end;
          else
              if self.milchTrailerActivatableAdded then
                  g_currentMission:removeActivatableObject(self.milchTrailerActivatable);
                  self.milchTrailerActivatableAdded = false;
              end;
          end;
		  
		if self.isServer then
            if self.isMilchTrailerFilling then
                if not self.isNearMilktruckFillTrigger then
                    self:setIsMilchTrailerFilling(false);
                end
            end
			if self.isMilchTrailerBuyMilk then
                if not self.isNearBuyMilkTrigger then
                    self:setIsMilchTrailerBuyMilk(false);
                end
            end
			if self.isZuchtFilling then
                if not self.isNearZuchtTrigger then
                    self:setIsZuchtFilling(false);
                end
            end
 
            if self.isMilchTrailerFilling then
                local delta = self.fillLitersPerSecond*dt*0.001;
 
                if self:allowFillType(Fillable.FILLTYPE_MILK, false) then
					local milk = 0
					if self.NoPatch then
						milk = g_currentMission.husbandries.cow.fillLevels[Fillable.FILLTYPE_MILK]
					else
						milk = g_currentMission.husbandries.cow.fillLevelMilk or 0
					end
					delta = math.min(milk,delta)
					local oldFillLevel = self:getFillLevel(Fillable.FILLTYPE_MILK);
					self:setFillLevel(oldFillLevel + delta, Fillable.FILLTYPE_MILK, true);
					delta = self:getFillLevel(Fillable.FILLTYPE_MILK) - oldFillLevel;
					if self.NoPatch then
						g_currentMission.husbandries.cow.fillLevels[Fillable.FILLTYPE_MILK] =  milk - delta
					else
						g_currentMission.husbandries.cow.fillLevelMilk = milk - delta
					end
				else
					delta = 0;
				end
                
                 if delta <= 0 then
                     self:setIsMilchTrailerFilling(false);
                 end;
			elseif self.isMilchTrailerBuyMilk then
				local delta = self.fillLitersPerSecond*dt*0.001;
				 
				local oldFillLevel = self:getFillLevel(Fillable.FILLTYPE_MILK);
				delta = math.min(oldFillLevel,delta)
				self:setFillLevel(oldFillLevel - delta, Fillable.FILLTYPE_MILK, true);
				delta = self:getFillLevel(Fillable.FILLTYPE_MILK) - oldFillLevel;
				local difficultyMultiplier = math.max(2 * (3 - g_currentMission.missionStats.difficulty), 1); -- 1  2  4
				local price = Fillable.fillTypeIndexToDesc[Fillable.FILLTYPE_MILK].pricePerLiter * difficultyMultiplier * delta;
				g_currentMission:addSharedMoney(-price);
				if delta >= 0 then
                     self:setIsMilchTrailerBuyMilk(false);
                end; 
			elseif self.isZuchtFilling then
				local delta = self.fillLitersPerSecond*dt*0.001;
				 
				delta = math.min(self:getFillLevel(Fillable.FILLTYPE_MILK),delta)
				
				local oldFillLevel = self.isNearZuchtTrigger:getFillLevel(Fillable.FILLTYPE_MILK);
				self.isNearZuchtTrigger:setFillLevel(oldFillLevel + delta, Fillable.FILLTYPE_MILK);
				delta = self.isNearZuchtTrigger:getFillLevel(Fillable.FILLTYPE_MILK) - oldFillLevel;
								
				self:setFillLevel(self:getFillLevel(Fillable.FILLTYPE_MILK) - delta, Fillable.FILLTYPE_MILK, true);
				
				if delta <= 0 then
                    self:setIsZuchtFilling(false);
                end; 
            end;
         end;
	end
end

function MilchTransport:readStream(streamId, connection)
    if connection:getIsServer() then
    end;
end;

function MilchTransport:writeStream(streamId, connection)
    if not connection:getIsServer() then
    end;
end;

function MilchTransport:readUpdateStream(streamId, timestamp, connection)
	if connection:getIsServer() then
		if self.isMilchTrailerFilling then
			fillLevel = streamReadFloat32(streamId);
			if fillLevel and fillLevel > 0 then
				if self.NoPatch then
					g_currentMission.husbandries.cow.fillLevels[Fillable.FILLTYPE_MILK] =  fillLevel
				else
					g_currentMission.husbandries.cow.fillLevelMilk = fillLevel
				end
			end
		end
	end
		 
end;

function MilchTransport:writeUpdateStream(streamId, connection, dirtyMask)
	if not connection:getIsServer() then
        if self.isMilchTrailerFilling then
			local milk = 0
			if self.NoPatch then
				milk = g_currentMission.husbandries.cow.fillLevels[Fillable.FILLTYPE_MILK]
			else
				milk = g_currentMission.husbandries.cow.fillLevelMilk
			end
			streamWriteFloat32(streamId, milk);
		end
	end
end;

function MilchTransport:draw()
end;

function MilchTransport:onAttach()
end; 

function MilchTransport:onDetach()
	if self.milchTrailerActivatableAdded then
		g_currentMission:removeActivatableObject(self.milchTrailerActivatable);
		self.milchTrailerActivatableAdded = false;
	end;
end;

function MilchTransport:onLeave()
	if self.milchTrailerActivatableAdded then
		g_currentMission:removeActivatableObject(self.milchTrailerActivatable);
		self.milchTrailerActivatableAdded = false;
	end;
end

function MilchTransport:getSaveAttributesAndNodes(nodeIdent)

	local attributes = "";
    local nodes = "";
  	
	return attributes,nodes;
end

function MilchTransport:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	return BaseMission.VEHICLE_LOAD_OK;
end

function MilchTransport:setIsMilchTrailerFilling(isFilling, noEventSend)
    MilchTrailerSetIsFillingEvent.sendEvent(self, isFilling, self.isMilchTrailerBuyMilk, self.isZuchtFilling, noEventSend)
    self.isMilchTrailerFilling = isFilling;
end;
 
function MilchTransport:setIsMilchTrailerBuyMilk(isBy, noEventSend)
    MilchTrailerSetIsFillingEvent.sendEvent(self, self.isMilchTrailerFilling, isBy, self.isZuchtFilling, noEventSend)
    self.isMilchTrailerBuyMilk = isBy;
end;

function MilchTransport:setIsZuchtFilling(isFilling, noEventSend)
	MilchTrailerSetIsFillingEvent.sendEvent(self, self.isMilchTrailerFilling, self.isMilchTrailerBuyMilk, isFilling, noEventSend)
    self.isZuchtFilling = isFilling;
end;

function MilchTransport:addMilchTrailerFillTrigger(trigger, send, noEventSend)
	table.insert(self.MilchTrailerFillTriggers, trigger);
	if send then
		MilchTriggerCallbackEvent.sendEvent(self, trigger.id, trigger.fillMilk, true, noEventSend)
	end		
 end;
 
function MilchTransport:removeMilchTrailerFillTrigger(trigger, send, noEventSend)
	 for i=1, table.getn(self.MilchTrailerFillTriggers) do
        if self.MilchTrailerFillTriggers[i].id == trigger.id then
            table.remove(self.MilchTrailerFillTriggers, i);
            break;
        end;
    end;
	if send then
		MilchTriggerCallbackEvent.sendEvent(self, trigger.id, trigger.fillMilk, false, noEventSend)
	end	
end;

function MilchTransport:TriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
		
	local vehicle = g_currentMission.nodeToVehicle[otherId];
	if vehicle ~= nil then
		if vehicle.milktruckStopNode then
			if onEnter then
				self:addMilchTrailerFillTrigger({id = otherId, buyMilk = true});
			else -- onLeave
				self:removeMilchTrailerFillTrigger({id = otherId, buyMilk = true});
			end;
		elseif vehicle ~= self and vehicle.addMilchTrailerFillTrigger ~= nil and vehicle.addMilchTrailerFillTrigger ~= nil then
			if onEnter then
				vehicle:addMilchTrailerFillTrigger({id = triggerId, Zucht = self});
			else -- onLeave
				vehicle:removeMilchTrailerFillTrigger({id = triggerId, Zucht = self});
			end;
		end;
	end;
 end;
 
MilchTrailerActivatable = {}
local MilchTrailerActivatable_mt = Class(MilchTrailerActivatable);
 
function MilchTrailerActivatable:new(trailer)
    local self = {};
    setmetatable(self, MilchTrailerActivatable_mt);
 
    self.trailer = trailer;
    self.activateText = "unknown";
 
    return self;
end;
 
function MilchTrailerActivatable:getIsActivatable()
    if self.trailer:getIsActiveForInput() then
		if self.trailer.isNearMilktruckFillTrigger and self.trailer:getFillLevel(Fillable.FILLTYPE_MILK) < self.trailer.capacity and self.trailer:allowFillType(Fillable.FILLTYPE_MILK, false) then
			self:updateActivateText();
			return true;
		elseif (self.trailer.isNearBuyMilkTrigger or self.trailer.isNearZuchtTrigger) and self.trailer:getFillLevel(Fillable.FILLTYPE_MILK) > 0 then
			self:updateActivateText();
			return true;
		end
    end
    return false;
end
 
function MilchTrailerActivatable:onActivateObject()
	if self.trailer.isNearMilktruckFillTrigger then
		self.trailer:setIsMilchTrailerFilling(not self.trailer.isMilchTrailerFilling);
	elseif self.trailer.isNearBuyMilkTrigger then
		self.trailer:setIsMilchTrailerBuyMilk(not self.trailer.isMilchTrailerBuyMilk);
	elseif self.trailer.isNearZuchtTrigger then
		self.trailer:setIsZuchtFilling(not self.trailer.isZuchtFilling);
	end
    self:updateActivateText();
    g_currentMission:addActivatableObject(self);
end;
 
function MilchTrailerActivatable:drawActivate()
    -- TODO draw icon
end;
 
function MilchTrailerActivatable:updateActivateText()
	if self.trailer.isNearMilktruckFillTrigger then
		if self.trailer.isMilchTrailerFilling then
			self.activateText = string.format(g_i18n:getText("stop_refill_OBJECT"), self.trailer.typeDesc);
		else
			self.activateText = string.format(g_i18n:getText("refill_OBJECT"), self.trailer.typeDesc);
		end;
	elseif self.trailer.isNearBuyMilkTrigger or self.trailer.isNearZuchtTrigger then
		if self.trailer.isMilchTrailerBuyMilk or self.trailer.isZuchtFilling then
			self.activateText = string.format(g_i18n:getText("stop_refill_OBJECT"), g_i18n:getText("Milk_storage"));
		else
			self.activateText = string.format(g_i18n:getText("refill_OBJECT"), g_i18n:getText("Milk_storage"));
		end;
	end;
end;
