require "class"
require "screens/pausescreen"
local easing = require "easing"

local trace = function() end

local CLICK_WALK_TIME = .5

local prefabs =
{
	"ghostplayer",
	"summonclone",
	"camera_prefab",
}


local PlayerController_spawner = Class(function(self, inst)
    self.inst = inst
    self.enabled = true
    
    self.player = {}
	self.player[2] = nil
	self.player[3] = nil
	
	
    self.inputhandlers = {}

    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_P, function() self:SpawnPlayer2() end))
	
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_DELETE, function() self:SpawnPlayer3("wilson") end))---1
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_HOME, function() self:SpawnPlayer3("willow") end))---2
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_INSERT, function() self:SpawnPlayer3("wolfgang") end))---3
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_END, function() self:SpawnPlayer3("wendy") end))---4
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_PAGEUP, function() self:SpawnPlayer3("wx78") end))----5
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_PAGEDOWN, function() self:SpawnPlayer3("wickerbottom") end))----6
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_RSHIFT, function() self:SpawnPlayer3("woodie") end))---7
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_RCTRL, function() self:SpawnPlayer3("waxwell") end))---8
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_ENTER, function() self:SpawnPlayer3("wes") end))---8
	
    table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_Z, function() self:Camera() end))---7
	table.insert(self.inputhandlers, TheInput:AddKeyUpHandler(KEY_KP_MINUS, function() self:TryToRespawn("respawn",23,false) end))
	
	
    table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_X, function() self:CameraPrefab() end))---7
    table.insert(self.inputhandlers, TheInput:AddKeyDownHandler(KEY_C, function() self:Defence() end))---7

end)

function PlayerController_spawner:Camera()
    TheCamera:SetTarget(self.inst)
end

function PlayerController_spawner:CameraPrefab()
    local cameraprefab = FindEntity(GetPlayer(), 1000, function(guy) return (guy.components.playercontroller_camera)end)
	if cameraprefab then
		cameraprefab.components.health:DoDelta(-9000)
	end
	
    local ghostplayer = SpawnPrefab("camera_prefab")
    ghostplayer.Transform:SetPosition(GetPlayer().Transform:GetWorldPosition())
    TheCamera:SetTarget(ghostplayer)
	ghostplayer.components.playercontroller_camera.camfocus = 1
	
end

function PlayerController_spawner:Defence()
if TUNING.DEFENCEOFF==1 then
 print("coop def is off")
 return
end

    local cameraprefab = FindEntity(self.inst, 1000, function(guy) return (guy:HasTag("deftorch"))end)
if cameraprefab then
	cameraprefab.components.health:DoDelta(-9000)
			
			


end	
            local ghostplayer = SpawnPrefab("deftorch")
            ghostplayer.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
    self.inst.components.inventory:ConsumeByName("ash", 4)
    self.inst.components.inventory:ConsumeByName("torch", 1)



		
end

function PlayerController_spawner:SpawnPlayer2()
if TUNING.GHOSTPLAYERON==1 then return end
            local ghostplayer = SpawnPrefab("ghostplayer")
            ghostplayer.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
		if self.inst.components.health.currenthealth > 50 then
			self.inst.components.health:SetPercent(.5)
			self.inst.components.hunger:SetPercent(.5)
			self.inst.components.sanity:SetPercent(.5)
		end			
end





function PlayerController_spawner:FindPlayerByNum(plnum, fromcam)
	local num = plnum or 322
	if self.player[num] and not self.player[num].components.health:IsDead() then return self.player[num] end
	local pl = FindEntity(self.inst, 125, function(guy) return (guy.components.playercontroller_3 and guy.plnum == num)end)
	if pl and not fromcam then print("=============PLAYER FOUND ~"..plnum.."  =======") end
	if not pl then return nil end
	if pl and not pl.components.health:IsDead() then self.player[num]=pl return pl end
end

function PlayerController_spawner:WasPlayerByNumSpawned(plnum)
	local num = plnum or 2
	if self.inst.components.p3stats_saver.stat[num] == true then
		print("player"..num.."  was spawned --------WasPlayerByNumSpawned")
	else 
		print("player"..num.."  was -=NOT=- spawned --------WasPlayerByNumSpawned")
	end
	return self.inst.components.p3stats_saver.stat[num] or false
end




function PlayerController_spawner:SetPlayersChars(tag, newplnum)
	local plnum = newplnum or 3
	print("SetPlayersChars ~"..plnum.."  TAG =" ..tag)
	if TUNING.PICK_CHAR_IN_WORLD == 1 and tag and tag~="respawn" then
		self.inst.components.p3stats_saver.shstats[newplnum]["char"] = tag
	elseif TUNING.PICK_CHAR_IN_WORLD == 0 then
		self.inst.components.p3stats_saver.shstats[2]["char"] = TUNING.PLAYER_2_CHARACTER-- or wilson"
		self.inst.components.p3stats_saver.shstats[3]["char"] = TUNING.PLAYER_3_CHARACTER-- or "wilson"
	end
end


function PlayerController_spawner:IsRespawnNeeded(newplnum, spawn1)
	if TUNING.PLAYER_CHARACTER_ENABLED[newplnum]==false then return end
	
	local wasspawned = self:WasPlayerByNumSpawned(newplnum)
	--print("========WASSPWANED ~".. newplnum.." wasspawned = "..wasspawned)
	local playercheck = self:FindPlayerByNum(newplnum)
	if playercheck then print("IsRespawnNeeded  PLAYER FOUND NO NEED TO RESPAWN") return false end
	if wasspawned==false or wasspawned ==true then
		print("RESPAWN IS NEEDED")
		return true
	elseif spawn1 and spawn1==true then
		print("RESPAWN IS NEEDED")
		return true
	else --if wasspawned==true then 
		print("RESPAWN NOT NEEDED")
		return false
	end
end





function PlayerController_spawner:TryToRespawn(tag, newplnum, newspawn, screwchecks)
	print("PlayerController_spawner:TryToRespawn")
	self.inst:DoTaskInTime(0.01, function()	

	if screwchecks then
		print("======== SCREW CHECKS RESPAWN!========")
		self:DoSpawnPlayer(tag, newplnum)
		return
	end
	
	local nws = newspawn or false
	if newplnum==23 then 
		print("Do twise!")
		
		local respawnneeded = self:IsRespawnNeeded(2, newspawn)
		if respawnneeded == true and nws ==false then
			self:DoSpawnPlayer("respawn", 2, false)
		elseif respawnneeded == true then
			self:DoSpawnPlayer(tag, 2, true)
		end
		
		respawnneeded = self:IsRespawnNeeded(3, newspawn)
		if respawnneeded == true and nws ==false then
			self:DoSpawnPlayer("respawn", 3, false)
		elseif respawnneeded == true then
			self:DoSpawnPlayer(tag, 3, true)
		end		
		
		
		
		return
	end
	local respawnneeded = self:IsRespawnNeeded(newplnum, newspawn)

	if respawnneeded == true and nws ==false then
		self:DoSpawnPlayer("respawn", newplnum, false)
	elseif respawnneeded == true then
		self:DoSpawnPlayer(tag, newplnum, true)
	end
	
	end)
end


function PlayerController_spawner:FindAndKillPlayerByNum(newplnum, norecordstats)

	local targ = self:FindPlayerByNum(newplnum)
	if targ then targ.components.playercontroller_3:DeleteWithStatsRecord(norecordstats) end

end





function PlayerController_spawner:DoSpawnPlayer(tag, newplnum, newspwn)
	local player1 = GetPlayer()
	local plnum = newplnum
	
	---local newspawn1 = newspwn
	self:FindAndKillPlayerByNum(newplnum)
	self:SetPlayersChars(tag, newplnum)
	
	local version = "ds"
	if player1.components.driver then
		version = "sw"
	elseif player1.components.moisture then
		version = "rog"
	end
	
	print("SPAWNING player for  " ..version)
	
    local newplayer = SpawnPrefab("summonclone"..version..plnum)
	player1.components.p3stats_saver.stat[newplnum] = true


	local health = player1.components.p3stats_saver.shstats[plnum]["health"] or 1
	local sanity = player1.components.p3stats_saver.shstats[plnum]["sanity"] or 1 
	local hunger = player1.components.p3stats_saver.shstats[plnum]["hunger"] or 1 
	local x = player1.components.p3stats_saver.shstats[plnum]["x"] or 0
	local y = player1.components.p3stats_saver.shstats[plnum]["y"] or 0	
	local dead = false
	local newspawn = newspwn or false
	
	
	if newspwn==true then
		print("240 newspawn set to TRUE")
		health = 1
		sanity = 1
		hunger = 1
	elseif health <0.1 or hunger<0.1 then
		print("DO RESPAWN PUNISHMENT")
		self:DoRespawnPunishment(health, hunger, sanity)
		dead = true
	end

	self:SetHpPos(newplayer, health, hunger, sanity, x, y, dead, newspwn)
	if dead == true then
		player1.components.p3stats_saver:RespawnDelta(-1,newplayer)
		newplayer.sg:GoToState("wakeup")
	else
		print("====RESPAWN -=NOT=- COUNTED on summonclone  RESPAWNS LEFT = ".. player1.components.p3stats_saver.stat["respawnsleft"])
	end
	self:BoatFix(newplayer, dead)
end


function PlayerController_spawner:SetHpPos(targ, hp, hun, san, x, y, isdead, newspwn)
	if not targ then return end
	local health = hp or 1
	local hunger = hun or 1
	local sanity = san or 1
	local dead = isdead or false 
	local firstspawn = newspwn or false
	
	if dead==true then
		health = 0.35
		hunger = 2/3
		sanity = .5
	end
	
	targ.components.health:SetPercent(health)
	targ.components.hunger:SetPercent(hunger)
	targ.components.sanity:SetPercent(sanity)
	
	
	if x~=0 and dead == false and firstspawn == false then
		print("MOVING TO POS")
		targ.Transform:SetPosition(x, 0, y)
	else
		targ.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
	end
	
end

function PlayerController_spawner:DoRespawnPunishment(deadhp, deadhunger, deadsanity)
			local p1tohealth = 1
			
			if deadhp<0.1 then
				p1tohealth = p1tohealth-0.5

				self.inst.components.sanity:DoDelta(-25,true)
				self.inst.components.hunger:DoDelta(-25,true)
			end
			if deadhunger<0.1 then
				p1tohealth = p1tohealth-0.15
				
				self.inst.components.sanity:DoDelta(-5,true)
				self.inst.components.hunger:DoDelta(-5,true)
			end
			if self.inst.components.health:GetPercent()>p1tohealth then
				self.inst.components.health:SetPercent(p1tohealth)
			end


	local phrase = ""
	local respawnsleft = self.inst.components.p3stats_saver.stat["respawnsleft"] or 322
	if respawnsleft == 322 then
		phrase = "Rise!"
	else
		phrase = "We've got "..respawnsleft.." resurrections left!"
	end
	self.inst.components.talker:Say(phrase)
	
end


function PlayerController_spawner:DoRespawnPunishmentttt1(deadhp, deadhunger, deadsanity)
			local player1 = self.inst
			
			local hp = 1
			local sanity = 1
			local hunger = 1
			local x = 0
			local y = 0
			local dead = false
			local p1tohealth = 1


			hp = player1.components.p3stats_saver.shstats[plnum]["health"]
			sanity = player1.components.p3stats_saver.shstats[plnum]["sanity"]
			hunger = player1.components.p3stats_saver.shstats[plnum]["hunger"]
			x = player1.components.p3stats_saver.shstats[plnum]["x"]
			y = player1.components.p3stats_saver.shstats[plnum]["y"]
			print("===136  POSITION pos;  x "..x.."  y:"..y)
			if hp<0.01 then
				dead = true
				hp = 0.35
				p1tohealth = 35

				self.inst.components.sanity:DoDelta(-25,true)
				self.inst.components.hunger:DoDelta(-25,true)
			end
			if hunger<0.01 then
				hunger = 0.35
				p1tohealth = p1tohealth-0.15
				
				self.inst.components.sanity:DoDelta(-5,true)
				self.inst.components.hunger:DoDelta(-5,true)
			end
			if self.inst.components.health:GetPercent()>p1tohealth then
				self.inst.components.health:SetPercent(p1tohealth)
			end

end




function PlayerController_spawner:BoatFix(newplayer, dd)
	local dead = dd or false
	local player1 = GetPlayer()
	local plnum = newplayer.plnum or 2
	if not newplayer.components.driver then return end
	
	if (player1.components.driver.driving == true and dead == true) or (player1.components.p3stats_saver.shstats[plnum]["boatingwith"] and player1.components.p3stats_saver.shstats[plnum]["boatingwith"] ==1) then
		newplayer.components.playercontroller_3:MountBoat()
		newplayer.mountedvehicle = player1.components.driver.vehicle
	elseif player1.components.p3stats_saver.shstats[plnum]["boatingwith"]==2 then
		print("BOATING  WITH == 2")
		local emptyboatnear	= FindEntity(newplayer, 2, function(guy) return (guy.components.drivable and not guy:HasTag("NOCLICK") and guy.components.boathealth and not guy.components.boathealth:IsDead()) end)
		if emptyboatnear then
			print("206 BOAT FoUND")
			newplayer.startupdatingboatwithplayer = false
			local action = ACTIONS.MOUNT
			local ba = BufferedAction(newplayer, emptyboatnear, action)
			newplayer.mountedvehicle = emptyboatnear
			newplayer.components.locomotor:PushAction(ba, true)
			newplayer.boatingwith = 2
			newplayer:RemoveComponent("Player3KeepOnLand")
		end
	else
		newplayer:RemoveTag("aquatic")

		newplayer:AddComponent("Player3KeepOnLand")

	
	end
	
end




--[[

function PlayerController_spawner:RespawnPlayer3(tag, newplnum, newspawn)
	self.inst:DoTaskInTime(0.25, function()	
		
			print("==========PlayerController_spawner:RespawnPlayer3============")
			local plnum = newplnum or 3
			print("============PLAYER NUMBER = ".. plnum)

			if GetPlayer().components.p3stats_saver.stat["respawnsleft"]<1 then
				print("==== NO LIFES LEFT CAN NOT RESPAWN!===")
				return
			end


			if self.inst:HasTag("RespawnPlayer3") then
					self.inst:DoTaskInTime(5, function()	
					self.inst:RemoveTag("RespawnPlayer3")
					return
				end)
				return
			end
			
			---find and kill existing player3
			local oldplayer = self:FindPlayerByNum(plnum)
			if oldplayer then
				GetPlayer().components.p3stats_saver:RecordStatsSeparate(oldplayer,"PlayerController_spawner:RespawnPlayer3")			
				oldplayer.components.playercontroller_3:DeleteWithStatsRecord(true)
			end
			
			TheCamera:SetTarget(self.inst)
			
			local player1 = GetPlayer()

			
			local hp = 1
			local sanity = 1
			local hunger = 1
			local x = 0
			local y = 0
			local dead = false
			local p1tohealth = 1
			
			
		if self.inst:HasTag("notspawn") or player1.components.p3stats_saver.shstats[plnum]["notspawn"] == true then
			hp = player1.components.p3stats_saver.shstats[plnum]["health"]
			sanity = player1.components.p3stats_saver.shstats[plnum]["sanity"]
			hunger = player1.components.p3stats_saver.shstats[plnum]["hunger"]
			x = player1.components.p3stats_saver.shstats[plnum]["x"]
			y = player1.components.p3stats_saver.shstats[plnum]["y"]
			print("===136  POSITION pos;  x "..x.."  y:"..y)
			if hp<0.01 then
				dead = true
				hp = 0.35
				p1tohealth = p1tohealth-0.65

				self.inst.components.sanity:DoDelta(-25,true)
				self.inst.components.hunger:DoDelta(-25,true)
			end
			if hunger<0.01 then
				hunger = 0.35
				p1tohealth = p1tohealth-0.15
				
				self.inst.components.sanity:DoDelta(-5,true)
				self.inst.components.hunger:DoDelta(-5,true)
			end
			if self.inst.components.health:GetPercent()<p1tohealth then
				self.inst.components.health:SetPercent(p1tohealth)
			end
		end
		
			if not newplayer then
				print("WTF?!")
				return
			end
			if not player1.components.p3stats_saver.shstats[plnum]["char"] then player1.components.p3stats_saver.shstats[plnum]["char"]="wilson" end
			print("CHAR :  "..player1.components.p3stats_saver.shstats[plnum]["char"].."=====:stat  hp: "..hp.." stat hunger: "..hunger)
			newplayer.components.health:SetPercent(hp)
			newplayer.components.hunger:SetPercent(sanity)
			newplayer.components.sanity:SetPercent(hunger)
			

		
		if x~=0 and not dead == true then
			print("MOVING TO POS")
			--newplayer.Physics:Teleport(x, 0, y) 
			newplayer.Transform:SetPosition(x, 0, y)
		else
			newplayer.Transform:SetPosition(self.inst.Transform:GetWorldPosition())
		end
		
		if dead == true then
			player1.components.p3stats_saver:RespawnDelta(-1,newplayer)
			newplayer.sg:GoToState("wakeup")

		else
			print("====RESPAWN -=NOT=- COUNTED on summonclone  RESPAWNS LEFT = ".. player1.components.p3stats_saver.stat["respawnsleft"])
		end

			self.CameraPrefab()
			

			self.inst.components.sanity:DoDelta(-1,true)
			self.inst.components.hunger:DoDelta(-1,true)
			
			
			self.inst:AddTag("notspawn")
			player1.components.p3stats_saver.shstats[plnum]["notspawn"] = true

			

	newplayer.components.playercontroller_3:GiveSpecialItems()

	
	
	end
   
   
   
   
	end)
end--]]


function PlayerController_spawner:Respawner(tag)


end

function PlayerController_spawner:SpawnPlayer3(tag)
	local player1 = GetPlayer()
	local spawning = false
	local dospawnnumber = nil
	
	if not player1.components.playercontroller_spawner:FindPlayerByNum(2) and player1.components.playercontroller_spawner:WasPlayerByNumSpawned(2) == false then
		print("PLAYER 2     274:SpawnPlayer!")
		spawning = true
		dospawnnumber = 2
	end
	
	if not player1.components.playercontroller_spawner:FindPlayerByNum(3) and player1.components.playercontroller_spawner:WasPlayerByNumSpawned(3) == false
	and not spawning == false then
		player1.components.p3stats_saver.stat["char"] = tag
		player1.components.p3stats_saver.shstats[3]["char"] = tag
		print("PLAYER 3     289:SpawnPlayer!")
		spawning = true
		dospawnnumber = 3
	end

	
	if spawning == true and dospawnnumber then--- and tag~="respawn" then
		player1.components.p3stats_saver.stat["char"] = tag
		player1.components.p3stats_saver.shstats[dospawnnumber]["char"] = tag
		print("p3stats_saver.shstats  char "..dospawnnumber.."  = "..player1.components.p3stats_saver.shstats[dospawnnumber]["char"])
		self:TryToRespawn(tag, dospawnnumber, true)

	end
	
	
	--[[if not self.inst:HasTag("notspawn") and player1.components.p3stats_saver.stat["notspawn"] == false then
			self.inst:AddTag(tag)
			player1.components.p3stats_saver.stat["char"] = tag
			player1.components.p3stats_saver.shstats[3]["char"] = tag

			print("tag = "..tag)

	end--]]
end



return PlayerController_spawner
