local npcManager = require("npcManager")
local npcutils = require("npcs/npcutils")

local bigShyGuy = {}


bigShyGuy.idList = {}
bigShyGuy.idMap = {}


bigShyGuy.sharedSettings = {
	gfxwidth = 64,
	gfxheight = 64,

	width = 58,
	height = 58,

	gfxoffsetx = 0,
	gfxoffsety = 2,

	frames = 2,
	framestyle = 2,
	framespeed = 8,

	luahandlesspeed = false,
	nowaterphysics = false,
	cliffturn = false,
	staticdirection = false,

	npcblock = false,
	npcblocktop = false,
	playerblock = false,
	playerblocktop = true,

	nohurt = false,
	nogravity = false,
	noblockcollision = false,
	notcointransformable = false,
	nofireball = true,
	noiceball = true,
	noyoshi = true,

	jumphurt = false,
	spinjumpsafe = false,
	harmlessgrab = false,
	harmlessthrown = false,
	nowalldeath = false,

	grabside = false,
	grabtop = true,

	iswalker = true,
}


function bigShyGuy.register(npcID)
	npcManager.registerEvent(npcID, bigShyGuy, "onTickNPC")
	npcManager.registerEvent(npcID, bigShyGuy, "onDrawNPC")

    table.insert(bigShyGuy.idList,npcID)
    bigShyGuy.idMap[npcID] = true
end


local function initialise(v)
	local config = NPC.config[v.id]
	local data = v.data

	data.initialised = true
end


function bigShyGuy.onTickNPC(v)
	if Defines.levelFreeze then return end

	local data = v.data

	if v.despawnTimer <= 0 then
		data.initialised = false
		return
	end

	local config = NPC.config[v.id]

	if not data.initialised then
		initialise(v)
	end

	for _,p in ipairs(Player.get()) do
		if p.standingNPC == v and p.grabTopTimer > 1 and lunatime.tick()%3 < 2 then
			p.grabTopTimer = p.grabTopTimer - 1
		end
	end
end

function bigShyGuy.onDrawNPC(v)
	if v.despawnTimer <= 0 then
		return
	end

	local config = NPC.config[v.id]
	local data = v.data

	if not data.initialised then
		initialise(v)
	end

	
end


function bigShyGuy.onTick()
	for _,p in ipairs(Player.get()) do
		if p.grabTopTimer > 0 and p.standingNPC ~= nil and bigShyGuy.idMap[p.standingNPC.id] then
			p.data.bigShyGuyGrabTimer = (p.data.bigShyGuyGrabTimer or 0) + 1

			if p.data.bigShyGuyGrabTimer < 24 then
				p.grabTopTimer = 1
			end

			if p.data.bigShyGuyGrabTimer < 24 then
				p:mem(0x118,FIELD_FLOAT,0)
			else
				p:mem(0x118,FIELD_FLOAT,6)
			end
		else
			p.data.bigShyGuyGrabTimer = nil
		end
	end
end


function bigShyGuy.onNPCHarm(eventObj,v,reason,culprit)
	if bigShyGuy.idMap[v.id] and (reason == HARM_TYPE_NPC or reason == HARM_TYPE_TAIL) then
		v.isProjectile = true
		v.speedX = 0
		v.speedY = -6

		if type(culprit) == "NPC" and culprit.heldIndex > 0 then
			v:mem(0x130,FIELD_WORD,culprit.heldIndex)
			v:mem(0x12E,FIELD_WORD,128)

			culprit:harm(HARM_TYPE_NPC)
		end

		SFX.play(9)

		eventObj.cancelled = true
	end
end

function bigShyGuy.onPostNPCHarm(v,reason,culprit)
	if reason == HARM_TYPE_NPC and type(culprit) == "NPC" and bigShyGuy.idMap[culprit.id] then
		if culprit.heldIndex > 0 then
			culprit.isProjectile = true
			culprit.speedY = -6

			culprit:mem(0x130,FIELD_WORD,culprit.heldIndex)
			culprit:mem(0x12E,FIELD_WORD,128)

			Player(culprit.heldIndex):mem(0x154,FIELD_WORD,0)
			culprit.heldIndex = 0
		elseif culprit.isProjectile then
			culprit.speedX = math.clamp(culprit.speedX,-4,4)
			culprit.speedY = -5
		end
	end
end


function bigShyGuy.onInitAPI()
	registerEvent(bigShyGuy,"onTick")
	registerEvent(bigShyGuy,"onNPCHarm")
	registerEvent(bigShyGuy,"onPostNPCHarm")
end


return bigShyGuy