local MakePlayerCharacter = require "prefabs/player_common"

local assets = {
	Asset("ANIM", "anim/bearger_build.zip"),
	Asset("ANIM", "anim/bearger_basic.zip"),
	Asset("ANIM", "anim/bearger_actions.zip"),
	Asset("SOUND", "sound/bearger.fsb"),
	--Asset( "ANIM", "anim/ghost_waxwell_build.zip" ),
	Asset("ANIM", "anim/bearger_shiny_build_01.zip"),
	Asset("ANIM", "anim/bearger_shiny_build_02.zip"),
	Asset("ANIM", "anim/bearger_shiny_build_06.zip"),
}
local prefabs = 
{
	"groundpound_fx",
	"groundpoundring_fx",
	"bearger_fur",
	"furtuft",
	"collapse_small",
}
local start_inv = {
}

local function RestoreNightImmunity(inst)

	inst:DoTaskInTime(3, function(inst) 
	inst.Light:Enable(true)
	inst.Light:SetRadius(0)
	inst.Light:SetFalloff(.1)
	inst.Light:SetIntensity(.1)
	inst.Light:SetColour(245/255,40/255,0/255)
	end, inst)
end

------------------------------------------------------
----PvP Teleport----

local function getwildposition(inst)
    local ground = TheWorld
    local centers = {}
    for i, node in ipairs(ground.topology.nodes) do
        if ground.Map:IsPassableAtPoint(node.x, 0, node.y) then
            table.insert(centers, {x = node.x, z = node.y})
        end
    end
    if #centers > 0 then
        local pos = centers[math.random(#centers)]
        return Point(pos.x, 0, pos.z)
    else
        return inst:GetPosition()
    end
end

local function PvPTeleport(inst)
if inst.mobteleported == nil or inst.mobteleported == false then
	local ground = TheWorld
	local pt = getwildposition(inst)--Point(inst.Transform:GetWorldPosition())
      if pt.y <= .1 then
         pt.y = 0
         inst.Physics:Stop()
         inst.Physics:Teleport(pt.x,pt.y,pt.z)
		 inst.mobteleported = true
      end
	end
end

------------------------------------------------------
local function OnLoad(inst, data)
	if data ~= nil then
		inst.mobteleported = data.mobteleported or false
		inst.isshiny = data.isshiny or 0
	end
end

local function OnSave(inst, data)
	data.mobteleported = inst.mobteleported or false
	data.isshiny = inst.isshiny or 0
end

local function setSkin(inst)
	if not inst:HasTag("playerghost") then
		local mobskin = inst.components.skinner.skin_name
		local getshiny = (mobskin ~= inst.prefab and mobskin ~= "") and string.gsub(mobskin, inst.prefab.."_", "" ) --will return false if no skin is equipped.
		if SKIN_RARITY_COLORS.ModMade ~= nil then
			if getshiny ~= false then
				inst.isshiny = getshiny --used for other purposes
				inst.AnimState:SetBuild("bearger_shiny_build_0"..inst.isshiny)
			end		
		end
	end	
end
-------------------------------------------------------

local function setChar(inst)
	if not inst:HasTag("playerghost") then
    inst.AnimState:SetBank("bearger")
	inst.AnimState:SetBuild("bearger_build")
    inst:SetStateGraph("SGbearplayer")
	if inst.userid == "KU_4WvyrApB" then
		inst.isshiny = 2
		inst.AnimState:SetBuild("bearger_shiny_build_02")
	end
		
	end
	if MONSTERHUNGER == "Disable" then
		inst.components.hunger:Pause()
	end
	if MOBPVPMODE == "Enable" then
		PvPTeleport(inst)
	end
	inst.components.sanity.ignore = true	
end




SetSharedLootTable( 'bearplayer',
{
	{'meat',			 1.00},
	{'meat',			 1.00},
	{'meat',			 1.00},
	{'meat',			 1.00},
	{'meat',			 1.00},
	{'meat',			 1.00},
	{'meat',			 1.00},
	{'meat',			 1.00},
	{'bearger_fur',		 1.00},
})


--------GvG Mode------------
local GVG = require "pp_gvg"

local function FindFood(item)
	
end

local function HasFood(target)
	if target.components.inventory then
	
	end
end

local function OnAttacked_GVG(inst, data)
	if data.attacker and data.attacker:HasTag("epic") and HasFood(data.attacker) then
		inst.components.hunger:DoDelta(-20, false)
	end
end

local function SetGvGMode(inst)
	inst.components.health:SetMaxHealth(GVG.STATS.BEARGER_HEALTH)
	inst.components.hunger:SetMax(GVG.STATS.BEARGER_HUNGER)
	inst.components.hunger:SetRate(GVG.STATS.BEARGER_HUNGERRATE)
	
	inst.components.locomotor.runspeed = GVG.STATS.BEARGER_RUNSPEED
	inst.components.locomotor.walkspeed = GVG.STATS.BEARGER_WALKSPEED
	
end
----------------------------

local function oncollapse(inst, other)
	if other and other.components.workable ~= nil and other.components.workable.workleft > 0 then
		SpawnPrefab("collapse_small").Transform:SetPosition(other:GetPosition():Get())
		other.components.workable:Destroy(inst)
	end
end

local function oncollide(inst, other)
	if other == nil or not other:HasTag("tree") then
		return
	end
	local v1 = Vector3(inst.Physics:GetVelocity())
	if v1:LengthSq() < 1 then
		return
	end
	inst:DoTaskInTime(2*FRAMES, oncollapse, other)
end

local function WorkEntities(inst)
	local pt = inst:GetPosition()
	local ents = TheSim:FindEntities(pt.x, pt.y, pt.z, 5, nil, {"insect"})
	local heading_angle = -(inst.Transform:GetRotation())
	local dir = Vector3(math.cos(heading_angle*DEGREES),0, math.sin(heading_angle*DEGREES))

	for k,v in pairs(ents) do
		if v and v.components.workable then
			local hp = v:GetPosition()
			local offset = (hp - pt):GetNormalized()
			local dot = offset:Dot(dir)
			if dot > .3 then
				v.components.workable:Destroy(inst)
			end
		end
	end
end

local NIGHTVISION_COLOURCUBES =
{
    day = "images/colour_cubes/purple_moon_cc.tex",
    dusk = "images/colour_cubes/purple_moon_cc.tex",
    night = "images/colour_cubes/purple_moon_cc.tex",
    full_moon = "images/colour_cubes/purple_moon_cc.tex",

}

local function SetNightVision(inst, enable)
    if TheWorld.state.isnight or TheWorld:HasTag("cave") then
        inst.components.playervision:ForceNightVision(true)
        inst.components.playervision:SetCustomCCTable(NIGHTVISION_COLOURCUBES)
    else
        inst.components.playervision:ForceNightVision(false)
        inst.components.playervision:SetCustomCCTable(nil)
    end
end

local function RemovePenalty(inst)
	inst.components.health:DeltaPenalty(-1.00) --Removes health penalty when reviving
	inst.components.health:DoDelta(250, false) 
end

local function LaunchItem(inst, target, item)
	if item.Physics then

		local x, y, z = item:GetPosition():Get()
		y = .1
		item.Physics:Teleport(x,y,z)

		local hp = target:GetPosition()
		local pt = inst:GetPosition()
		local vel = (hp - pt):GetNormalized()
		local speed = 5 + (math.random() * 2)
		local angle = math.atan2(vel.z, vel.x) + (math.random() * 20 - 10) * DEGREES
		item.Physics:SetVel(math.cos(angle) * speed, 10, math.sin(angle) * speed)

	end
end

local function DontTriggerCreep(inst)
	inst.components.locomotor.walkspeed = (4)
    inst.components.locomotor.runspeed = (6)
	inst.components.locomotor.fasteronroad = false
	--inst.components.shedder:StartShedding(TUNING.BEARGER_SHED_INTERVAL)
	
end

local function OnGroundPound(inst)
	if math.random() < .2 then 
		inst.components.shedder:DoMultiShed(3, false) -- can't drop too many, or it'll be really easy to farm for thick furs
	end
end

local common_postinit = function(inst) 
	inst.soundsname = "wilson"

	inst.MiniMapEntity:SetIcon( "bearplayer.tex" )
	
	inst:DoTaskInTime(0, function()
   if ThePlayer then
      inst:EnableMovementPrediction(false)
   end
end)

inst:WatchWorldState( "isday", function() SetNightVision(inst) end)
  	inst:WatchWorldState( "isdusk", function() SetNightVision(inst) end)
  	inst:WatchWorldState( "isnight", function() SetNightVision(inst)  end)
	inst:WatchWorldState( "iscaveday", function() SetNightVision(inst) end)
  	inst:WatchWorldState( "iscavedusk", function() SetNightVision(inst) end)
  	inst:WatchWorldState( "iscavenight", function() SetNightVision(inst)  end)
	
	SetNightVision(inst)
end

local function SetStandState(inst, state)
    --"quad" or "bi" state
    inst.StandState = string.lower(state)
end

local function IsStandState(inst, state)
    return inst.StandState == string.lower(state)
end

local function OnDead(inst)
	TheWorld:PushEvent("beargerkilled", inst)
	inst.components.shedder:StopShedding()
end

local master_postinit = function(inst)
    inst.components.health:SetMaxHealth(TUNING.BEARGER_HEALTH)

	inst.OnSetSkin = function(skin_name)
	inst.AnimState:SetBank("bearger")
    inst.AnimState:SetBuild("bearger_build")
	inst:SetStateGraph("SGbearplayer")
	end
	inst:SetStateGraph("SGbearplayer")
	inst.components.talker:IgnoreAll()
	if MONSTERHUNGER == "Disable" then
		inst.components.hunger:Pause()
	end
	inst.components.hunger:SetMax(500)
	inst.components.hunger:SetRate(.15)
	inst.components.sanity.ignore = true
	inst.components.temperature:SetTemp(20)
	SetStandState(inst, "quad")--SetStandState(inst, "BI")
	inst.SetStandState = SetStandState
	inst.IsStandState = IsStandState
	inst.components.locomotor:SetShouldRun(true)
	inst.components.locomotor.fasteronroad = false
	
  	local light = inst.entity:AddLight()
  	inst.Light:Enable(true)
	inst.Light:SetRadius(0)
	inst.Light:SetFalloff(.1)
	inst.Light:SetIntensity(.1)
	inst.Light:SetColour(245/255,40/255,0/255)

	inst.components.talker.colour = Vector3(127/255, 0/255, 0/255)
	inst:ListenForEvent("respawnfromghost", RestoreNightImmunity)
	
	inst.ghostbuild = "ghost_monster_build"
    inst:DoTaskInTime(0, setChar)
	inst:DoTaskInTime(3, setSkin)
    inst:ListenForEvent("respawnfromghost", function()
		inst:DoTaskInTime(3, function()  inst.components.health:SetInvincible(false)
            if inst.components.playercontroller ~= nil then
				inst.components.playercontroller:EnableMapControls(true)
				inst.components.playercontroller:Enable(true)
			end
			inst.components.inventory:Show()
			inst:ShowActions(true)
            inst:ShowHUD(true)
            inst:SetCameraDistance()
			inst.sg:RemoveStateTag("busy")
            SerializeUserSession(inst) 
		end)
        inst:DoTaskInTime(5, setChar)
		inst:DoTaskInTime(5.1, setSkin)
		inst:DoTaskInTime(6, RemovePenalty)
		inst:DoTaskInTime(6, DontTriggerCreep)
		inst:DoTaskInTime(10, RestoreNightImmunity)
    end)
	
	--inst:ListenForEvent("equip", Equip)
	--inst:ListenForEvent("equip", SetWeaponDamage)
	--inst:ListenForEvent("unequip", UnEquip)
	--inst:ListenForEvent("onhitother", OnHitOther)
	
	inst.DynamicShadow:SetSize(6, 3.5)
	local s = 1
	inst.Transform:SetScale(s,s,s)

	MakeCharacterPhysics(inst, 1000, 0.5)


	inst.AnimState:SetBank("bearger")
    inst.AnimState:SetBuild("bearger_build")
	inst:SetStateGraph("SGbearplayer")
	
	inst.components.locomotor.walkspeed = (4)
	inst.components.locomotor.runspeed = (6)
	inst.components.locomotor:SetShouldRun(false)
	MakeLargeBurnableCharacter(inst, "swap_fire")
	--inst:AddComponent("sanityaura")
	--inst.components.sanityaura.aurafn = CalcSanityAura
	inst.components.health.destroytime = 5
	
	inst.components.combat:SetDefaultDamage(200)
	inst.components.combat.playerdamagepercent = MOBPVP
	
	inst.components.combat:SetRange(TUNING.BEARGER_ATTACK_RANGE, TUNING.BEARGER_MELEE_RANGE)
	inst.components.combat:SetAreaDamage(6, 0.8)
	inst.components.combat.hiteffectsymbol = "bearger_body"
	inst.components.combat:SetAttackPeriod(TUNING.BEARGER_ATTACK_PERIOD)
	inst.components.combat:SetHurtSound("dontstarve_DLC001/creatures/bearger/hurt")
	
	
	
	inst:AddComponent("shedder")
	inst.components.shedder.shedItemPrefab = "furtuft"
	inst.components.shedder.shedHeight = 6.5
	inst.components.shedder:StartShedding(TUNING.BEARGER_SHED_INTERVAL)
	
	inst:AddComponent("lootdropper")
	inst.components.lootdropper:SetChanceLootTable("bearplayer")
	
	inst:AddComponent("groundpounder")
	inst.components.groundpounder.destroyer = true
	inst.components.groundpounder.groundpounddamagemult = 1
	inst.components.groundpounder.damageRings = 2
	inst.components.groundpounder.destructionRings = 2
	inst.components.groundpounder.numRings = 3
	inst.components.groundpounder.groundpoundFn = OnGroundPound
	inst:AddComponent("timer")
	inst.components.eater:SetDiet({ FOODGROUP.BEARGER }, { FOODGROUP.BEARGER })
	inst.components.eater:SetAbsorptionModifiers(1,1.5,1.5)
	inst.components.eater.eatwholestack = true

	MakeHugeFreezableCharacter(inst, "bearger_body")
	
	inst.israged_special = true
	inst.specialatk = true
	inst.israged = false
	inst.mobteleported = false
	inst.isshiny = 0
	inst.mobsleep = true
	inst.mobplayer = true
	
	inst:AddTag("epic")
	inst:AddTag("monster")
	inst:AddTag("bearger") --might not even be needed since beargers fight each other.
	inst:AddTag("largecreature")
	
	inst.Physics:SetCollisionCallback(oncollide)
	
	inst.OnSave = OnSave
    inst.OnLoad = OnLoad
	
	if GVG_MODE ~= "Disable" then
		inst:DoTaskInTime(0, SetGvGMode)
	end
	
    return inst
	
end

--SkinRelated--
if SKIN_RARITY_COLORS.ModMade ~= nil then
AddModCharacterSkin("bearplayer", 1, {normal_skin = "bearger_shiny_build_01", ghost_skin = "ghost_monster_build"}, {"bearger_shiny_build_01", "ghost_monster_build"}, {"BEARPLAYER", "FORMAL"})
AddModCharacterSkin("bearplayer", 6, {normal_skin = "bearger_shiny_build_06", ghost_skin = "ghost_monster_build"}, {"bearger_shiny_build_06", "ghost_monster_build"}, {"BEARPLAYER", "6"})
end

return MakePlayerCharacter("bearplayer", prefabs, assets, common_postinit, master_postinit, start_inv)
