--
-- sellSiloTrigger
--
-- MOD by Defender
--

print("trailerMOD: sellSiloTrigger jf livestocktrailer loaded");

sellSiloPresenter = {};

function sellSiloPresenter:loadMap(name)
  print("sellSiloPresenter jf loaded");
  if g_currentMission.sellSiloPresenter == nil then
     g_currentMission.sellSiloPresenter = {};
  end;
end;

function sellSiloPresenter:deleteMap()
end;

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

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

function sellSiloPresenter:update(dt)
end;

function sellSiloPresenter:draw()
  if g_currentMission.sellSiloPresenter~=nil then
    for i=1, table.maxn(g_currentMission.sellSiloPresenter) do
      if g_currentMission.sellSiloPresenter[i]~=nil then
        g_currentMission.sellSiloPresenter[i]:draw();
      end;
    end;
  end;
end;

addModEventListener(sellSiloPresenter);


sellSiloTrailerInTriggerEvent = {};
sellSiloTrailerInTriggerEvent_mt = Class(sellSiloTrailerInTriggerEvent, Event);

InitEventClass(sellSiloTrailerInTriggerEvent, "sellSiloTrailerInTriggerEvent");

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

function sellSiloTrailerInTriggerEvent:new(object, trailer)
    local self = sellSiloTrailerInTriggerEvent:emptyNew()
    self.object = object;
    self.trailer = trailer;
    return self;
end;

function sellSiloTrailerInTriggerEvent:readStream(streamId, connection)
    self.object = networkGetObject(streamReadInt32(streamId));
    local nID = streamReadInt32(streamId)
    self.trailer = nil;
    if nID ~= 0 then
      self.trailer = networkGetObject(nID);
    end;
    self:run(connection);
end;

function sellSiloTrailerInTriggerEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
    local nID = 0;
    if self.trailer ~= nil then
      nID=networkGetObjectId(self.trailer);    
    end;
    streamWriteInt32(streamId, nID);
end;

function sellSiloTrailerInTriggerEvent:run(connection)
    sellSiloTrailerInTriggerEvent.execute(self.object, self.trailer);
end;

function sellSiloTrailerInTriggerEvent.execute(object, trailer)
  object.trailer = trailer;
end;




sellSiloSetupEvent = {};
sellSiloSetupEvent_mt = Class(sellSiloSetupEvent, Event);

InitEventClass(sellSiloSetupEvent, "sellSiloSetupEvent");

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

function sellSiloSetupEvent:new(object, actualfruit, fill )
    local self = sellSiloSetupEvent:emptyNew()
    self.object = object;
    self.actualfruit = actualfruit;
    self.fill = fill;
    return self;
end;

function sellSiloSetupEvent:readStream(streamId, connection)
    self.object = networkGetObject(streamReadInt32(streamId));
    self.actualfruit = streamReadInt8(streamId);
    self.fill = streamReadBool(streamId);
    self:run(connection);
end;

function sellSiloSetupEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
    streamWriteInt8(streamId, self.actualfruit);
    streamWriteBool(streamId, self.fill);
end;

function sellSiloSetupEvent:run(connection)
    sellSiloSetupEvent.execute(self.object, self.actualfruit, self.fill);
end;

function sellSiloSetupEvent.execute(object, actualfruit, fill)
    object.actualfruit = actualfruit;
    object.fill = fill;
    local key="FRUITTYPE_"..string.upper(FruitUtil.fruitIndexToDesc[object.fruits[actualfruit]].name);
    object.fillType = FruitUtil[key];
    object.subHudBack = Utils.getFilename(FruitUtil.fruitIndexToDesc[actualfruit].hudFruitOverlayFilename, object.baseDirectory);
    object.fruitHud = Overlay:new("fruitHud",object.subHudBack, 0.01, 0.01, g_currentMission.hudTipperOverlay.width, g_currentMission.hudTipperOverlay.height);
end;




sellSiloTrigger = {};

local sellSiloTrigger_mt = Class(sellSiloTrigger, Object);

--InitObjectClass(sellSiloTrigger, "sellSiloTrigger");

function sellSiloTrigger:OnCreate(id)
    local trigger = sellSiloTrigger:new(g_server ~= nil, g_client ~= nil);
    local index = g_currentMission:addOnCreateLoadedObject(trigger);
    trigger:load(id);
    trigger:register(true);
end;

function sellSiloTrigger:new(isServer, isClient)
    local self = Object:new(isServer, isClient, sellSiloTrigger_mt);
    self.className = "sellSiloTrigger";
    self.rootNode = 0;

    self.sellSiloTriggerDirtyFlag = self:getNextDirtyFlag();
    return self;
end;

sellSiloOnCreate = sellSiloTrigger.OnCreate;

function sellSiloTrigger:load(id)
  print("Pridavam sellSiloTrigger");
  if g_currentMission.sellSiloPresenter == nil then
    g_currentMission.sellSiloPresenter = {};
  end;
  table.insert(g_currentMission.sellSiloPresenter,self);
  self.startFilling = sellSiloTrigger.startFilling;
  self.stopFilling = sellSiloTrigger.stopFilling;
  self.rootNode = id;
  if self.isServer then
    addTrigger(id, "sellSiloTriggerCallback", self);
  end;
	self.fillSpeed = getUserAttribute(id, "fillSpeed");
	self.extraFruits = Utils.getNoNil(getUserAttribute(id, "extraFruits"),"");
	self.id = id;
  
	self.trailerInTrigger = 0;	
	self.fruitTriggerId = 0;
	
	self.fill = false;
	self.printText = false;
	
	self.fruits = {};
	local i = 0;
  for a=1, FruitUtil.NUM_FRUITTYPES do
    if ((FruitUtil.fruitIndexToDesc[a].allowsSeeding) or (string.find(self.extraFruits, FruitUtil.fruitIndexToDesc[a].name)~=nil)) and (FruitUtil.fruitIndexToDesc[a].name~="grass") then
      i=i+1;
      self.fruits[i]=a;
    end;      
  end;
  self.fruitscount=i;
  self.actualfruit=1;
  local key="FRUITTYPE_"..string.upper(FruitUtil.fruitIndexToDesc[self.actualfruit].name);
  self.fillType = FruitUtil[key];
  self.subHudBack = Utils.getFilename(FruitUtil.fruitIndexToDesc[self.actualfruit].hudFruitOverlayFilename, self.baseDirectory);
  self.fruitHud = Overlay:new("fruitHud",self.subHudBack, 0.01, 0.01, g_currentMission.hudTipperOverlay.width, g_currentMission.hudTipperOverlay.height);
  
  if self.isClient then
    self.siloParticleSystemRoot = loadI3DFile("data/vehicles/particleSystems/wheatParticleSystemLong.i3d");
    local x,y,z = localToWorld(self.id, -0.05, 0.15, 0.05);
    setTranslation(self.siloParticleSystemRoot, x, y, z);
    link(getRootNode(), self.siloParticleSystemRoot);

    for i=0, getNumOfChildren(self.siloParticleSystemRoot)-1 do
      local child = getChildAt(self.siloParticleSystemRoot, i);
      if getClassName(child) == "Shape" then
        local geometry = getGeometry(child);
        if geometry ~= 0 then
          if getClassName(geometry) == "ParticleSystem" then
            self.siloParticleSystem = geometry;
          end;
        end;
      end;
    end;

    if self.siloParticleSystem ~= nil then
      setEmittingState(self.siloParticleSystem, false);
    end;
  end;
  self.ShowHud=false; 	
end;

function sellSiloTrigger:loadMap(name)
end;

function sellSiloTrigger:deleteMap()
end;

function sellSiloTrigger:delete()
  if self.isServer then
    removeTrigger(self.id);
  end;

  if self.siloParticleSystemRoot ~= nil then
    delete(self.siloParticleSystemRoot);
  end;

  delete(self.rootNode);
  SiloTrigger:superClass().delete(self);
end;

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

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

function sellSiloTrigger:readStream(streamId, connection)
    sellSiloTrigger:superClass().readStream(self, streamId);
    if connection:getIsServer() then
      self.fill = streamReadBool(streamId);
      self.actualfruit = streamReadInt8(streamId);
      local key="FRUITTYPE_"..string.upper(FruitUtil.fruitIndexToDesc[self.fruits[self.actualfruit]].name);
      self.fillType = FruitUtil[key];
      self.subHudBack = Utils.getFilename(FruitUtil.fruitIndexToDesc[self.actualfruit].hudFruitOverlayFilename, self.baseDirectory);
      self.fruitHud = Overlay:new("fruitHud",self.subHudBack, 0.01, 0.01, g_currentMission.hudTipperOverlay.width, g_currentMission.hudTipperOverlay.height);
--      self.nID = streamReadInt32(streamId);
--      if self.nID == 0 then
--        self.nID = nil;
--      end;
    end;
end;

function sellSiloTrigger:writeStream(streamId, connection)
    sellSiloTrigger:superClass().writeStream(self, streamId);
    if not connection:getIsServer() then
      streamWriteBool(streamId, self.fill);
      streamWriteInt8(streamId, self.actualfruit);
--      local nID = 0;
--      if self.trailer ~= nil then
--        nID=networkGetObjectId(self.trailer);
--      end;
--      print("posilam nID="..tostring(nID));
--      streamWriteInt32(streamId, nID);
    end;
end;

function sellSiloTrigger:readUpdateStream(streamId, timestamp, connection)

end;

function sellSiloTrigger:writeUpdateStream(streamId, connection, dirtyMask)

end;

function sellSiloTrigger:update(dt)
--  if not self.isServer then
--    print("nID="..tostring(self.nID));
--    if self.nID ~= nil then
--      if self.nID~=0 then
--        self.trailer = networkGetObject(self.nID);
--      else
--        self.trailer = nil;
--      end;
--      self.nID = nil;
--    end;
--  end;
  if self.isClient then

    if self.trailer ~= nil and self.trailer:getIsActiveForInput() then
		  self.printText = false;
			if self.trailer.fillTypes ~= nil and self.trailer.setFillLevel ~= nil and self.trailer.fillLevel ~= nil then

--        local s=g_i18n:getText(FruitUtil.fruitIndexToDesc[self.fruits[self.actualfruit]].name);
--        if string.find(s,".xml")~=nil then
--          s=FruitUtil.fruitIndexToDesc[self.fruits[self.actualfruit]].name;
--        end;
--        g_currentMission:addExtraPrintText(s);

        if not self.fill then
          g_currentMission:addHelpButtonText(g_i18n:getText("SELLSILO_CHOOSEFRUIT"),InputBinding.IMPLEMENT_EXTRA2);

          if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2)  then
            self.actualfruit=self.actualfruit+1;            
            if self.actualfruit>self.fruitscount then
              self.actualfruit=1;
            end;
            local key="FRUITTYPE_"..string.upper(FruitUtil.fruitIndexToDesc[self.fruits[self.actualfruit]].name);
            self.fillType = FruitUtil[key];
            self.subHudBack = Utils.getFilename(FruitUtil.fruitIndexToDesc[self.fruits[self.actualfruit]].hudFruitOverlayFilename, self.baseDirectory);
            self.fruitHud = Overlay:new("fruitHud",self.subHudBack, 0.01, 0.01, g_currentMission.hudTipperOverlay.width, g_currentMission.hudTipperOverlay.height);

            if g_server ~= nil then
                g_server:broadcastEvent(sellSiloSetupEvent:new(self, self.actualfruit, self.fill), nil, nil, self);
            else
                g_client:getServerConnection():sendEvent(sellSiloSetupEvent:new(self, self.actualfruit, self.fill));
            end;
		      end; 
        end;
        self.ShowHud=true;
        local realFillType = FruitUtil.fruitTypeToFillType[self.fillType];
        local fillName = Fillable.fillTypeIntToName[realFillType]; 
        
				if realFillType == self.trailer.currentFillType or self.trailer.currentFillType == Fillable.FILLTYPE_UNKNOWN then
					if self.trailer.fillLevel < self.trailer.capacity and self.trailer:allowFillType(realFillType, true) then
						self.printText = true;
		        if self.fill and self.printText then
			        g_currentMission:addHelpButtonText(g_i18n:getText("SELLSILO_STOPFILL"),InputBinding.SELLSILO_FILL);
		        elseif self.printText then
			        g_currentMission:addHelpButtonText(g_i18n:getText("SELLSILO_STARTFILL"),InputBinding.SELLSILO_FILL);
		        end;						
		        if InputBinding.hasEvent(InputBinding.SELLSILO_FILL)  then
			        if self.fill then
			          self:stopFilling();
			        else
			          self:startFilling();
			        end;
		        end;            						
					end;
				end;
      end;
    else
      self.ShowHud = false;
    end;
    setEmittingState(self.siloParticleSystem, self.fill);
  end;
  if self.isServer and self.trailer~=nil then
    local _realFillType = FruitUtil.fruitTypeToFillType[self.fillType];
        
		if (_realFillType == self.trailer.currentFillType or self.trailer.currentFillType == Fillable.FILLTYPE_UNKNOWN) and self.trailer:allowFillType(_realFillType, true) then
			if self.trailer.fillLevel < self.trailer.capacity then
				if self.fill then
          local difficultyMultiplier = 2 ^ (3 - g_currentMission.missionStats.difficulty);
          local price = FruitUtil.fruitIndexToDesc[self.fillType].pricePerLiter;
          price = price * difficultyMultiplier*2;
          local deltaFillLevel = dt*self.fillSpeed;
          if g_currentMission.missionStats.money<=deltaFillLevel*price then
            deltaFillLevel=g_currentMission.missionStats.money/price;
            self:stopFilling();
          end;
          if deltaFillLevel>0 then
					  self.trailer:setFillLevel(self.trailer.fillLevel+deltaFillLevel, _realFillType);
            g_currentMission:addSharedMoney(-(deltaFillLevel*price));
          end;
          if g_currentMission.missionStats.money<=0 then
            g_currentMission:addSharedMoney(-(g_currentMission.missionStats.money));
            self:stopFilling();
          end; 									
				end;
			else
			  if self.fill then
			    self:stopFilling();
			  end;
			end;
		end;
  end;
end;

function sellSiloTrigger:startFilling()
  self.fill = true;
  if g_server ~= nil then
    g_server:broadcastEvent(sellSiloSetupEvent:new(self, self.actualfruit, true), nil, nil, self);
  else
    g_client:getServerConnection():sendEvent(sellSiloSetupEvent:new(self, self.actualfruit, true));
  end;			        
end;

function sellSiloTrigger:stopFilling()
  self.fill = false;
  if g_server ~= nil then
    g_server:broadcastEvent(sellSiloSetupEvent:new(self, self.actualfruit, false), nil, nil, self);
  else
    g_client:getServerConnection():sendEvent(sellSiloSetupEvent:new(self, self.actualfruit, false));
  end;
end;


function sellSiloTrigger:draw()
  if self.ShowHud then
    self.fruitHud:render();
    local s=g_i18n:getText(FruitUtil.fruitIndexToDesc[self.fruits[self.actualfruit]].name);
    if string.find(s,".xml")~=nil then              
      s=FruitUtil.fruitIndexToDesc[self.fruits[self.actualfruit]].name;
    end;
    renderText(0.01, 0.01+g_currentMission.hudTipperOverlay.height+0.02,0.02,s);
    local difficultyMultiplier = 2 ^ (3 - g_currentMission.missionStats.difficulty);
    local price = FruitUtil.fruitIndexToDesc[self.fillType].pricePerLiter;
    price = price * difficultyMultiplier*1000*2;
    renderText(0.01, 0.01+g_currentMission.hudTipperOverlay.height+0.04,0.02,string.format("%d %s",price, g_i18n:getText("PricePerTon")));
  end;
end;

function sellSiloTrigger:sellSiloTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
  assert(self.isServer);
  local trailer = g_currentMission.objectToTrailer[otherShapeId];
  if trailer ~= nil and trailer.allowFillFromAir then
    if onEnter then
			self.trailerInTrigger = otherId;
			self.trailer = trailer;
			g_server:broadcastEvent(sellSiloTrailerInTriggerEvent:new(self, trailer));
			self.fruitTriggerId = triggerId;		
    elseif onLeave then
			self.trailerInTrigger = 0;
			self.trailer = nil;
			self.fruitTriggerId = 0;
      g_server:broadcastEvent(sellSiloTrailerInTriggerEvent:new(self, nil));
      self:stopFilling();
    end;
  end;
end;