extends CharacterBody2D

@onready var partPoints = $PartPoints
@onready var partsContainer = $PartsContainer
@onready var coyoteTimer = $CoyoteTimer


var part = "res://scenes/NewBlocks/part.tscn"
var block1x1 = "res://scenes/NewBlocks/1x1/1x1.tscn"


var coyoteTime = 0.5

var type = GLOBAL.BLOCKTYPES.LIGHT
var expand = false

@export var id = 0

var expanding = false

var stopped = false

@export var offset = false

func _physics_process(delta: float) -> void:
	if isCurrent() and not GLOBAL.blockStopped and not stopped:
		if isBottomColliding():
			if coyoteTimer.is_stopped():
				coyoteTimer.start(coyoteTime)
		if Input.is_action_just_pressed("rotate_left"):
			rotateBlock(1)
		elif Input.is_action_just_pressed("rotate_right"):
			rotateBlock(2)
		if Input.is_action_just_pressed("left"):
			
			if not isLeftColliding():
				global_position.x -= GLOBAL.GRID
		elif Input.is_action_just_pressed("right"):
			if not isRightColliding():
				global_position.x += GLOBAL.GRID
		if Input.is_action_pressed("down"):
			velocity = get_gravity() * delta * GLOBAL.SPEED.MAX
		else:
			velocity = get_gravity() * delta * GLOBAL.currentSpeed


	if is_on_floor():
		position = position.snapped(Vector2(32,32))

	if isCurrent() and not expanding and not GLOBAL.blockStopped:
		move_and_slide()
	else:
		velocity = Vector2.ZERO

func expandBlocks():
	expanding = true
	scale = Vector2(2,2)
	position -= Vector2(32,32)
	snapPosition()
	for i in range(0,5):
		if isCollidingBorder():
			if isCollidingBorder():
				position.x += GLOBAL.GRID
			if isCollidingBorder():
				position.x += GLOBAL.GRID
			if isCollidingBorder():
				position.x -= GLOBAL.GRID
			if isCollidingBorder():
				position.x -= GLOBAL.GRID
			if isCollidingBorder():
				position.x -= GLOBAL.GRID
			if isCollidingBorder():
				position.x -= GLOBAL.GRID
			if isCollidingBorder():
				position.x += GLOBAL.GRID
			if isCollidingBorder():
				position.x += GLOBAL.GRID
			if isCollidingBorder():
				position.y -= GLOBAL.GRID
	
	for i in partsContainer.get_children():
		if i != null:
			i.removeOverlapp()
	#splitParts()

func addParts():
	for i in partPoints.get_children():
		var newPart = load(part).instantiate()
		partsContainer.add_child(newPart)
		var look = 0
		if not expand and type == GLOBAL.BLOCKTYPES.HEAVY:
			look = 1
		elif expand and not type == GLOBAL.BLOCKTYPES.HEAVY:
			look = 2
		elif expand and type == GLOBAL.BLOCKTYPES.HEAVY:
			look = 3 
		newPart.init(i.position,look)
		
func splitParts():
	for i in $PartsContainer.get_children():
		var newBlock = load(block1x1).instantiate()
		get_parent().add_child(newBlock)
		newBlock.init(i.global_position, expand)
		newBlock.setColor(modulate)
	queue_free()

func setColor(color):
	modulate = color

func init(pos, scaler=null):
	
	if scaler != null:
		if scaler:
			expand = scaler
			#$AnimationPlayer.play("Expand")
			scale = Vector2(2,2)
	addParts()
	id = GLOBAL.getNewID()
	GLOBAL.currentID = id
	snapPosition()
	global_position = pos
	if offset:
		snapPosition()

func setNewID():
	id = GLOBAL.getNewID()

func isCurrent():
	return GLOBAL.currentID == id

func snapPosition(): #x :bool, y: bool
	position = position.snapped(Vector2(64,64))

func rotateBlock(direction):
	match direction:
		1: 
			rotation_degrees -= 90
			for i in partsContainer.get_children():
				i.rotation_degrees += 90
			for j in range(0,3):
				if isColliding():
					global_position.x -= GLOBAL.GRID
					if isColliding():
						global_position.x += GLOBAL.GRID*2
						if isColliding():
							global_position.x -= GLOBAL.GRID
							for s in range(0,3):
								rotation_degrees -= 90
								for i in partsContainer.get_children():
									i.rotation_degrees += 90
						else:
							break
					else:
						break
				else:
					break
		2: 
			rotation_degrees += 90
			for i in partsContainer.get_children():
				i.rotation_degrees -= 90
			for j in range(0,3):
				if isColliding():
					global_position.x -= GLOBAL.GRID
					if isColliding():
						global_position.x += GLOBAL.GRID*2
						if isColliding():
							global_position.x -= GLOBAL.GRID
							for s in range(0,3):
								rotation_degrees += 90
								for i in partsContainer.get_children():
									i.rotation_degrees -= 90
						else:
							break
					else:
						break
				else:
					break

func isLeftColliding():
	var colliding = false
	for i in partsContainer.get_children():
		if i.isLeftColliding():
			colliding = true
	return colliding

func isRightColliding():
	var colliding = false
	for i in partsContainer.get_children():
		if i.isRightColliding():
			colliding = true
	return colliding

func isBottomColliding():
	var colliding = false
	for i in partsContainer.get_children():
		if i.isBottomColliding():
			colliding = true
	return colliding

func isColliding() -> bool:
	var collided = false
	for i in get_children():
		if is_instance_of(i,RayCast2D):
			i.force_raycast_update()
			var collider = i.get_collider()
			if collider != null:
				if collider.is_in_group("Block"):
					if collider.id != GLOBAL.currentID:
						collided = true
				elif collider.is_in_group("Border"):
					collided = true
	return collided


func isCollidingBorder() -> bool:
	var collided = false
	for i in get_children():
		if is_instance_of(i,RayCast2D):
			i.force_raycast_update()
			var collider = i.get_collider()
			if collider != null:
				if collider.is_in_group("Border"):
					collided = true
	return collided

func _on_animation_player_animation_finished(anim_name: StringName) -> void:
	if anim_name == "Expand":
		snapPosition()
		#position -= Vector2(32,32)
		splitParts()


func _on_coyote_timer_timeout() -> void:
	if isBottomColliding():
		stopped = true
		GLOBAL.blockStopped = true
		if expand:
			expandBlocks()
