local MakePlayerCharacter = require "prefabs/player_common"

--Notes--
--I'm gonna completely rewrite tiredness. Having to try to make it a work-around with sanity was a BAD idea. Going to need to make a new meter for it.

local assets = 
{
	Asset("ANIM", "anim/hound_basic.zip"),
    Asset("ANIM", "anim/houndplayer.zip"),
	Asset("ANIM", "anim/hound.zip"),
	Asset("ANIM", "anim/hounddarkplayer.zip"),
    Asset("SOUND", "sound/hound.fsb"),
	--Asset("ANIM", "anim/ghost_waxwell_build.zip"),
}
local prefabs = {
	
    }
	
local start_inv = {
	"houndstooth",
	"houndstooth",
	--"nightmarefuel",
}

local start_inv2 = 
{
	"houndstooth",
	"houndstooth",
	"houndhome",
}

if MOBHOUSE == "Enable1" or MOBHOUSE == "Enable3" then
	start_inv = start_inv2
end

--local REGEN_RATE_HEALTH = 0.25

SetSharedLootTable( 'hounddarkplayer',
{
	--{'purplegem',			 0.20},
	--{'nightmarefuel',			 0.50},
	--{'nightmarefuel',			 0.50},
	--{'monstermeat',			 1.00},
	{'monstermeat',			 1.00},
	--{'monstermeat',			 1.00},
	--{'monstermeat',			 1.00},
	--{'houndstooth',			 0.50},
	{'houndstooth',			 0.50},
	--{'houndstooth',			 0.50},
	--{'bluegem',			 	 0.25},
	
})

local function Equip(inst)
   -- local hands = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HANDS) or nil
	local head = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD) or nil
	local body = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.BODY) or nil
	if head ~= nil or body ~= nil then
		inst.components.sanity.dapperness = -0.1
	end		
end

local function onattacked(inst, data) --Get friends to come help you out when you're in trouble!
    if data.attacker then
        inst.components.combat:SetTarget(data.attacker)
        inst.components.combat:ShareTarget(data.attacker, 40, function(dude) return dude:HasTag("hound") and not dude.components.health:IsDead() end, 3)
    end
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 RestoreNightvision(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

local NIGHTVISION_COLOURCUBES =
{
    day = "images/colour_cubes/day05_cc.tex",
    dusk = "images/colour_cubes/dusk03_cc.tex",
    night = "images/colour_cubes/mole_vision_on_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 HealthDrain(inst)
if inst.istired == true and not inst.sg:HasStateTag("sleeping") then
	inst.components.health:DoDelta(-3, false)
	end
end



local function TiredPenalties(inst)
local sanitypercent = inst.components.sanity:GetPercent()
if sanitypercent > 0.5 then
	inst.components.combat:SetDefaultDamage(30*2)	--defualt values
	inst.components.locomotor.runspeed = (TUNING.HOUND_SPEED*1)
elseif sanitypercent <= 0.5 then
	inst.components.combat:SetDefaultDamage(30*1.5)	--30% less speed, 25% less damage values
	inst.components.locomotor.runspeed = (TUNING.HOUND_SPEED/1.3)
elseif sanitypercent <= 0.3 then
	inst.components.combat:SetDefaultDamage(30)	--half values
	inst.components.locomotor.runspeed = (TUNING.HOUND_SPEED/2)
	end
end


local function IsTired(inst)
if inst.components.sanity.current <= 35 and inst.istired == false then
	inst.istired = true
	inst:DoPeriodicTask(2, HealthDrain)
elseif inst.components.sanity.current > 35 and inst.istired == true then
	inst.istired = false
end
end

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

local function OnSave(inst, data) --don't save because the sanity checker will set it anyways.
	--data.istired = inst.istired or false
	data.mobteleported = inst.mobteleported or false
end

local function setChar(inst)
	if not inst:HasTag("playerghost") then
    inst.AnimState:SetBank("hound")
    inst.AnimState:SetBuild("hounddarkplayer")
    inst:SetStateGraph("SGhounddarkplayer")
	end
	if MONSTERHUNGER == "Disable" then
		inst.components.hunger:Pause()
	end
	if MONSTERSANITY == "Disable" then
		inst.components.sanity.ignore = true
	end
	if MOBPVPMODE == "Enable" then
		PvPTeleport(inst)
	end
	inst.components.locomotor.runspeed = (TUNING.HOUND_SPEED)
	inst.components.locomotor.fasteronroad = false
	TiredPenalties(inst)
	IsTired(inst)
end

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

	inst.MiniMapEntity:SetIcon( "hounddarkplayer.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)
	
	--inst:WatchWorldState("isday", function(inst, val)    
	--local mult = val and 1 or -2    
	--inst.components.sanity.dapperness = mult*TUNING.SANITY_NIGHT_LIGHT end)
end

local function RemovePenalty(inst)
	inst.components.health:DeltaPenalty(-1.00) --Removes health penalty when reviving
	--inst.components.health:DoDelta(20000, false) --Returns heals to max health upon reviving
end

local function DontTriggerCreep(inst)
    inst.components.locomotor.runspeed = (TUNING.HOUND_SPEED)
end


local master_postinit = function(inst)
    inst.components.health:SetMaxHealth(250)
	inst.components.hunger:SetMax(100)
	inst.components.sanity:SetMax(100)
	--inst:AddComponent("healthRegenerate")
	inst.components.combat.playerdamagepercent = MOBPVP
    --inst.components.combat:SetAttackPeriod(TUNING.HOUND_ATTACK_PERIOD)
	inst.components.combat:SetRange(TUNING.WORM_ATTACK_DIST)
    inst.components.locomotor.runspeed = (TUNING.HOUND_SPEED)
	inst.components.combat:SetDefaultDamage(30*2)	
	inst.components.combat:SetHurtSound("dontstarve/creatures/hound/hit")
	--inst.components.temperature.hurtrate = 0
    inst.components.temperature.inherentinsulation = -TUNING.INSULATION_SMALL
	inst.AnimState:SetBank("hound")
	inst.AnimState:SetBuild("hounddarkplayer")	
	inst.OnSetSkin = function(skin_name)
    inst.AnimState:SetBuild("hounddarkplayer")
	inst:SetStateGraph("SGhounddarkplayer")
	
	inst:ListenForEvent("ms_respawnedfromghost", DontTriggerCreep)
    DontTriggerCreep(inst)
	
	end
	inst:SetStateGraph("SGhounddarkplayer")
	inst.components.locomotor:SetShouldRun(true)
	inst.components.talker:IgnoreAll()
	if MONSTERHUNGER == "Disable" then
	inst.components.hunger:Pause()
	end
	--inst.components.sanity.ignore = true
	
	inst:AddComponent("lootdropper")
    inst.components.lootdropper:SetChanceLootTable('hounddarkplayer')
	
	--inst.components.temperature.maxtemp = 60
	--inst.components.temperature.mintemp = 20
	
	inst.components.eater:SetDiet({ FOODTYPE.MEAT }, { FOODTYPE.MEAT })
    inst.components.eater:SetCanEatHorrible()
	inst.components.eater:SetCanEatRaw()
	inst.components.eater:SetAbsorptionModifiers(1,2,0)

    inst.components.eater.strongstomach = true -- can eat monster meat!
	
	inst:AddTag("hound")
	inst:AddTag("monster")
	inst:AddTag("mobsleep")
	inst:AddTag("houndplayer")
	inst:AddTag("houndfriend")
	--inst:AddTag("scarytoprey")    
	inst:RemoveTag("character")
	
	inst.ghostbuild = "ghost_monster_build"
	inst.mobteleported = false
	
	MakeCharacterPhysics(inst, 10, 0.5)
    inst.DynamicShadow:SetSize(2.5, 1.5)
    inst.Transform:SetFourFaced()

	inst.istired = false
	inst.taunt = true
	inst.taunt2 = true
	--local mult = val and 1 or -2
	--inst.components.sanity.dapperness = mult*TUNING.SANITY_NIGHT_LIGHT

	
    inst.Transform:SetScale(1, 1, 1)
	
	inst:ListenForEvent("equip", Equip) --Shows head when hats make heads disappear.
	inst:ListenForEvent("attacked", onattacked)
	inst:ListenForEvent("sanitydelta", function() inst:DoTaskInTime(1, IsTired) inst:DoTaskInTime(1, TiredPenalties)end)
	--inst:ListenForEvent("sanitydelta", function() inst:DoTaskInTime(1, TiredPenalties)end)
	---MakeHugeFreezableCharacter(inst, "hound_body")
	---MakeHugeBurnableCharacter(inst, "hound_body")
    
	--SanityDrain(inst)
	inst.components.sanity.dapperness = -0.1
	inst.components.sanity.night_drain_mult = 0
	------------------
    inst.OnSave = OnSave
    inst.OnLoad = OnLoad
    ------------------

	
  	local light = inst.entity:AddLight()
  	inst.Light:Enable(true)
  	inst.Light:SetRadius(0)
  	inst.Light:SetFalloff(0.9)
  	inst.Light:SetIntensity(0.6)
  	inst.Light:SetColour(180/255,195/255,150/255)
	
	SetNightVision(inst, true)
	
	inst.components.talker.colour = Vector3(127/255, 0/255, 0/255)
	inst:ListenForEvent("respawnfromghost", RestoreNightvision)

    inst:DoTaskInTime(0, setChar)
    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(6, DontTriggerCreep)
		inst:DoTaskInTime(6, RemovePenalty)
		inst:DoTaskInTime(10, RestoreNightvision)
    end)
	
    return inst
	
end




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