--KHI NHẤP CHUỘT PHẢI -> HIỂN THỊ LỰA CHỌN TƯƠNG TÁC VỚI ĐỐI TƯỢNG NHIỆM VỤ

require "npc/vl_quest_npc_client"

assert(VLZB, "Stack trace: Missing dependency: VLZB - vl_addcontextmenu.lua")
 
local GetZombieOnlineIDorUID = VLZB.GetZombieOnlineIDorUID
local GetQuestGlobalModData = VLGMD.GetQuestGlobalModData
local NPCTurnToZombie = VLF.NPCTurnToZombie
local GetZombieModDataQuest = VLZB.GetZombieModDataQuest
local GetFoodInContainer = VLIT.GetFoodInContainer
local GetWaterSourcesInCont = VLIT.GetWaterSourcesInCont
local GetPlayerGlobalModDataQ1 = VLGMD.GetPlayerGlobalModDataQ1
local SetPlayerGMD_Q1 = VLGMD.SetPlayerGMD_Q1
local GetItemInContainerRecursive = VLIT.GetItemInContainerRecursive
local AddReputationPoint = VLGMD.AddReputationPoint

--===========================================================================--
--============================== TALK TO NPCs ===============================--
--===========================================================================--

--Talk với Free NPC bị nhiễm
local function TalkToInfectedNPC(player, square, zNPC, qStep)
	NPCTurnToZombie(player, zNPC, qStep, {isPopUp = false})
end

--Hiển thị bảng thông tin sức khỏe NPC
local function ShowNPCInfo(player, square, zNPC, qStep)
	VLF.QuestUI.NpcHealthWindow(player, qStep, zNPC)
end

--Cho NPC ăn
local function FeedTheNPC(player, square, zNPC, qStep)
	local foodList = {}
    -- Inventory chính
    local inv = player:getInventory()
    GetFoodInContainer(inv, foodList)
	VLF.QuestUI.FoodsInINVWindow(player, qStep, zNPC, foodList)
end

--Cho NPC uống
local function GiveADrinkForNPC(player, square, zNPC, qStep)
	--Nếu trong người có nước thì giảm nước trong chai, giảm thirst cho NPC.
	local waterSourceList = {}
    -- Inventory chính
    local inv = player:getInventory()
    GetWaterSourcesInCont(inv, waterSourceList)
	 
	if #waterSourceList > 0 then
		for i = #waterSourceList, 1, -1 do
			local waterSource = waterSourceList[i]
			if waterSource then
				local fluidCont = waterSource:getFluidContainer()
				if fluidCont and fluidCont:getAmount() > 0 then
					--if (fluidCont:getPrimaryFluid():getFluidTypeString() == "Water" or fluidCont:getPrimaryFluid():getFluidTypeString() == "CarbonatedWater") then
					if fluidCont:contains(Fluid.Water) or fluidCont:contains(Fluid.CarbonatedWater) then
						local playerGMD_Quest_Q1 = GetPlayerGlobalModDataQ1(player, qStep)
						if playerGMD_Quest_Q1[qStep].npcThirst > 10 then
							local amount = fluidCont:getAmount() * 100
							
							local thirst = playerGMD_Quest_Q1[qStep].npcThirst
							
							if amount >= thirst then
								SetPlayerGMD_Q1(player, qStep, "npcThirst", 0.0)
								fluidCont:adjustAmount((amount - thirst) / 100)
							else
								SetPlayerGMD_Q1(player, qStep, "npcThirst", (thirst - amount))
								fluidCont:adjustAmount(0)
							end
							
							zNPC:getEmitter():playSound("drinkingfrombottle")
							AddReputationPoint(player, 1)
							return
						else
							HaloTextHelper.addBadText(player, getText("IGUI_VLQ_Notification_NPCNotThirsty"))
							return
						end
					end
				end
			end
		end
	end
	
	HaloTextHelper.addBadText(player, getText("IGUI_VLQ_Notification_NotHaveWaterSource"))
end

--Thêm lựa chọn Tương tác với NPC khi chuột phải vào ô npc đứng 	--Talk, TakeCare
local function ContextMenu_TalkToNPC(playerIndex, context, worldobjects, test)
    local player = getSpecificPlayer(playerIndex)
    if not player then return end
    local mx, my = ISCoordConversion.ToWorld(getMouseXScaled(), getMouseYScaled(), player:getZ())
    local x, y, z = math.floor(mx), math.floor(my), player:getZ()

    for _x = x, x + 1 do
        for _y = y, y + 1 do
            local square = getCell():getGridSquare(_x, _y, z)
            if square then
                local objs = square:getMovingObjects()
				if objs and objs:size() > 0 then
					for i = 0, objs:size() - 1 do
						local zNPC = objs:get(i)
						if zNPC and zNPC:isZombie() then
							local questMD = GetQuestGlobalModData(nil)
							local zID = GetZombieOnlineIDorUID(zNPC)
							local qStep = questMD.NPCqStep[zID]
							local npcData = VLF.npcData[qStep]
							if qStep and zNPC:getVariableBoolean(npcData.variable) then
								--hiển thị qStep của NPC trong debug.debug
								if isDebugEnabled() then
									context:addOption(qStep, player, nil)
								end
								
								if not npcData.infected then		--nếu không phải bị nhiễm
									if npcData.needTakeCare == true then	--nếu là NPC cần chăm sóc, thêm menu riêng
										local takeCareOption
										if npcData.name then
											takeCareOption = context:addOption(getText("IGUI_VLQ_TakeCareOf").." "..npcData.name)
										else
											takeCareOption = context:addOption(getText("IGUI_VLQ_TakeCare"))
										end
										
										local takeCareMenu = context:getNew(context)
										context:addSubMenu(takeCareOption, takeCareMenu)
										takeCareMenu:addOption(getText("IGUI_VLQ_TakeCare_Info"), player, ShowNPCInfo, square, zNPC, qStep)
										takeCareMenu:addOption(getText("IGUI_VLQ_TakeCare_Feed"), player, FeedTheNPC, square, zNPC, qStep)
										takeCareMenu:addOption(getText("IGUI_VLQ_TakeCare_GiveADrink"), player, GiveADrinkForNPC, square, zNPC, qStep)
										--takeCareMenu:addOption(getText("IGUI_VLQ_TakeCare_CleanTheBody"), player, CleanTheBodyForNPC, square, zNPC, qStep)
									end 
								 
									 if string.find(qStep, "freeNPC_") then		--nếu là NPC của event Survivalist_InHouse
										context:addOption(getText("IGUI_VLQ_Talk"), player, VLF.TalkToNPC["freeNPC"], square, zNPC, qStep)
									 else
										--tất cả loại NPC còn lại
										local zData = GetZombieModDataQuest(zNPC)
										if zData.name then
											context:addOption(getText("IGUI_VLQ_TalkTo")..zData.name, player, VLF.TalkToNPC[qStep], square, zNPC, qStep)
										else
											context:addOption(getText("IGUI_VLQ_Talk"), player, VLF.TalkToNPC[qStep], square, zNPC, qStep)
										end
									end
								else
									local zData = GetZombieModDataQuest(zNPC)
									context:addOption(getText("IGUI_VLQ_Talk"), player, TalkToInfectedNPC, square, zNPC, qStep)
								end
							end
						end
					end
				end
            end
        end
    end
end
Events.OnPreFillWorldObjectContextMenu.Remove(ContextMenu_TalkToNPC)
Events.OnPreFillWorldObjectContextMenu.Add(ContextMenu_TalkToNPC)


--===========================================================================--
--============================ Get Blood Sample =============================--
--===========================================================================--

local function DoGetBloodSample(player, corpse)
	local inv = player:getInventory()
	if inv then return end
	--local item = inv:FindAndReturn("Base.VLEmptySyringe")
	
	local item = GetItemInContainerRecursive(inv, nil, "Base.VLEmptySyringe")
	if item then
		local square = player:getCurrentSquare()
		local sq = corpse:getSquare()
		--if square and sq and square ~= sq then
		if square and sq then
			local adjacent = AdjacentFreeTileFinder.Find(sq, player)
			if adjacent then
				ISTimedActionQueue.add(ISWalkToTimedAction:new(player, adjacent))
				ISTimedActionQueue.add(VL_ISTakeBloodSample:new(player, corpse, 300))
			end
		end
	else
		HaloTextHelper.addBadText(player, getText("IGUI_VLQ_NotHaveEmptySyringe"))
	end
end

--Thêm lựa chọn Get Blood Sample khi click ô có xác zombie
function VLF.AddContextMenu_BloodSample(playerIndex, context, worldobjects, test)
	local player = getSpecificPlayer(playerIndex)
	local mx, my = ISCoordConversion.ToWorld(getMouseXScaled(), getMouseYScaled(), player:getZ())
    local square = getCell():getGridSquare(math.floor(mx), math.floor(my), math.floor(player:getZ()))
	if square then
		local objs = square:getStaticMovingObjects()
		if objs and objs:size() > 0 then
			for i = 0, objs:size() - 1 do
				local corpse = objs:get(i)
				if corpse and corpse:isZombie() and instanceof(corpse, "IsoDeadBody") and not corpse:isSkeleton() then
				--print("Client-----------AddContextMenu_BloodSample= ")
					--local cData = corpse:getModData()
					local zData = GetZombieModDataQuest(corpse)
					if not zData.takenBloodSample then
						context:addOption(getText("IGUI_VLQ_TakeBloodSample"), player, DoGetBloodSample, corpse)
					end
				end
			end
		end
	end
end
--Events.OnPreFillWorldObjectContextMenu.Remove(VLF.AddContextMenu_BloodSample)
--Events.OnPreFillWorldObjectContextMenu.Add(VLF.AddContextMenu_BloodSample)


--===========================================================================--
--=========================== Get Zombie Specimen ===========================--
--===========================================================================--

local function DoGetZombieSpecimen(player, zombie)
	local inv = player:getInventory()
	--local item1 = inv:FindAndReturn("Base.VLEmptySpecimenContainer")
	local item1 = GetItemInContainerRecursive(inv, nil, "Base.VLEmptySpecimenContainer")
	if item1 then
		--local item2 = inv:FindAndReturn("Base.Scalpel")
		local item2 = GetItemInContainerRecursive(inv, nil, "Base.Scalpel")
		if item2 then
			local square = player:getCurrentSquare()
			local sq = zombie:getSquare()
			if square and sq then
				ISTimedActionQueue.add(ISWalkToTimedAction:new(player, sq))
				ISTimedActionQueue.add(VL_ISTakeZombieSpecimen:new(player, zombie, 500))
			end
		else
			HaloTextHelper.addBadText(player, getText("IGUI_VLQ_NotHaveScalpel"))
		end
	else
		HaloTextHelper.addBadText(player, getText("IGUI_VLQ_NotHaveEmptySpecimenContainer"))
	end
end

--Thêm lựa chọn Take Zombie's Specimen khi click ô có zombie đang nằm
function VLF.AddContextMenu_ZombieSpecimen(playerIndex, context, worldobjects, test)
	local player = getSpecificPlayer(playerIndex)
	local mx, my = ISCoordConversion.ToWorld(getMouseXScaled(), getMouseYScaled(), player:getZ())
    local square = getCell():getGridSquare(math.floor(mx), math.floor(my), math.floor(player:getZ()))
	if square then
		local objs = square:getMovingObjects()
		if objs and objs:size() > 0 then
			for i = 0, objs:size() - 1 do
				local zombie = objs:get(i)
				if zombie and zombie:isZombie() and zombie:getActionStateName() == "onground" then
					--print("Client-----------AddContextMenu_ClickSquare= ")
					--local cData = zombie:getModData()
					local zData = GetZombieModDataQuest(zombie)
					if not zData.takenZombieSpecimen then
						context:addOption(getText("IGUI_VLQ_TakeZombieSpecimen"), player, DoGetZombieSpecimen, zombie)
					end
				end
			end
		end
	end
end
--Events.OnPreFillWorldObjectContextMenu.Remove(VLF.AddContextMenu_ZombieSpecimen)
--Events.OnPreFillWorldObjectContextMenu.Add(VLF.AddContextMenu_ZombieSpecimen)


--===========================================================================--
--========================== Get Infected Specimen ==========================--
--===========================================================================--

local function DoGetInfectedSpecimen(player, zNPC, qStep)
	local inv = player:getInventory()
	--local item1 = inv:FindAndReturn("Base.VLEmptySpecimenContainer")
	local item1 = GetItemInContainerRecursive(inv, nil, "Base.VLEmptySpecimenContainer")
	if item1 then
		--local item2 = inv:FindAndReturn("Base.Scalpel")
		local item2 = GetItemInContainerRecursive(inv, nil, "Base.Scalpel")
		if item2 then
			local square = player:getCurrentSquare()
			local sq = zNPC:getSquare()
			if square and sq then
				local adjacent = AdjacentFreeTileFinder.Find(sq, player)
				if adjacent then
					ISTimedActionQueue.add(ISWalkToTimedAction:new(player, adjacent))
					ISTimedActionQueue.add(VL_ISTakeInfectedNPCSpecimen:new(player, zNPC, 500, qStep))			
				end
			end
		else
			HaloTextHelper.addBadText(player, getText("IGUI_VLQ_NotHaveScalpel"))
		end
	else
		HaloTextHelper.addBadText(player, getText("IGUI_VLQ_NotHaveEmptySpecimenContainer"))
	end
end

--Thêm lựa chọn Take Infected NPC's Specimen khi click ô có NPC
function VLF.AddContextMenu_InfectedSpecimen(playerIndex, context, worldobjects, test)
	local player = getSpecificPlayer(playerIndex)
	local mx, my = ISCoordConversion.ToWorld(getMouseXScaled(), getMouseYScaled(), player:getZ())
    local square = getCell():getGridSquare(math.floor(mx), math.floor(my), math.floor(player:getZ()))
	if square then
		local objs = square:getMovingObjects()
		if objs and objs:size() > 0 then
			for i = 0, objs:size() - 1 do
				local zNPC = objs:get(i)
				if zNPC and zNPC:isZombie() then
					local questMD = GetQuestGlobalModData(nil)
					local zID = GetZombieOnlineIDorUID(zNPC)
					local qStep = questMD.NPCqStep[zID]
					if qStep and zNPC:getVariableBoolean(VLF.npcData[qStep].variable) and VLF.npcData[qStep].infected then
						--local cData = zNPC:getModData()
						local zData = GetZombieModDataQuest(zNPC)
						--context:addOption(getText("IGUI_VLQ_Talk"), player, TalkToInfectedNPC, square, zNPC, qStep)
						if not zData.takenInfectedSpecimen then
							context:addOption(getText("IGUI_VLQ_TakeInfectedSpecimen"), player, DoGetInfectedSpecimen, zNPC, qStep)
						end
					end
				end
			end
		end
	end
end
--Events.OnPreFillWorldObjectContextMenu.Remove(VLF.AddContextMenu_InfectedSpecimen)
--Events.OnPreFillWorldObjectContextMenu.Add(VLF.AddContextMenu_InfectedSpecimen)