
extends Control

# Edit: IT-Karro 2019
# Simple Tetris-like demo, (c) 2012 Juan Linietsky
# Implemented by using a regular Control and drawing on it during the _draw() callback.
# The drawing surface is updated only when changes happen (by calling update())

# Member variables

var score = 0
var score1 = 0
var score2 = 0
var score3 = 1
var score4 = 1
var score_session = null
var score_label = null
var score_label1 = null
var score_shapes = null
var score_SPEED = null
var SPEED = 1
var alpha_block = 0.8
var cur_joy = null
const MAX_SHAPES = 9
var block = preload("../textures/block.png")
var arrow_d = load("res://textures/cursor.png")
var arrow_l = load("res://textures/cursor_2.png")
var block_colors = [
    # Add color
	#Color(1, 0.5, 0.5),
	#Color(0.5, 1, 0.5),
	#Color(0.5, 0.5, 1),
	#Color(0.8, 0.4, 0.8),
	#Color(0.8, 0.8, 0.4),
	#Color(0.4, 0.8, 0.8),
	#Color(0.8, 0.8, 0.8),
	#Color(0.0, 0.5, 0.5),
	#Color(0.2, 0.5, 0.5)
	
	# No color RGB + Alpha
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block),
	Color(0.0, 0.5, 0.5,alpha_block)
	]

var block_shapes = [
	[ Vector2(0, -1), Vector2(0, 0), Vector2(0, 1), Vector2(0, 2) ], # I
	[ Vector2(0, 0), Vector2(1, 0), Vector2(1, 1), Vector2(0, 1) ], # O
	[ Vector2(-1, 1), Vector2(0, 1), Vector2(0, 0), Vector2(1, 0) ], # S
	[ Vector2(1, 1), Vector2(0, 1), Vector2(0, 0), Vector2(-1, 0) ], # Z
	[ Vector2(-1, 1), Vector2(-1, 0), Vector2(0, 0), Vector2(1, 0) ], # L
	[ Vector2(1, 1), Vector2(1, 0), Vector2(0, 0), Vector2(-1, 0) ], # J
	[ Vector2(0, 1), Vector2(1, 0), Vector2(0, 0), Vector2(-1, 0) ], # T
	[ Vector2(0, 0), Vector2(-1, 1), Vector2(1, 1), Vector2(0, 1), Vector2(0, 2) ], # +
	[ Vector2(1, 0), Vector2(2, 1), Vector2(1, 1) ]  # [
	]

var block_rotations = [
	Matrix32(Vector2(1, 0), Vector2(0, 1), Vector2()),
	Matrix32(Vector2(0, 1), Vector2(-1, 0), Vector2()),
	Matrix32(Vector2(-1, 0), Vector2(0, -1), Vector2()),
	Matrix32(Vector2(0, -1), Vector2(1, 0), Vector2()),
	#Matrix32(Vector2(-1, -1), Vector2(-1, 1), Vector2()) # Add new rotations
	]

var width = 0
var height = 0

var cells = {}

var piece_active = false
var piece_shape = 0
var piece_pos = Vector2()
var piece_rot = 0


func piece_cell_xform(p, er = 0):
	var r = (4 + er + piece_rot) % 4
	return piece_pos + block_rotations[r].xform(p)


func _draw():
	var sb = get_stylebox("bg", "Tree") # Use line edit bg
	draw_style_box(sb, Rect2(Vector2(), get_size()).grow(3))
	
	
	var bs = block.get_size()
	for y in range(height):
		for x in range(width):
			if (Vector2(x, y) in cells):
				draw_texture_rect(block, Rect2(Vector2(x, y)*bs, bs), false, block_colors[cells[Vector2(x, y)]])
	
	if (piece_active):
		for c in block_shapes[piece_shape]:
			draw_texture_rect(block, Rect2(piece_cell_xform(c)*bs, bs), false, block_colors[piece_shape])


func piece_check_fit(ofs, er = 0):
	for c in block_shapes[piece_shape]:
		var pos = piece_cell_xform(c, er) + ofs
		if (pos.x < 0):
			return false
		if (pos.y < 0):
			return false
		if (pos.x >= width):
			return false
		if (pos.y >= height):
			return false
		if (pos in cells):
			return false
	return true

func new_piece():
	get_node("../score/sfx2").play("hit")
	piece_shape = randi() % MAX_SHAPES
	piece_pos = Vector2(width/2, 0)
	piece_active = true
	piece_rot = 0
	if (piece_shape == 0):
		piece_pos.y += 1
	
	if (not piece_check_fit(Vector2())):
		# Game over
		game_over()
		update()

func test_collapse_rows():
	var accum_down = 0
	get_node("Version").set_text("2019")
	get_node("gameover").set_text("SET_GUI_MESS_UP")
	get_node("Logo/AnimationPlayer").stop_all()
	get_node("BG/Sprite_ramka/AnimationPlayer").stop_all()
	get_node("BG/TextureFrame 3").hide()
	get_node("BG/TextureFrame 2").hide()
	get_node("BG/TextureFrame").show()
	score2 += accum_down+1 # Add Shapes Score
	score_shapes.set_text(str(score2)) # Set Shapes Score
	_add_text_TRASH()
	#SPEED = randf() # Add random Speed
	SPEED = rand_range(0.1,1) # Add Random Sec 0.1<=>1.0
	#SPEED += -0.01 # Add < 0 Speed
	score4 = SPEED # Add score4 Speed
	score_SPEED.set_text(str(score4)) # Add score4 Speed
	get_node("timer_add_shapes").set_wait_time(SPEED) # Change speed
	_add_text_SPEDD()
		
	for i in range(height):
		var y = height - i - 1
		var collapse = true
		for x in range(width):
			if (Vector2(x, y) in cells):
				if (accum_down):
					cells[Vector2(x, y + accum_down)] = cells[Vector2(x, y)]
			else:
				collapse = false
				if (accum_down):
					cells.erase(Vector2(x, y + accum_down))

		if (collapse):
			get_node("../Hit/sfx3").play("delete_line")
			get_node("Version").set_text("2019")
			get_node("Logo/AnimationPlayer").play("hit_01")
			get_node("BG/Sprite_ramka/AnimationPlayer").play("Lines_01")
			accum_down += 1
			score += accum_down*1
			score1 += accum_down*1
			get_node("../score/sfx2").play("hit")
			score_label.set_text(str(score))
			score_label1.set_text(str(score1))
			_add_text_HIT()
			_add_text_SMART()

func game_over():
	piece_active = false
	get_node("gameover").set_text("SET_GUI_GV")
	get_node("sfx").play("game_over")
	set_opacity(0.7)
	update()

func restart_pressed():
	score = 0
	score2 = 0
	score4 = 1
	score_label.set_text("0")
	score_shapes.set_text("0")
	score3 += 1 # Add Session
	score_session.set_text(str(score3)) # Add Session
	cells.clear()
	get_node("gameover").set_text("SET_GUI_CLEAR")
	_add_text_SESSION()
	set_opacity(1)
	piece_active = true
	get_node("../restart").release_focus()
	get_node("../restart/sfx4").play("clear")
	get_node("../Pause").grab_focus()
	update()


func piece_move_down():
	if (!piece_active):
		return
	if (piece_check_fit(Vector2(0, 1))):
		piece_pos.y += 1
		update()
	else:
		for c in block_shapes[piece_shape]:
			var pos = piece_cell_xform(c)
			cells[pos] = piece_shape
		test_collapse_rows()
		new_piece()

func piece_rotate():
	var adv = 1
	if (not piece_check_fit(Vector2(), 1)):
		return
	piece_rot = (piece_rot + adv) % 4
	get_node("../Grid/sfx_rot").play("rotate")
	update()

func _input(ie):
	if ie.type == InputEvent.MOUSE_MOTION:Input.set_custom_mouse_cursor(arrow_d)
	if Input.is_mouse_button_pressed(BUTTON_LEFT):Input.set_custom_mouse_cursor(arrow_l)
	if (not piece_active):
		return
	if (!ie.is_pressed()):
		return
	if (ie.is_action("move_left")):
		if (piece_check_fit(Vector2(-1, 0))):
			piece_pos.x -= 1
			update()
	elif (ie.is_action("move_right")):
		if (piece_check_fit(Vector2(1, 0))):
			piece_pos.x += 1
			update()
	elif (ie.is_action("move_down")):
		piece_move_down()
	elif (ie.is_action("rotate")):
		piece_rotate()
		
	elif (ie.is_action("pause")):
		_on_pause_button_pressed()
		
	elif (ie.is_action("reset")):
		restart_pressed()
		
	elif (ie.is_action("sound")):
		_on_pause_sfx()
		
	elif (ie.is_action("sound_on")):
		_on_pause_sfx_ON()

func setup(w, h):
	width = w
	height = h
	set_size(Vector2(w, h)*block.get_size())
	new_piece()
	get_node("timer_add_shapes").start()
	get_tree().set_pause(true)
	get_node("Pause_popup").show()
	
func _on_pause_button_pressed():
	get_tree().set_pause(true)
	get_node("Pause_popup/sfx5").play("end")
	get_node("gameover").set_text("SET_GUI_P")
	get_node("Pause_popup").show()
	get_node("Pause_popup/Play").grab_focus()
	set_opacity(0.7)

func _on_pause_popup_close_pressed():
	get_node("Pause_popup/sfx6").play("start")
	get_node("Pause_popup").hide()
	get_tree().set_pause(false)
	get_node("../Pause").grab_focus()
	set_opacity(1)
		
func _on_exit_game():
    get_tree().quit()
	
func _on_pause_sfx():
		AudioServer.set_fx_global_volume_scale(0)
		get_node("gameover").set_text("SET_GUI_S_OFF")
	
func _on_pause_sfx_ON():
	AudioServer.set_fx_global_volume_scale(1)
	get_node("gameover").set_text("SET_GUI_S_ON")
	
func _add_text_TRASH():
	if (score2 == 98):
		get_node("gameover").set_text("SET_GUI_T1")
	elif (score2 == 198):
		get_node("gameover").set_text("SET_GUI_T2")
	elif (score2 == 498):
		get_node("gameover").set_text("SET_GUI_T3")
			
func _add_text_SPEDD():
	if (SPEED < 0.3):
		get_node("../Monitor_Speed/Speed_UP1").play("speed_up")
		get_node("gameover").set_text("SET_GUI_ROCKET")
		get_node("BG/TextureFrame 2").show()
		get_node("BG/TextureFrame").hide()
	elif (SPEED > 0.9):
		get_node("gameover").set_text("SET_GUI_SLOW")
		get_node("BG/TextureFrame 3").show()
		get_node("BG/TextureFrame").hide()
			
func _add_text_SMART():
	if (score == 1):
		get_node("gameover").set_text("SET_GUI_S1")
	elif (score == 10):
		get_node("gameover").set_text("SET_GUI_S2")
	elif (score == 25):
		get_node("gameover").set_text("SET_GUI_S3")
	
func _add_text_HIT():
	if (score1 == 25):
		get_node("gameover").set_text("SET_GUI_H1")
	elif (score1 == 50):
		get_node("gameover").set_text("SET_GUI_H2")
	elif (score1 == 100):
		get_node("gameover").set_text("SET_GUI_H3")
		
func _add_text_SESSION():
	if (score3 == 3):
		get_node("gameover").set_text("SET_GUI_SSE_1")
	elif (score3 == 5):
		get_node("gameover").set_text("SET_GUI_SSE_2")
	elif (score3 == 10):
		get_node("gameover").set_text("SET_GUI_SSE_3")
				
# Add GUI arrow		
func _key_gui_down():
	piece_move_down()
	
func _key_gui_up():
	piece_rotate()
	
func _key_gui_right():
	if (piece_check_fit(Vector2(1, 0))):
		piece_pos.x += 1
		update()
			
func _key_gui_left():
	if (piece_check_fit(Vector2(-1, 0))):
		piece_pos.x -= 1
		update()
	
# bbCODE
func _on_RichTextLabel_meta_clicked(meta):
	get_node("Pause_popup/sfx6").play("start")
	OS.shell_open(meta)
	
func _bbcode_delete():
	get_node("Pause_popup/HTML_LINKS").queue_free()
	get_node("Pause_popup/Help").queue_free()
	
func _get_help_timer():
	get_node("Pause_popup/Label_Credits").set_text("KEY_CONTROL_K")
	get_node("Pause_popup/Label_Credits/AnimationPlayer_Text_Line").set_speed(0.1)
	
func _ready():
	setup(20,25) # Stakan W/H
	set_opacity(0.9)
	rand_seed(OS.get_unix_time())
	randi(OS.get_unix_time())
	get_node("BG/TextureFrame 2").hide()
	get_node("BG/TextureFrame 3").hide()
	get_node("../Grid/sfx_bg").play("bg")
	get_node("../Hit/sfx3").play("delete_line")
	score_label = get_node("../score")
	score_label1 = get_node("../score1")
	score_shapes = get_node("../score2")
	score_session = get_node("../score3")
	score_SPEED = get_node("../score4")
	get_node("Pause_popup/Play").grab_focus()
	set_process_input(true)
