--[[
	Interactivity for stove furniture
	Author: HarukaSai (visit us at: https://discord.com/invite/efp)
	Credits: Aoldri
	19-06-2023
]]

local function use_container(id,pid)
	local box = id and level.object_by_id(id)
	if (box) then
		--level.map_add_object_spot(id, "ui_pda2_actor_box_location", "st_ui_pda_actor_box") -- debug
		curBoxID = pid
		hide_hud_inventory()
		box:use(db.actor)
		return true -- destroy timed event
	end 
	return false -- repeat timed event
end 

-- called from item section in items.ltx
function access_inventory(obj)
	local id = obj:id()
	local m_data = alife_storage_manager.get_state()
	local se_inv_box = m_data.stove_stashes and m_data.stove_stashes[id] and alife_object(m_data.stove_stashes[id])
	if not (se_inv_box) then
		-- position under map
		local pos = vec_set(obj:position())
		pos.y = pos.y - 50

		-- create inventory_box_s
		se_inv_box = alife_create(SYS_GetParam(0, obj:section(), "integrated_storage"),pos,obj:level_vertex_id(),obj:game_vertex_id())

	end
	if (se_inv_box) then
		-- shouldn't be possible but very safe incase some sort of save corruption
		if not (IsInvbox(nil,se_inv_box:clsid())) then
			if m_data.stove_stashes then
				m_data.stove_stashes[id] = nil
			end
			return 
		end
		
		-- force strictly online
		alife():set_switch_online(se_inv_box.id,true)
		alife():set_switch_offline(se_inv_box.id,false)
		
		-- Save container
		if not (m_data.stove_stashes) then
			m_data.stove_stashes = {}
		end
		m_data.stove_stashes[id] = se_inv_box.id
		
		-- Object will come online next update so wait
		CreateTimeEvent(id,"container",0,use_container,se_inv_box.id,id)
	end
end

local ratio = utils_xml.screen_ratio()
GUI = nil -- instance, don't touch

class "UICookStove" (CUIScriptWnd)

function UICookStove:__init() super()
	self:InitControls()
	self:InitCallbacks()
end

function UICookStove:__finalize()
	GUI = nil
end

function UICookStove:InitControls()
	self:SetWndRect(Frect():set(0,0,1024,768))
	self.wide = (device().width/device().height) > (1024/768 + 0.01)
	
	self:SetAutoDelete(true)

	local xml = CScriptXmlInit()
	-- xml:ParseFile("ui_sleep_dialog.xml")
    xml:ParseFile("ui_furniture_stove_dialog.xml")

	self.back = xml:InitFrame("background", self)

	self.icon = xml:InitStatic("icon", self.back)
	self.icon_temp = xml:InitStatic("icon", self.back)

	self.icon:SetWndSize(vector2():set( self.icon:GetWidth(), self.icon:GetWidth() / ratio ))

	--self.btn_pickup = xml:Init3tButton("btn_pickup", self.back)
	--self:Register(self.btn_pickup, "btn_pickup")

    self.btn_close = xml:Init3tButton("btn_close", self.back)
	self:Register(self.btn_close, "btn_close")

	self.btn_access_stash = xml:Init3tButton("btn_access_stash", self.back)
	self:Register(self.btn_access_stash, "btn_access_stash")


    self.btn_use_stove = xml:Init3tButton("btn_use_stove", self.back)
	self:Register(self.btn_use_stove, "btn_use_stove")
end

function UICookStove:AccessStash()
	local obj = get_object_by_id(self.obj_id)
	access_inventory(obj)
	self:Close()
end

function UICookStove:GetStashObj()
	local m_data = alife_storage_manager.get_state()
	local se_inv_box = m_data.stove_stashes and m_data.stove_stashes[self.obj_id] and alife_object(m_data.stove_stashes[self.obj_id])
	local stash_id = nil
	if (se_inv_box) then
		-- shouldn't be possible but very safe incase some sort of save corruption
		if not (IsInvbox(nil,se_inv_box:clsid())) then
			if m_data.stove_stashes then
				m_data.stove_stashes[self.obj_id] = nil
			end
			return 
		end
		
		-- force strictly online
		alife():set_switch_online(se_inv_box.id,true)
		alife():set_switch_offline(se_inv_box.id,false)
		
		-- Save container
		if not (m_data.stove_stashes) then
			m_data.stove_stashes = {}
		end
		m_data.stove_stashes[self.obj_id] = se_inv_box.id

		stash_id = se_inv_box.id
		
	end
	-- Object will come online next update so wait
	CreateTimeEvent(self.obj_id,"move_stash",0,self.GiveStashToActor,self,stash_id)
end

function UICookStove:Pickup()
	local obj = get_object_by_id(self.obj_id)
	
	alife_create_item(self.section.item, db.actor)

	local m_data = alife_storage_manager.get_state()
	if m_data.stove_stashes then
		local id = m_data.stove_stashes[self.obj_id]
		local stash_obj = get_object_by_id(id)
		if stash_obj then
			stash_obj:iterate_inventory_box( function(temp, obj)
				stash_obj:transfer_item(obj, db.actor)
			end, stash_obj)
		end
		alife_release_id(id)
	end

	alife_release(obj)
	self:Close()
end

function UICookStove:UseCook()
	self:GetStashObj()
end

local item_ids = {}
local stash_obj_id = nil

function return_items()
	if stash_obj_id == nil then return end
    local stash_obj = get_object_by_id(stash_obj_id)
    if stash_obj == nil then return end

    for i, id in ipairs(item_ids) do
        local item_obj = get_object_by_id(id)
        if item_obj then
            db.actor:transfer_item(item_obj, stash_obj)
        end
    end
end

function GUI_on_hide(name)
	if name == "UICook" then
		return_items()
		UnregisterScriptCallback("GUI_on_hide", GUI_on_hide)
	end
end

function UICookStove:GiveStashToActor(id)
	local items = {}

	if id then
		local stash_obj = get_object_by_id(id)
		stash_obj:iterate_inventory_box( function(temp, obj)
			table.insert(items, obj:id())
			stash_obj:transfer_item(obj, db.actor)
		end, stash_obj)
	end

	item_ids = items
	stash_obj_id = id

	RegisterScriptCallback("GUI_on_hide", GUI_on_hide)
	
	CreateTimeEvent(self.obj_id,"open_stove",0.1,self.OpenCookUI,self)
	return true
end

function UICookStove:OpenCookUI()
	local obj = get_object_by_id(self.obj_id)
	local cook_ui = item_cooking.start(obj, "fieldcooker")
	self:Close()
	return true
end

function UICookStove:InitCallbacks()
	self:AddCallback("btn_access_stash", ui_events.BUTTON_CLICKED, self.AccessStash, self)
	--self:AddCallback("btn_pickup", ui_events.BUTTON_CLICKED, self.Pickup, self)
	self:AddCallback("btn_use_stove", ui_events.BUTTON_CLICKED, self.UseCook, self)
	self:AddCallback("btn_close", ui_events.BUTTON_CLICKED, self.Close, self)
end

function UICookStove:Initialize()
	local obj = get_object_by_id(self.obj_id)
	
	self.section 			= {} 
	self.section.placeable 	= obj:section() or "placeable_stove1"
	self.section.item	   	= SYS_GetParam(0, self.section.placeable, "item_section", "prop_stove2")

	utils_xml.set_icon(self.section.item, false, self.icon_temp, self.icon)

	self.btn_access_stash:Enable(SYS_GetParam(0, self.section.placeable, "integrated_storage") and true or false)
end

function UICookStove:TestAndShow(obj_id)
    self.obj_id = obj_id
	self:Initialize()
	self:ShowDialog(true)
	Register_UI("UICookStove","ui_furniture_stove")
end

function UICookStove:Update()
	CUIScriptWnd.Update(self)
end

function UICookStove:OnTrackButton()
end

function UICookStove:OnKeyboard(dik, keyboard_action)
	local res = CUIScriptWnd.OnKeyboard(self,dik,keyboard_action)
	if (res == false) then
		local bind = dik_to_bind(dik)
		if keyboard_action == ui_events.WINDOW_KEY_PRESSED then
		
			if dik == DIK_keys.DIK_ESCAPE then
				self:Close()
			end

		end
	end

	return res
end

function UICookStove:Close()
	if (self:IsShown()) then
		self:HideDialog()
	end
	
	Unregister_UI("UICookStove")
end

function start_dialog(obj_id)
	if (GUI == nil) then
		GUI = UICookStove()
	end
	GUI:TestAndShow(obj_id)
end