--***********************************************************
--**                    ROBERT JOHNSON                     **
--***********************************************************

require "TimedActions/ISBaseTimedAction"

ISGrabItemAction = ISBaseTimedAction:derive("ISGrabItemAction");

function ISGrabItemAction:isValid()
	-- Prevent grabbing item if another player acts with it
	if not isItemTransactionConsistent(self.item:getItem(), self.item:getItem():getContainer(), self.destContainer) then
		return false
	end

	-- Prevent grabbing items through walls
	if self.item:getSquare() and self.character:getSquare() then
		if self.item:getSquare():isBlockedTo(self.character:getSquare()) then
			return false;
		end;
	end;

	-- Check that the item wasn't picked up by a preceding action
	if self.item == nil or self.item:getSquare() == nil then return false end

	-- Check that the item wasn't removed by another player's action
	if not self.item:getSquare():getWorldObjects():contains(self.item) then return false; end;

	return self.destContainer:hasRoomFor(self.character, self.item:getItem())
end

function ISGrabItemAction:update()
	self.item:getItem():setJobDelta(self:getJobDelta());
end

function ISGrabItemAction:start()
	self:setActionAnim("Loot");
	self:setAnimVariable("LootPosition", "Low");
	self:setOverrideHandModels(nil, nil);
	self.item:getItem():setJobType(getText("ContextMenu_Grab"));
	self.item:getItem():setJobDelta(0.0);
	self.character:reportEvent("EventLootItem");
	createItemTransaction(self.item:getItem(), self.item:getItem():getContainer(), self.destContainer)
end

function ISGrabItemAction:stop()
    ISBaseTimedAction.stop(self);
    self.item:getItem():setJobDelta(0.0);
end

function ISGrabItemAction:perform()
	local queuedItem = table.remove(self.queueList, 1);
	for i,item in ipairs(queuedItem.items) do
		self.item = item
		-- Check destination container capacity and item-count limit.
		if not self:isValid() then
			self.queueList = {}
			break
		end

		if instanceof(item:getItem(), "Radio") then
			local square = item:getItem():getWorldItem():getSquare()
			local _obj = nil
			for i=0, square:getObjects():size()-1 do
				local tObj = square:getObjects():get(i)
				if instanceof(tObj, "IsoRadio") then
					if tObj:getModData().RadioItemID == item:getItem():getID() then
						_obj = tObj
						break
					end
				end
			end
			if _obj ~= nil then
				local deviceData = _obj:getDeviceData();
				if deviceData then
					item:getItem():setDeviceData(deviceData);
				end
				square:transmitRemoveItemFromSquare(_obj)
				square:RecalcProperties();
				square:RecalcAllWithNeighbours(true);
			end
		end
		
		self:transferItem(item);
	end
	if #self.queueList > 0 then
		queuedItem = self.queueList[1]
		self.maxTime = queuedItem.time;
		self.action:setTime(tonumber(queuedItem.time))
		self.item = queuedItem.items[1];
		self:resetJobDelta();
	else
		self.action:stopTimedActionAnim();
		self.action:setLoopedAction(false);
		-- needed to remove from queue / start next.
		ISBaseTimedAction.perform(self);
	end
end

function ISGrabItemAction:transferItem(item)

	if isItemTransactionConsistent(self.item:getItem(), self.item:getItem():getContainer(), self.destContainer) then
		removeItemTransaction(self.item:getItem(), self.item:getItem():getContainer(), self.destContainer)
	else
		return
	end

	local inventoryItem = self.item:getItem()
	self.item:getSquare():transmitRemoveItemFromSquare(self.item);
	self.item:removeFromWorld()
	self.item:removeFromSquare()
	self.item:setSquare(nil)
	inventoryItem:setWorldItem(nil)
	inventoryItem:setJobDelta(0.0);
	self.destContainer:setDrawDirty(true);
	self.destContainer:AddItem(inventoryItem);

	local pdata = getPlayerData(self.character:getPlayerNum());
	if pdata ~= nil then
		ISInventoryPage.renderDirty = true
--		pdata.playerInventory:refreshBackpacks();
--		pdata.lootInventory:refreshBackpacks();
	end
end

function ISGrabItemAction:checkQueueList()
	-- Get the last timed action in the character's queue.
	-- Reuse the action if it's an ISGrabItemAction.
	local actionQueue = ISTimedActionQueue.getTimedActionQueue(self.character)
	local lastAction = actionQueue.queue[#actionQueue.queue]
	local addTo = self
	if lastAction and (lastAction.Type == "ISGrabItemAction") then
		addTo = lastAction
	end
	local fullType = self.item:getItem():getFullType()
	-- first time we call this
	if addTo == self then
		self.queueList = {};
		local queuedItem = {items = {self.item}, time = self.maxTime, type = fullType};
		table.insert(self.queueList, queuedItem);
	else
		-- ISTimedActionQueue.add() won't add this action.
		self.ignoreAction = true;
		local typeAlreadyExist = false;
		-- we check if in our queue list an item with the same type exist, so we can transfer them in bulk
		-- limit this to 20 items (so transfer 20 per 20 nails)
		for i, v in ipairs(addTo.queueList) do
			if v.type == fullType and #v.items < 20 then
				table.insert(v.items, self.item);
				typeAlreadyExist = true;
				break;
			end
		end
		-- add the current item to our queue list
		if not typeAlreadyExist then
			table.insert(addTo.queueList, {items = {self.item}, time = self.maxTime, type = fullType});
		end
	end
end

function ISGrabItemAction:new (character, item, time)
	local o = {}
	setmetatable(o, self)
	self.__index = self
	o.character = character;
	o.item = item;
	o.stopOnWalk = true;
	o.stopOnRun = true;
	o.maxTime = time;
	o.loopedAction = true;
	o.destContainer = o.character:getInventory();
	o:checkQueueList();
	return o
end
