--[[
BY
 _____   _____   __   _  
|  _  \ /  _  \ |  \ | | 
| | | | | | | | |   \| | 
| | | | | | | | | |\   | 
| |_| | | |_| | | | \  | 
|_____/ \_____/ |_|  \_| 

]]

require "prefabutil"

local containers = require("containers")

local assets =
{
    Asset("ANIM", "anim/furnacepotions.zip"),
    Asset("ANIM", "anim/ui_potions_don.zip"),
	
	Asset("IMAGE", "images/minimap/donfurnacepotionsmap.tex"),
	Asset("ATLAS", "images/minimap/donfurnacepotionsmap.xml"),	
}

local prefabs =
{
}

local isvalidiingreitem = {
	"donpotionempty",
	"spidergland", 
	"ash",
	"cutgrass",
	"poop",
	"carrot", 
	"monstermeat", 
	"log", 
	"berries",
	"froglegs", 
	"green_cap", 
	"red_cap", 
	"butterfly",      
	"bee", 
	"honey", 
	"pinecone", 
	"petals",
	"berries_juicy",
}


local potionsrecipes = {
	{ prefabname = "donpotionlife", ingA = "spidergland", ingB = "ash", ingC = "cutgrass", ingD = "poop", cooktime = 22, },
		
	{ prefabname = "donpotionfood", ingA = "carrot", ingB = "monstermeat", ingC = "log", ingD = "berries", cooktime = 18, },
	{ prefabname = "donpotionfood", ingA = "carrot", ingB = "monstermeat", ingC = "log", ingD = "berries_juicy", cooktime = 18, }, --alternativo	
	
	{ prefabname = "donpotionsanity", ingA = "froglegs", ingB = "cutgrass", ingC = "green_cap", ingD = "red_cap", cooktime = 25, },
	
	{ prefabname = "donpotionlight", ingA = "red_cap", ingB = "froglegs", ingC = "berries", ingD = "ash", cooktime = 30, },
	{ prefabname = "donpotionlight", ingA = "red_cap", ingB = "froglegs", ingC = "berries_juicy", ingD = "ash", cooktime = 30, }, --alternativo
	
	{ prefabname = "donpotionmaxlife", ingA = "spidergland", ingB = "butterfly", ingC = "froglegs", ingD = "red_cap", cooktime = 35, },    
	{ prefabname = "donpotionpoisonous", ingA = "bee", ingB = "poop", ingC = "monstermeat", ingD = "cutgrass", cooktime = 23, },
	{ prefabname = "donpotionsleep", ingA = "honey", ingB = "froglegs", ingC = "pinecone", ingD = "petals", cooktime = 25, },
}


local function onhammered(inst, worker)

    if inst.components.container ~= nil then
        inst.components.container:DropEverything()
		inst.components.container:Close()
    end
	
	inst.Light:Enable(false)
	inst.inuse = false
	inst.cookpotiontime = 0
	
    inst.components.lootdropper:DropLoot()
    local fx = SpawnPrefab("collapse_small")
    fx.Transform:SetPosition(inst.Transform:GetWorldPosition())
    fx:SetMaterial("metal")
    inst:Remove()
end

local function onhit(inst, worker)		
	SpawnPrefab("donfx_small_puff_green").Transform:SetPosition(inst.Transform:GetWorldPosition())
end


local function onfar(inst)
    if inst.components.container ~= nil then
        inst.components.container:Close()
    end
end

local function onbuilt(inst)
    inst.AnimState:PlayAnimation("place")
    inst.AnimState:PushAnimation("idle")
    inst.SoundEmitter:PlaySound("dontstarve/common/cook_pot_craft")
end

local function cookpotion_done(inst)	
	SpawnPrefab("donfx_purple_smoke").Transform:SetPosition(inst.Transform:GetWorldPosition())	
	SpawnPrefab("donfx_shadow_despawn_purple").Transform:SetPosition(inst.Transform:GetWorldPosition())	
	
	inst.components.container:DestroyContents()
	
	local potionitem = SpawnPrefab(inst.cookpotionprefab)
	
    local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0,1,0)
    potionitem.Transform:SetPosition(pt:Get())
    local down = TheCamera:GetDownVec()
    local angle = math.atan2(down.z, down.x) + (math.random()*60)*DEGREES
    local sp = 3 + math.random()
    potionitem.Physics:SetVel(sp*math.cos(angle), math.random()*2+8, sp*math.sin(angle))
	
	
	inst.AnimState:PlayAnimation("idle", true)
	inst.SoundEmitter:KillSound("snd")
    inst.SoundEmitter:PlaySound("dontstarve/common/cookingpot_finish")
	inst.Light:Enable(false)
	inst.inuse = false
	inst.cookpotiontime = 0	
	inst.cookpotionprefab = ""
	inst.components.container.canbeopened = true
end

local function pufffx(inst)
    if inst.inuse == true then
        SpawnPrefab("donfx_small_puff_green").Transform:SetPosition(inst.Transform:GetWorldPosition())
		inst:DoTaskInTime(3 + math.random() * 5, pufffx)
    end  
end

local function cookpotion_start(inst, timetocook, recipeprefab)	
	inst.cookpotiontime = timetocook
	inst.cookpotionprefab = recipeprefab
	
	local randanim = math.random(4)
	if randanim <= 0 then randanim = 1 end
	inst.AnimState:PlayAnimation(("inuse_"..randanim), true)
	
	inst.SoundEmitter:KillSound("snd")
    inst.SoundEmitter:PlaySound("dontstarve/common/cookingpot_rattle", "snd")
	inst.Light:Enable(true)
	inst.inuse = true
	inst.components.container:Close()	
	inst.components.container.canbeopened = false

	inst:DoTaskInTime(inst.cookpotiontime, cookpotion_done)
	pufffx(inst)	
end


local function FindItemDon(inst, prefabname)
	return inst.components.container:Has(prefabname, 1)
end

local function cookpotion_CheckRecipes(inst)
inst.components.container:Close()

local selectedrecipepotion = ""
local selectedrecipetime = 0
local isok = false


	for k,v in ipairs(potionsrecipes) do
		if v.prefabname ~= nil and isok == false then
			if FindItemDon(inst, "donpotionempty") and FindItemDon(inst, v.ingA) and FindItemDon(inst, v.ingB) and FindItemDon(inst, v.ingC) and FindItemDon(inst, v.ingD) then
				selectedrecipepotion = v.prefabname
				selectedrecipetime = v.cooktime
				isok = true
			end
		end
	end

	if isok == true and selectedrecipepotion ~= nil and selectedrecipetime > 0 then
		cookpotion_start(inst, selectedrecipetime, selectedrecipepotion)
	else
		cookpotion_start(inst, 12, "donpotionstrange")
	end

end


local function onopen(inst)
	if inst.inuse == false then
		inst.SoundEmitter:PlaySound("dontstarve/common/cookingpot", "snd")
	end
	
	if inst.inuse == true then
		inst.components.container:Close()
	end
end

local function onclose(inst)
    if inst.inuse == false then
		inst.AnimState:PlayAnimation("idle")
		inst.SoundEmitter:KillSound("snd")
		inst.Light:Enable(false)
    end
end

local function onsave(inst, data)
	data.inuse = inst.inuse
	data.cookpotiontime = inst.cookpotiontime
	data.cookpotionprefab = inst.cookpotionprefab
end


local function onload(inst, data)
	inst.Light:Enable(false)
	
	if data ~= nil and inst.inuse ~= nil and data.cookpotiontime ~= nil and data.cookpotionprefab ~= nil then
		inst.inuse = data.inuse
		inst.cookpotiontime = data.cookpotiontime
		inst.cookpotionprefab = data.cookpotionprefab
	end
	
	if inst.inuse == true and inst.cookpotiontime ~= nil and inst.cookpotionprefab ~= nil then
		if inst.cookpotiontime > 0 then
				cookpotion_start(inst, inst.cookpotiontime, inst.cookpotionprefab)
			else
				inst.inuse = false
				inst.cookpotiontime = 0
				inst.cookpotionprefab = ""
				inst.components.container:DropEverything()
				inst.components.container:Close()
		end
	end
	
end

local function CheckFurnaceitens(inst)
	if inst.components.container:GetItemInSlot(1).prefab == "donpotionempty" and 
		inst.components.container:GetItemInSlot(2).prefab ~= "donpotionempty" and 
		inst.components.container:GetItemInSlot(3).prefab ~= "donpotionempty" and
		inst.components.container:GetItemInSlot(4).prefab ~= "donpotionempty" and
		inst.components.container:GetItemInSlot(5).prefab ~= "donpotionempty" then
			cookpotion_CheckRecipes(inst)
		end

		if inst.components.container:GetItemInSlot(1).prefab ~= "donpotionempty" then
			inst.components.container:DropItemBySlot(1)
		end

		for i = 2, 5 do
			if inst.components.container:GetItemInSlot(i).prefab == "donpotionempty" then
				inst.components.container:DropItemBySlot(i)
			end
		end	
end


local function oncookmagic(inst)
	if inst.components.container ~= nil then
		CheckFurnaceitens(inst)
	else
		print("erro grave!")	
	end			
end


local ui_potions_make =
{
    widget =
    {
        slotpos =
        {
			Vector3(6.5, 134, 0),
			
            Vector3(-37.5, 27, 0), 
            Vector3(37.5, 27, 0),
            Vector3(-37.5, -46, 0), 
            Vector3(37.5, -46, 0),
        },
        animbank = "ui_potions_don",
        animbuild = "ui_potions_don",
        pos = Vector3(0, 180, 0),
        side_align_tip = 160,

		buttoninfo  =
		{
			text = STRINGS.DONBTN_BEWITCH,
			position = Vector3(0, -115, 0),
			
			fn = function(inst)--clicou no botão			
				if inst.components.container ~= nil then
					BufferedAction(inst.components.container.opener, inst, ACTIONS.CONTAINERDON):Do()
				elseif inst.replica.container ~= nil and not inst.replica.container:IsBusy() then
					SendRPCToServer(RPC.DoWidgetButtonAction, ACTIONS.CONTAINERDON.code, inst, ACTIONS.CONTAINERDON.mod_name)
				end		
			end,

			validfn = function(inst)--checar se pode continuar
				return inst.replica.container ~= nil and inst.replica.container:IsFull()
			end,
			
		}
    },
	
	type = "cooker",
	acceptsstacks = false,
	issidewidget = false,  

	itemtestfn = function(container, item, slot)
	
		for i, v in ipairs(isvalidiingreitem) do
			if (v == item.prefab) then
				return true
			end	
		end	

		return false
		
	end,
}

local oldwidgetsetup = containers.widgetsetup
function containers.widgetsetup(container, prefab, data, ...)
	if container.inst.prefab == "donfurnace_potions" or prefab == "donfurnace_potions" then
        for k, v in pairs(ui_potions_make) do
            container[k] = v
        end
        container:SetNumSlots(container.widget.slotpos ~= nil and #container.widget.slotpos or 0)
        return
	end
	
    return oldwidgetsetup(container, prefab, data, ...)
end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddSoundEmitter()
    inst.entity:AddMiniMapEntity()
    inst.entity:AddLight()
    inst.entity:AddNetwork()

    MakeObstaclePhysics(inst, .5)

    inst.MiniMapEntity:SetIcon("donfurnacepotionsmap.tex")

    inst.Light:Enable(false)
    inst.Light:SetRadius(.6)
    inst.Light:SetFalloff(1)
    inst.Light:SetIntensity(.5)
    inst.Light:SetColour(235/255,62/255,12/255)

    inst:AddTag("structure")

    inst.AnimState:SetBank("furnacepotions")
    inst.AnimState:SetBuild("furnacepotions")
    inst.AnimState:PlayAnimation("idle")
	
    MakeSnowCoveredPristine(inst)

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
		inst.OnEntityReplicated = function(inst) inst.replica.container:WidgetSetup("donfurnace_potions", ui_potions_make) end	
        return inst
    end

	inst.inuse = false
	inst.cookpotiontime = 0
	inst.cookpotionprefab = ""

    inst:AddComponent("playerprox")
    inst.components.playerprox:SetDist(3,5)
    inst.components.playerprox:SetOnPlayerFar(onfar)

	inst:AddComponent("container_don")
	inst.components.container_don.onmagiccookfn = oncookmagic
	
	inst:AddComponent("container")
	inst.components.container:WidgetSetup("donfurnace_potions", ui_potions_make)
	inst.components.container.onopenfn = onopen
	inst.components.container.onclosefn = onclose
	inst:ListenForEvent("itemget", function(inst, data)
		if inst.components.container ~= nil then
			inst.components.container:Open(ThePlayer)
		end
	end)
	inst.components.container.canbeopened = true
			

    inst:AddComponent("lootdropper")
    inst:AddComponent("workable")
    inst.components.workable:SetWorkAction(ACTIONS.HAMMER)
    inst.components.workable:SetWorkLeft(4)
    inst.components.workable:SetOnFinishCallback(onhammered)
    inst.components.workable:SetOnWorkCallback(onhit)

    MakeSnowCovered(inst)
    inst:ListenForEvent("onbuilt", onbuilt)

    inst.OnSave = onsave 
    inst.OnLoad = onload

    return inst
end


return Prefab("donfurnace_potions", fn, assets, prefabs),
    MakePlacer("donfurnace_potions_placer", "furnacepotions", "furnacepotions", "idle")
