extends Node2D

@onready var player = $"../../"
@onready var sprite = $"../"

@onready var grappleCore = $"GrappleCore"

var grappleProjectile = preload("res://Player/GrappleHook/GrappleHookProjectile/GrappleHookProjectile.tscn")

var proj = null
var retractingProj = []

var grappleSpeed = Vector2.ZERO
var retractDur = 0
var retractStart = Vector2.ZERO

var grappleDur = 0

var grappling = false

var grapples = 0

var grappleShootParti = preload("res://Particles/Grapple/GrappleParti.tscn")

func renderLine(proj):
	var grappleLine = proj.get_node("GrappleLine")
	var grappleBord = proj.get_node("GrappleBord")
	
	var grapOffset = grappleCore.offset * sprite.scale
	
	grappleLine.set_point_position(1, player.position + grapOffset)
	grappleBord.set_point_position(1, player.position + grapOffset)
	
	grappleLine.set_point_position(0, proj.position)
	grappleBord.set_point_position(0, proj.position)
	
	var curve = Curve.new()
	curve.add_point(Vector2(0, 1))
	curve.add_point(Vector2(1, sprite.scale.y))
	
	grappleLine.width_curve = curve
	grappleBord.width_curve = curve

func launch(delta):
	if proj:
		player.jumps = player.MAX_JUMPS - 1
		var distance = proj.global_position - player.global_position
		var grappleVeloc = distance.normalized() * (grappleSpeed + distance.length())
		player.launch(grappleVeloc.x)
		player.velocity.y = lerp(player.velocity.y, grappleVeloc.y, 10 * delta)

func grappleStart():
	grappleSpeed = (500 + clamp(player.velocity.length(), 500, 2000))
	grappleDur = 0.1
	grappling = true

func _physics_process(delta):
	if not Input.is_action_pressed("pullGrapple"):
		grappleDur -= delta
	
	var moveVector = (get_global_mouse_position() - player.position).normalized()
	
	if player.is_on_floor():
		grapples = 2
	
	#$"parti".emitting = grappling
	
	if Input.is_action_just_pressed("pullGrapple") and not proj and grapples:
		grapples -= 1
		
		proj = grappleProjectile.instantiate()
		
		proj.position = player.position
		proj.rotation = moveVector.angle()
		
		modulate = Color8(0, 255, 150)
		proj.modulate = modulate
	
		proj.velocity = (moveVector * (1500 + player.velocity.dot(moveVector))) #+ (player.velocity.normalized() * player.velocity.dot(moveVector))
		print(player.velocity.dot(moveVector))
		#grappleDur = 10
		add_child(proj)
		
		#var parti = grappleShootParti.instantiate()
		#parti.rotation = proj.rotation
		#parti.position = proj.position
		#parti.process_material.initial_velocity_min = (proj.velocity.length() + player.velocity.length()) / 6
		#add_child(parti)
	#else:
	
	if proj and grappleDur > 0 and (player.position - proj.position).length() > 15 and not Input.is_action_just_pressed("jump"):
		launch(delta)
	elif proj and grappling:
		player.jumps = player.MAX_JUMPS
		player.falling = false
		#player.velocity.y = player.JUMP_VELOCITY
		grappleDur = 0
		
		retractingProj.append({"proj": proj, "retractStart": proj.position, "retractDur": 0})
		proj = null
		grappling = false
		
func _process(delta):
	for projData in retractingProj:
		var proj = projData.proj
		if is_instance_valid(proj):
			proj.position = lerp(projData.retractStart, player.position, projData.retractDur)
			projData.retractDur += delta * 4 / ((projData.retractStart - player.position).length() / 300)
			renderLine(proj)
			if projData.retractDur >= 1:
				if proj.find_child("parti"):
					var parti = proj.get_node("parti")
					parti.emitting = false
					parti.reparent(self)
				proj.queue_free()
				proj = null
				retractDur = 0
		else:
			retractingProj.remove_at(retractingProj.find(projData))
		
	if is_instance_valid(proj):
		renderLine(proj)
		
