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

]]

require "prefabutil"

local MAXUSE_CANDYMACHINE = 25

local assets =
{
    Asset("ANIM", "anim/candy_machine.zip"),

	Asset("IMAGE", "images/minimap/doncandymachine_icon.tex"),
	Asset("ATLAS", "images/minimap/doncandymachine_icon.xml"),
	
	Asset("SOUNDPACKAGE", "sound/doncandymachine.fev"),
	Asset("SOUND", "sound/doncandymachine_bank00.fsb"),
}

local prefabs =
{
    "collapse_small",
}


local candyitem =
{	
	"winter_food1",
	"winter_food2",
	"winter_food3",
	"winter_food4",
	"winter_food5",
	"winter_food6",
	"winter_food7",
	"winter_food8",
	"winter_food9",	
	"halloweencandy_1",
	"halloweencandy_2",
	"halloweencandy_3",
	"halloweencandy_4",
	"halloweencandy_5",
	"halloweencandy_6",
	"halloweencandy_7",
	"halloweencandy_8",
	"halloweencandy_9",
	"halloweencandy_10",
	"halloweencandy_11",
}

local normalitem =
{
	"rocks",
	"twigs",
	"charcoal",
	"nitre",
}


local function SparksFX(inst)	
	inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_jelly_fish_electric_land_1")
	SpawnPrefab("lightning_rod_fx").Transform:SetPosition(inst.Transform:GetWorldPosition())
end

local function DestroyMachineObj(inst)
	inst.components.lootdropper:DropLoot()
    local x, y, z = inst.Transform:GetWorldPosition()
    local fx = SpawnPrefab("collapse_small")
    fx.Transform:SetPosition(x, y, z)
    fx:SetMaterial("stone")
    inst:Remove()
end

local function onhammered(inst, worker)
	if inst.components.burnable ~= nil and inst.components.burnable:IsBurning() then 
        inst.components.burnable:Extinguish()
    end
	
	SparksFX(inst)
	
    DestroyMachineObj(inst)
end

local function onhit(inst, worker)
	SparksFX(inst)	

    inst.AnimState:PlayAnimation("hit")
    inst.AnimState:PushAnimation("idle")
end

local function onbuilt(inst)
	inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_SlotMachine_JumpUp_V2")
    inst.AnimState:PlayAnimation("ok")
    inst.AnimState:PushAnimation("idle", false)
end

	
local function MachineDeath(inst)		
	inst.inwork = false	
	inst.sysfailure = true		
	inst.Light:Enable(false)
	inst.components.talker:Say("System Failure!")
	inst.components.talker.colour = Vector3(209/255, 102/255, 100/255, 1)
	
		SparksFX(inst)
	
	inst.AnimState:PlayAnimation("hit")	
	inst.AnimState:PushAnimation("burnt")
	
	inst:DoTaskInTime(0.5, function() 
		SparksFX(inst)
	end)
	
	inst:DoTaskInTime(1, function() 
		SparksFX(inst)
	end)
	
	inst:DoTaskInTime(3.2, function() 
		SparksFX(inst)
		DestroyMachineObj(inst)
		inst:Remove()
	end)
	
end

local function SpawnReward(inst, itemname, machineresult)	
	local machinereward = SpawnPrefab(itemname)
	
	if inst.iswonderfulcandys == true and machineresult == "good" then
		machinereward.components.edible.hungervalue = (machinereward.components.edible.hungervalue + math.random(15))
		machinereward.components.edible.sanityvalue = (machinereward.components.edible.sanityvalue + math.random(17))	
	end
	
    local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0,1,0)
    machinereward.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()
    machinereward.Physics:SetVel(sp*math.cos(angle), math.random()*2+8, sp*math.sin(angle))
	
	inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_slot_machine_reward_1")
	
	SpawnPrefab("collapse_small").Transform:SetPosition(inst.Transform:GetWorldPosition())	
	
	inst:DoTaskInTime(1.3, function() 
		if inst.sysfailure == false then
			inst.components.talker:Say("")
		end
	end)
	
	
	if inst.isinfiniteuse == false then
		if inst.countuses >= MAXUSE_CANDYMACHINE then
		inst.inwork = false	
		inst.sysfailure = true
			inst:DoTaskInTime(1, function() 
				MachineDeath(inst);
			end)		
		end
	end
	
	
end


local function ShouldAcceptItem(inst, item)
	if item.prefab == inst.currentcoinmachine and inst.inwork == false and inst.sysfailure == false then
		return true
	else
		return false
	end
end

local function OnGetItemFromPlayer(inst, giver, item)
	inst.inwork = true
	
	if inst.isinfiniteuse == false then
		inst.countuses = inst.countuses + 1
	end
	
	inst.components.talker:Say("")

	inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_SlotMachine_PullLever_V3")
	
	inst:DoTaskInTime(0.4, function() 
		inst.Light:Enable(true)
		
		inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_SlotMachine_Spin_lp", "loopsounddoncm")
		inst.AnimState:PlayAnimation("use")

		local randnumb = math.random(20)
		local randresult = ""
		local selecteditem = ""
		
		if randnumb % 2 == 0 then
			randresult = "good"
			selecteditem = candyitem[math.random(table.getn(candyitem))]
		else
			randresult = "bad"
			selecteditem = normalitem[math.random(table.getn(normalitem))]
		end
		
		
			inst.AnimState:PushAnimation(randresult)
			

		inst:DoTaskInTime(4, function()		

			inst.SoundEmitter:KillSound("loopsounddoncm")

			if randresult == "good" then	
				inst.components.talker.colour = Vector3(183/255, 100/255, 209/255, 1)
				inst.components.talker:Say("Sweet!")
				inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_SlotMachine_GoodResult_V3")
			else
				inst.components.talker.colour = Vector3(209/255, 102/255, 100/255, 1)
				inst.components.talker:Say("Bad Luck... Ha Ha Ha!")
				inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_SlotMachine_BadResult_V4")
			end
			
			inst.AnimState:PlayAnimation("idle")
			
			SpawnReward(inst, selecteditem, randresult)
			
			inst.inwork = false		
			inst.Light:Enable(false)				
		end)
		
	end)
end

local function OnRefuseItem(inst, item)
	if inst.inwork == false and inst.sysfailure == false then
		inst.SoundEmitter:PlaySound("doncandymachine/doncandymachine/DSS_SlotMachine_CoinInSlot_03_V2")
		inst.AnimState:PlayAnimation("hit")
		inst.AnimState:PushAnimation("idle")
		
		if inst.currentcoinmachine ~= "doncandycoin" then
		inst.components.talker:Say("Sorry, "..inst.currentcoinmachine.." only!")
		else
		inst.components.talker:Say("Sorry, coins only!")
		end

		inst.components.talker.colour = Vector3(209/255, 102/255, 100/255, 1)
	
		inst:DoTaskInTime(0.6, function() 
		inst.components.talker:Say("")
		end)
		
	end
end


local function onsave(inst, data)
    if (inst.components.burnable ~= nil and inst.components.burnable:IsBurning()) then
        data.burnt = true
    end
	
	data.countuses = inst.countuses
end

local function onload(inst, data)
	
    if data ~= nil and data.burnt then
        inst.components.burnable.onburnt(inst)
    end

	if data ~= nil and data.countuses then
		inst.countuses = data.countuses
	end
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, 0.8, 1.2)

    inst.MiniMapEntity:SetIcon("doncandymachine_icon.tex")
    inst.MiniMapEntity:SetPriority(-1)

    inst.AnimState:SetBank("candy_machine")
    inst.AnimState:SetBuild("candy_machine")
    inst.AnimState:PlayAnimation("idle", false)

    inst:AddTag("structure")

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

	inst:AddComponent("inspectable")

    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)

	inst.Light:SetIntensity(.6)
    inst.Light:SetRadius(.8)
    inst.Light:SetFalloff(.6)
    inst.Light:SetColour(171/255, 100/255, 209/255)
	inst.Light:Enable(false)
	
	inst:AddComponent("talker")
    inst.components.talker.fontsize = 24
	inst.components.talker.font = TALKINGFONT
	inst.components.talker.offset = Vector3(0,-700,0)
	
	inst:AddComponent("trader")
    inst.components.trader:SetAcceptTest(ShouldAcceptItem)
    inst.components.trader.onaccept = OnGetItemFromPlayer
    inst.components.trader.onrefuse = OnRefuseItem
    inst.components.trader.deleteitemonaccept = true
	
	
	local inwork = false
	inst.inwork = false
	
	local sysfailure = false
	inst.sysfailure = false
	
	local isinfiniteuse = false
	inst.isinfiniteuse = false
	
	local iswonderfulcandys = false
	inst.iswonderfulcandys = false	
	
	local currentcoinmachine = "doncandycoin"
	inst.currentcoinmachine = "doncandycoin"
	
	local countuses = 0
	inst.countuses = 0
	
    inst:ListenForEvent("onbuilt", onbuilt)
	
	MakeSmallBurnable(inst, nil, nil, true)
    MakeSmallPropagator(inst)
	
	inst.OnSave = onsave
    inst.OnLoad = onload

    return inst
end

STRINGS.DONCANDYMACHINE = "Candy Machine"
STRINGS.NAMES.DONCANDYMACHINE = "Candy Machine"
STRINGS.RECIPE_DESC.DONCANDYMACHINE = "A very entertaining candy machine."
STRINGS.CHARACTERS.GENERIC.DESCRIBE.DONCANDYMACHINE = "Trick or Treat..."

return Prefab("doncandymachine", fn, assets, prefabs),
    MakePlacer("doncandymachine_placer", "candy_machine", "candy_machine", "idle")
