local MakePlayerCharacter = require "prefabs/player_common"

--ToDo:
--give skinn variable instead of isguard variable.

local assets = 
{
	Asset("ANIM", "anim/pig_shiny_build_01.zip"),
	Asset("ANIM", "anim/werepig_shiny_build_01.zip"),
}

local prefabs = {	
    }
	
local start_inv = {
	"Meat",
	"Meat",
	"pigskin",
	--"bedroll_monster",
}

local function ontalk(inst, script)
    inst.SoundEmitter:PlaySound("dontstarve/pig/grunt")
end

local function RestoreNightvision(inst)

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

local function CanShareTarget(dude)
    return dude:HasTag("pig")
        and not dude:IsInLimbo()
        and not (dude.components.health:IsDead() or dude:HasTag("player"))
end

local function OnAttacked(inst, data)
        inst.components.combat:SetTarget(data.attacker)
        inst.components.combat:ShareTarget(data.attacker, 30, CanShareTarget, 5)
 end
 
 local function SetBuild(inst)
    if inst.isguard == 1 then
		inst.AnimState:SetBuild("pig_guard_build")
		inst:AddTag("guard")
	else
		inst.AnimState:SetBuild("pig_build")
	end	
	
 end
 
  local function RemoveGuard(inst)
    inst:RemoveTag("guard")
	inst.isguard = 0
	
 end
 
   local function MakeGuard(inst)
    inst:AddTag("guard")
	inst.isguard = 1
	
 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 IsPig(dude)
    return dude:HasTag("pig")
end

local function IsWerePig(dude)
    return dude:HasTag("werepig")
end

local function BecomeGuard(inst)
	if not inst:HasTag("playerghost") then
	if inst.isguard == 1 then
		inst.AnimState:SetBuild("pig_guard_build")
	else
		inst.AnimState:SetBuild("pig_build")
	end	
	end
end

--local function OnPreload(inst, data)
    --if data ~= nil and data.build ~= nil then
        --SetBuild(inst)
        --re-set these from the save data, because of load-order clipping issues
        --if data.health and data.health.health then inst.components.health:SetCurrentHealth(data.health.health) end
        --if data.hunger and data.hunger.hunger then inst.components.hunger.current = data.hunger.hunger end
   -- end
--end

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

local function OnSave(inst, data)
	data.isguard = inst.isguard > 0 and inst.isguard or nil
	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("pig_shiny_build_0"..inst.isshiny)
			end		
		end
	end	
end

local function IsNonWerePig(dude)
    return dude:HasTag("pig") and not dude:HasTag("werepig")
end

local function IsGuardPig(dude)
    return dude:HasTag("guard") and dude:HasTag("pig")
end

local function SetNormalPig(inst)
    inst:RemoveTag("werepig")
    inst:RemoveTag("guard")
    --inst:SetBrain(normalbrain)
    inst:SetStateGraph("SGpigmanplayer")
	inst.sg:GoToState("transformNormal")
	--inst.AnimState:SetBuild("pig_build")
	
	inst.components.sanity:DoDelta(-75, false)
    inst.components.combat:SetDefaultDamage(50)
    inst.components.locomotor.runspeed = 6
    inst.components.locomotor.walkspeed = TUNING.PIG_WALK_SPEED

    --inst.components.lootdropper:SetLoot({})
    --inst.components.lootdropper:AddRandomLoot("meat", 3)
    --inst.components.lootdropper:AddRandomLoot("pigskin", 1)
    --inst.components.lootdropper.numrandomloot = 1

	inst.components.temperature.maxtemp = TUNING.MAX_ENTITY_TEMP
	inst.components.temperature.mintemp = TUNING.MIN_ENTITY_TEMP
	
    inst.components.health:SetMaxHealth(250)
    inst.components.talker:StopIgnoringAll("becamewerepig")
	inst:StopWatchingWorldState("startday")
end

local function SetGuardPig(inst)
    inst:RemoveTag("werepig")
    inst:AddTag("guard")
	inst:SetStateGraph("SGpigmanplayer")
	inst.sg:GoToState("transformNormal")
	--inst.AnimState:SetBuild("pig_guard_build")
	
	

    inst.components.health:SetMaxHealth(250)
    inst.components.combat:SetDefaultDamage(65)
	inst.components.sanity:DoDelta(-75, false)
    inst.components.locomotor.runspeed = 6
    inst.components.locomotor.walkspeed = TUNING.PIG_WALK_SPEED
	
	
	inst.components.temperature.maxtemp = TUNING.MAX_ENTITY_TEMP
	inst.components.temperature.mintemp = TUNING.MIN_ENTITY_TEMP
    --inst.components.sleeper:SetSleepTest(GuardShouldSleep)
    --inst.components.sleeper:SetWakeTest(GuardShouldWake)

    --inst.components.lootdropper:SetLoot({})
    --inst.components.lootdropper:AddRandomLoot("meat", 3)
   -- inst.components.lootdropper:AddRandomLoot("pigskin", 1)
    --inst.components.lootdropper.numrandomloot = 1

    inst.components.talker:StopIgnoringAll("becamewerepig")
	inst:StopWatchingWorldState("startday")

end

local function SetWerePig(inst)
if TheWorld.state.isnight and TheWorld.state.isfullmoon then
	inst:AddTag("werepig")
    --inst:RemoveTag("guard")
	
    inst:SetStateGraph("SGwerepigplayer")
	inst.sg:GoToState("transformWere")
    --inst.AnimState:SetBuild("werepig_build")
    --inst.components.sleeper:SetResistance(3)
	if inst.components.inventory ~= nil then
		inst.components.inventory:DropEverything(true)
	end

    inst.components.combat:SetDefaultDamage(100*2)
    --inst.components.combat:SetAttackPeriod(TUNING.WEREPIG_ATTACK_PERIOD)
    inst.components.locomotor.runspeed = 9
    inst.components.locomotor.walkspeed = 9

    --inst.components.sleeper:SetSleepTest(WerepigSleepTest)
    --inst.components.sleeper:SetWakeTest(WerepigWakeTest)

    --inst.components.lootdropper:SetLoot({ "meat", "meat", "pigskin" })
    --inst.components.lootdropper.numrandomloot = 0

    inst.components.health:SetMaxHealth(600)
	inst.components.health:DoDelta(20000, false)
    inst.components.talker:IgnoreAll("becamewerepig")
	
	inst.components.temperature.maxtemp = 60
	inst.components.temperature.mintemp = 20
	inst.components.temperature:SetTemp(30)
	if inst:HasTag("guard") then
		inst:WatchWorldState("startday", SetGuardPig)
	else
		inst:WatchWorldState("startday", SetNormalPig)
	end	
	end
end

local function GetStatus(inst)
    return (inst:HasTag("werepig") and "WEREPIG")
        or (inst:HasTag("guard") and "GUARD")
        or nil
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 setChar(inst)
	inst.ghostbuild = "ghost_monster_build"
	if inst.isguard == 1 then
		if not inst:HasTag("playerghost") then
		inst.AnimState:SetBank("pigman")
		inst.AnimState:SetBuild("pig_guard_build")
		inst:SetStateGraph("SGpigmanplayer")
		end
		inst:AddTag("guard")
		inst.components.health:SetMaxHealth(250) --these are here in the case of errors of werepig transformations.
		inst.components.sanity:SetMax(150)
	else
		if not inst:HasTag("playerghost") then
		inst.AnimState:SetBank("pigman")
		inst.AnimState:SetBuild("pig_build")
		inst:SetStateGraph("SGpigmanplayer")
		end
		inst.components.health:SetMaxHealth(250)
		inst.components.sanity:SetMax(150)
		
	end
	if MOBPVPMODE == "Enable" then
		PvPTeleport(inst)
	end
end	


local NIGHTVISION_COLOURCUBES =
{
    day = "images/colour_cubes/insane_day_cc.tex",
    dusk = "images/colour_cubes/insane_dusk_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:IsCave() 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 common_postinit = function(inst) 
	inst.soundsname = "wilson"

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

	inst:DoTaskInTime(0, function()
   if ThePlayer then
      inst:EnableMovementPrediction(false)
   end
   
   --inst:AddComponent("worker")
	--inst.components.worker:SetAction(ACTIONS.DIG, 1)
	--inst.components.worker:SetAction(ACTIONS.CHOP, 3)
	--inst.components.worker:SetAction(ACTIONS.MINE, 3)
	--inst.components.worker:SetAction(ACTIONS.HAMMER, 3)
   
end)

    
	--inst:WatchWorldState("isfullmoon", inst:DoTaskInTime(2, function()SetWerePig(inst) end))
end

local function Equip(inst)
    local head = inst.components.inventory:GetEquippedItem(EQUIPSLOTS.HEAD)
	if head then

	inst.AnimState:Show("HEAD")
        
		
	end 
	
end

local function DontTriggerCreep(inst)
    inst.components.locomotor.runspeed = (6)
	--inst.components.locomotor:SetSlowMultiplier( 1 )
    --inst.components.locomotor:SetTriggersCreep(false)
    --inst.components.locomotor.pathcaps = { ignorecreep = true }
end


local master_postinit = function(inst)
    inst.components.health:SetMaxHealth(250)
	inst.components.hunger:SetMax(150)
	inst.components.sanity:SetMax(125)
	--inst:AddComponent("healthRegenerate")
	inst.components.combat.playerdamagepercent = MOBPVP
	inst.components.combat.pvp_damagemod = 1 --disables second pvp override.
    --inst.components.combat:SetAttackPeriod(TUNING.HOUND_ATTACK_PERIOD)
	inst.components.combat:SetRange(TUNING.WORM_ATTACK_DIST)
    inst.components.locomotor.runspeed = (6)
	inst.components.combat:SetDefaultDamage(65)
	--inst.components.combat:SetHurtSound("dontstarve/creatures/hound/hit")
	--inst.components.temperature.hurtrate = 0
    inst.components.temperature.inherentinsulation = -TUNING.INSULATION_SMALL
	--inst.AnimState:SetBank("pigman")
	inst.AnimState:SetBuild("pig_build")	
	inst.OnSetSkin = function(skin_name)
    inst.AnimState:SetBuild("pig_build")
	inst:SetStateGraph("SGpigmanplayer")
	
	--SetCharSkinner(inst)
	
	inst:ListenForEvent("ms_respawnedfromghost", DontTriggerCreep)
    DontTriggerCreep(inst)

	
	end
	inst:SetStateGraph("SGpigmanplayer")
	
	inst.components.locomotor:SetShouldRun(true)
	
	MakeMediumBurnableCharacter(inst, "pig_torso")
    MakeMediumFreezableCharacter(inst, "pig_torso")
	
	inst.isguard = 0
	inst.taunt = true
	--inst.specialsleep = true
	inst.specialatk2 = true
	
	inst.mobteleported = false
	
	--inst:AddComponent("lootdropper")
    --inst.components.lootdropper:SetChanceLootTable('pigmanplayer')
	--inst.components.health.fire_damage_scale = 0 -- Take no damage from fire 
	inst:WatchWorldState("isfullmoon", SetWerePig)
	 
	inst:AddTag("character")
    inst:AddTag("pig")
	inst:AddTag("pigmanplayer")
	
	inst.isshiny = 0
	
    inst.components.talker.ontalk = ontalk
    inst.components.talker.fontsize = 35
    inst.components.talker.font = TALKINGFONT
    --inst.components.talker.colour = Vector3(133/255, 140/255, 167/255)
    inst.components.talker.offset = Vector3(0, -400, 0)
	
	--inst:AddComponent("werebeast")
    --inst.components.werebeast:SetOnWereFn(SetWerePig)
    --inst.components.werebeast:SetTriggerLimit(4)
	
	inst:ListenForEvent("attacked", OnAttacked)
	
	MakeCharacterPhysics(inst, 50, .5)
    inst.DynamicShadow:SetSize(1.5, .75)
    inst.Transform:SetFourFaced()
	
	 inst.userfunctions =
    {
        MakeGuard = MakeGuard,
        RemoveGuard = RemoveGuard,
    }
	
	--inst.components.temperature.maxtemp = 60
	--inst.components.temperature.mintemp = 20
	--inst.components.moisture:SetInherentWaterproofness(1)
	
	--inst.AnimState:Show("Head")
    --inst.AnimState:Show("HatFX")
	inst.ghostbuild = "ghost_monster_build"
	inst.OnSave = OnSave
	inst.OnLoad = OnLoad
	--inst.OnPreLoad = OnPreload
	
	inst:ListenForEvent("equip", Equip)
    
	inst:DoTaskInTime(2, SetWerePig)
	------------------
    
    ------------------

	
  	local light = inst.entity:AddLight() --Can't see at night but is immune to Grue
  	inst.Light:Enable(false)
  	inst.Light:SetRadius(0)
  	inst.Light:SetFalloff(0.6)
  	inst.Light:SetIntensity(0.6)
  	inst.Light:SetColour(180/255,195/255,255/255)
	
	--No nightvision, is afraid of Grue.
  	--inst:WatchWorldState( "isday", function() SetNightVision(inst) end)
  	--inst:WatchWorldState( "isdusk", function() SetNightVision(inst) end)
  	--inst:WatchWorldState( "isnight", function() SetNightVision(inst)  end)
	
	--SetNightVision(inst, true)
	
	--inst.components.talker.colour = Vector3(127/255, 0/255, 0/255)
	inst:ListenForEvent("respawnfromghost", RestoreNightvision)
	
	

    inst:DoTaskInTime(0, setChar)
	if SKIN_RARITY_COLORS.ModMade ~= nil then
	inst:DoTaskInTime(3, setSkin)
	end
    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, DontTriggerCreep)
		inst:DoTaskInTime(6, RemovePenalty)
		inst:DoTaskInTime(10, RestoreNightvision)
    end)
	
	
    return inst
	
end

local function normal()
    local inst = common()

    if not TheWorld.ismastersim then
        return inst
    end

    inst.build = builds[math.random(#builds)]
    inst.AnimState:SetBuild(inst.build)
    SetNormalPig(inst)
    return inst
end

local function guard()
    local inst = common()

    if not TheWorld.ismastersim then
        return inst
    end

    inst.build = guardbuilds[math.random(#guardbuilds)]
    inst.AnimState:SetBuild(inst.build)
    SetGuardPig(inst)
    return inst
end

if SKIN_RARITY_COLORS.ModMade ~= nil then
AddModCharacterSkin("pigmanplayer", 1, {normal_skin = "deerclops_shiny_build_01", ghost_skin = "ghost_monster_build"}, {"deerclops_shiny_build_01", "ghost_monster_build"}, {"DEERPLAYER", "FORMAL"})
end

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