extends Sprite2D

@onready var player = $"../"

var spinAccel = 0

func spin(veloc, delta):
	var vertSpinMult = abs(veloc.y) * clamp(veloc.x, -1, 1) / 1.5
	var spinFactor = (veloc.x + vertSpinMult) / 40
	spinFactor = clamp(spinFactor, -25, 25)
	
	if (player.direction or abs(player.velocity.x) > 100) and not player.is_on_wall():
		rotation = lerp(rotation, rotation + (spinFactor), delta)
	else:
		rotation = lerp(rotation, snappedf(rotation + clamp(spinFactor * delta * 2, -PI / 3, PI / 3), PI / 2), delta * 5)

var landed = 0

@onready var slidingVariants = [$"WallslidingNeutral", $"WallslidingUp", $"WallslidingDown"]

var afterImage = preload("res://Particles/Player/AfterImage.tscn")

func disableSlidingVariants(keep=null):
	for variant in slidingVariants:
		if variant != keep:
			variant.emitting = false

var imageTimer = 0
var imaging = false
var lastImage = Vector2.ZERO

func _ready():
	if player.has_signal("Jumped"):
		player.Jumped.connect(_on_character_jumped)

func _process(delta):
	
	var velocity = player.velocity
	
	var floored = player.is_on_floor()
	
	if velocity.length() >= 1100:
		imaging = true
	elif velocity.length() < 800:
		imaging = false
	
	if (imaging or (find_child("Grapple") and $"Grapple".grappling)) and (global_position - lastImage).length() > 16:
		var parti = afterImage.instantiate()
		add_child(parti)
		parti.duration = velocity.length() / 2000
		lastImage = global_position
	if player.isWallSliding():
		var wallSlidingParticles = slidingVariants[0]
		if abs(velocity.y) < 150:
			wallSlidingParticles = slidingVariants[1]
		elif abs(velocity.y) > 300:
			wallSlidingParticles = slidingVariants[2]
		
		disableSlidingVariants(wallSlidingParticles)
		wallSlidingParticles.emitting = true
		wallSlidingParticles.global_position = player.position + (player.get_wall_normal() * -8 * player.scale.x)
		wallSlidingParticles.global_rotation = player.get_wall_normal().x * deg_to_rad(45)
		
	else:
		disableSlidingVariants()
	
	if not floored:
		if player.is_on_ceiling() and landed < -100:
			rotation = 0
			scale.y = 1 + (landed / 800.)
			scale.x = 1 - (landed / 800.)
			
		
		spin(velocity, delta)
		landed = velocity.y
		
		#scale = Vector2.ONE
		
		if player.isWallSliding():
			rotation = lerp(rotation, deg_to_rad(30) * player.get_wall_normal().x + snappedf(rotation, PI / 2), delta * 15)
	else:
		if Input.is_action_just_pressed("down"):
			scale.x = 2
			scale.y *= 0.5
		
		var floorRot = player.get_floor_normal().angle() + (PI / 2)
		
		if abs(rotation - floorRot) > 0.9:
			rotation = floorRot
		
		rotation = lerp(rotation, floorRot, delta * 10)
		
		if landed:
			rotation = 0
			scale.y = 1 - (landed / 800)
			scale.x = 1 + (landed / 800)
			landed = 0
	
	scale.y = lerp(scale.y, 1.0, delta * 7)
	scale.x = lerp(scale.x, 1.0, delta * 7)
	
	scale.y = clamp(scale.y, 0.25, INF)
	scale.x = clamp(scale.x, 0.1, INF)
	
	#modulate.h = abs(player.position.x / 400.)
	offset.y = (8 * pow(scale.y, -1) - 8)
	offset.x = 0

	if find_child("Grapple"):
		$"Grapple/GrappleCore".offset = offset

func _on_character_jumped():
	if not player.direction:
		rotation = 0
		scale.y = 1.5
		scale.x = 0.5
	else:
		scale = Vector2.ONE
		offset = Vector2.ZERO
