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

]]

local db_chopslvl = {
	{tooldamage = 5, toolefficiency = 2, tooluses = 60},
	{tooldamage = 7, toolefficiency = 2, tooluses = 60},
	{tooldamage = 12, toolefficiency = 3, tooluses = 68}
}

local db_minelvl = {
	{tooldamage = 5, toolefficiency = 1.8, tooluses = 38},
	{tooldamage = 7, toolefficiency = 1.8, tooluses = 34},
	{tooldamage = 12, toolefficiency = 3.2, tooluses = 23}
}

local db_spearlvl = {
	{tooldamage = 7, toolefficiency = 0, tooluses = 145},
	{tooldamage = 7, toolefficiency = 0, tooluses = 145},
	{tooldamage = 16, toolefficiency = 0, tooluses = 100}
}



local function tools_don_night_trail_fx(inst)
    local owner = inst.components.inventoryitem:GetGrandOwner() or inst
    if not owner.entity:IsVisible() then
        return
    end

    local x, y, z = owner.Transform:GetWorldPosition()
    if owner.sg ~= nil and owner.sg:HasStateTag("moving") then
        local theta = -owner.Transform:GetRotation() * DEGREES
        local speed = owner.components.locomotor:GetRunSpeed() * .1
        x = x + speed * math.cos(theta)
        z = z + speed * math.sin(theta)
    end
    local mounted = owner.components.rider ~= nil and owner.components.rider:IsRiding()
    local map = TheWorld.Map
    local offset = FindValidPositionByFan(
        math.random() * 2 * PI,
        (mounted and 1 or .5) + math.random() * .5,
        4,
        function(offset)
            local pt = Vector3(x + offset.x, 0, z + offset.z)
            return map:IsPassableAtPoint(pt:Get())
                and not map:IsPointNearHole(pt)
                and #TheSim:FindEntities(pt.x, 0, pt.z, .7, { "shadowtrail" }) <= 0
        end
    )

    if offset ~= nil then
        local fxwalk = SpawnPrefab(inst.fxgroundname)
        fxwalk.Transform:SetPosition(x + offset.x, 0, z + offset.z)
    end
end


local function onequip(inst, owner)
	inst.counthisttopower = 0
    owner.AnimState:OverrideSymbol("swap_object", inst.toolanimswap, inst.toolanimswap)
    owner.AnimState:Show("ARM_carry")
    owner.AnimState:Hide("ARM_normal")

	if inst._trailtask == nil and inst.usefxwpground == true and inst.fxgroundname ~= nil then
        inst._trailtask = inst:DoPeriodicTask(6 * FRAMES, tools_don_night_trail_fx, 2 * FRAMES)
    end
end

local function onunequip(inst, owner)
    owner.AnimState:Hide("ARM_carry")
    owner.AnimState:Show("ARM_normal")

	if inst._trailtask ~= nil then
        inst._trailtask:Cancel()
        inst._trailtask = nil
    end

end


local function onattack_melee(inst, attacker, target, skipsanity)
	inst.counthisttopower = inst.counthisttopower + 1

	if inst.counthisttopower >= 3 then
	--print("power: "..inst.powername.." | hits: "..inst.counthisttopower)


	if not skipsanity and attacker ~= nil and attacker.components.sanity ~= nil then
        attacker.components.sanity:DoDelta(-3)
    end

    if not target:IsValid() then
        return
    end


	if inst.powername == "ice" then

	if target.components.burnable ~= nil then
        if target.components.burnable:IsBurning() then
            target.components.burnable:Extinguish()
        elseif target.components.burnable:IsSmoldering() then
            target.components.burnable:SmotherSmolder()
        end
    end

    if target.components.freezable ~= nil then
        --target.components.freezable:AddColdness(3)
        target.components.freezable:Freeze()
        target.components.freezable:SpawnShatterFX()
    end

	elseif inst.powername == "fire" then

		attacker.SoundEmitter:PlaySound("dontstarve/wilson/fireball_explo")
		if target.components.burnable ~= nil and not target.components.burnable:IsBurning() then
			if target.components.freezable ~= nil and target.components.freezable:IsFrozen() then
				target.components.freezable:Unfreeze()
			elseif target.components.fueled == nil then
				target.components.burnable:Ignite(true)
			elseif target.components.fueled.fueltype == FUELTYPE.BURNABLE
				or target.components.fueled.secondaryfueltype == FUELTYPE.BURNABLE then
				local fuel = SpawnPrefab("cutgrass")
				if fuel ~= nil then
					if fuel.components.fuel ~= nil and
						fuel.components.fuel.fueltype == FUELTYPE.BURNABLE then
						target.components.fueled:TakeFuelItem(fuel)
					else
						fuel:Remove()
					end
				end
			end
		end

		if target.components.freezable ~= nil then
			target.components.freezable:AddColdness(-1)
			if target.components.freezable:IsFrozen() then
				target.components.freezable:Unfreeze()
			end
		end
	end

	inst.counthisttopower = 0
	end

end


local function MakeDonTool(prefabname, animground, animswap, usetools, toollvl, powername, usefxwpground, fxgroundname)

local assets =
{
	Asset("ANIM", "anim/tools/"..animground..".zip"),
	Asset("ANIM", "anim/tools/"..animswap..".zip"),
}

local function fn()
    local inst = CreateEntity()

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

    MakeInventoryPhysics(inst)

	inst.toolanimswap = animswap
	inst.usefxwpground = usefxwpground
	inst.fxgroundname = fxgroundname
	inst.powername = powername

	inst.counthisttopower = 0

	inst.Light:SetIntensity(.1)
	inst.Light:SetRadius(.2)
	inst.Light:SetFalloff(.6)
	inst.Light:SetColour(15/255, 85/255, 235/255)
	inst.Light:Enable(true)
	inst.AnimState:SetBloomEffectHandle("shaders/anim.ksh")

    inst.AnimState:SetBank(animground)
    inst.AnimState:SetBuild(animground)
    inst.AnimState:PlayAnimation("idle")

    inst:AddTag("sharp")
    inst:AddTag("pointy")

    inst.entity:SetPristine()

    if not TheWorld.ismastersim then
        return inst
    end

	inst:AddComponent("weapon")
	inst:AddComponent("tool")
	inst:AddComponent("finiteuses")

	local tooldamage = 0
	local toolefficiency = 0
	local tooluses = 0
	local selectedtoollvl = nil

	if usetools == "chop" then
		selectedtoollvl = db_chopslvl[toollvl]
		inst.components.weapon:SetDamage(TUNING.AXE_DAMAGE+selectedtoollvl.tooldamage)
		inst.components.tool:SetAction(ACTIONS.CHOP, selectedtoollvl.toolefficiency)
		inst.components.finiteuses:SetMaxUses(selectedtoollvl.tooluses)
		inst.components.finiteuses:SetUses(selectedtoollvl.tooluses)
		inst.components.finiteuses:SetConsumption(ACTIONS.CHOP, 1/selectedtoollvl.toolefficiency)

	elseif usetools == "mine" then
		selectedtoollvl = db_minelvl[toollvl]
		inst.components.weapon:SetDamage(TUNING.PICK_DAMAGE+selectedtoollvl.tooldamage)
		inst.components.tool:SetAction(ACTIONS.MINE, selectedtoollvl.toolefficiency)
		inst.components.finiteuses:SetMaxUses(selectedtoollvl.tooluses)
		inst.components.finiteuses:SetUses(selectedtoollvl.tooluses)
		inst.components.finiteuses:SetConsumption(ACTIONS.MINE, 1)

	elseif usetools == "spear" then
		selectedtoollvl = db_spearlvl[toollvl]

		inst:AddTag("sharp")
		inst:AddTag("pointy")
		inst.components.weapon:SetDamage(TUNING.SPEAR_DAMAGE+selectedtoollvl.tooldamage)
		inst.components.finiteuses:SetMaxUses(selectedtoollvl.tooluses)
		inst.components.finiteuses:SetUses(selectedtoollvl.tooluses)
	end


	inst.components.weapon:SetOnAttack(onattack_melee)


	--print("Tool -> Lvl: "..toollvl.." / Damage: "..selectedtoollvl.tooldamage.." / Effic.: "..selectedtoollvl.toolefficiency.." / Uses: "..selectedtoollvl.tooluses)


	inst.components.finiteuses:SetOnFinished(inst.Remove)


    inst:AddComponent("inspectable")

    inst:AddComponent("inventoryitem")
	inst.components.inventoryitem.imagename = (prefabname.."icon")
	inst.components.inventoryitem.atlasname = ("images/inventoryimages/"..prefabname.."icon.xml")

    inst:AddComponent("equippable")
    inst.components.equippable:SetOnEquip(onequip)
    inst.components.equippable:SetOnUnequip(onunequip)

	if toollvl >= 3 then
		inst:AddTag("shadow")
		inst.components.equippable.dapperness = TUNING.CRAZINESS_MED
	end

    MakeHauntableLaunch(inst)

        return inst
    end

    return Prefab(prefabname, fn, assets)
end

return MakeDonTool("donrpgtools_axe_blue", "axe_don_blue", "swap_axe_don_blue", "chop", 1, "ice", true, "weapondon_shadow_fx_blue"),
       MakeDonTool("donrpgtools_axe_red", "axe_don_red", "swap_axe_don_red", "chop", 2, "fire", true, "weapondon_shadow_fx_red"),
       MakeDonTool("donrpgtools_axe_purple", "axe_don_purple", "swap_axe_don_purple", "chop", 3, "none", true, "weapondon_shadow_fx_purple_low"),

       MakeDonTool("donrpgtools_pickaxe_blue", "pickaxe_don_blue", "swap_pickaxe_don_blue", "mine", 1, "ice", true, "weapondon_shadow_fx_blue"),
       MakeDonTool("donrpgtools_pickaxe_red", "pickaxe_don_red", "swap_pickaxe_don_red", "mine", 2, "fire", true, "weapondon_shadow_fx_red"),
       MakeDonTool("donrpgtools_pickaxe_purple", "pickaxe_don_purple", "swap_pickaxe_don_purple", "mine", 3, "none", true, "weapondon_shadow_fx_purple_low"),

	   MakeDonTool("donrpgtools_spear_blue", "spear_don_blue", "swap_spear_don_blue", "spear", 1, "ice", true, "weapondon_shadow_fx_blue"),
	   MakeDonTool("donrpgtools_spear_red", "spear_don_red", "swap_spear_don_red", "spear", 2, "fire", true, "weapondon_shadow_fx_red"),
	   MakeDonTool("donrpgtools_spear_purple", "spear_don_purple", "swap_spear_don_purple", "spear", 3, "none", true, "weapondon_shadow_fx_purple_low")
