extends Node2D

#		 	----- UTILS ------
# 	This object is for code I want to execute in any object anytime.
# 	For instance, fade-in-and-out a single object on the fly, or flash an object for N seconds.
# 	Another use can be a global Timer for an event.

onready var tween

signal fade_in_complete
signal fade_out_complete
signal fade_expand_complete
signal fade_collapse_complete

var is_ready = false


func is_touch():
	return OS.has_touchscreen_ui_hint()


func get_exec_dir():
	return OS.get_executable_path().get_base_dir()

func fade_position(object, vector_pos, speed):
	if not object: return
	if object.get_class() == "ColorRect":
		tween.interpolate_property(object, "rect_position", object.rect_position, vector_pos, speed, Tween.TRANS_QUINT, Tween.EASE_OUT)
	else:
		tween.interpolate_property(object, "position", object.position, vector_pos, speed, Tween.TRANS_QUINT, Tween.EASE_OUT)		
	tween.start()


# ---------- Freezes a node (like a pause) -------

func freeze_node(node, freeze):
	if not node: return
	node.set_process(!freeze)
	node.set_physics_process(!freeze)
	node.set_process_input(!freeze)
	node.set_process_internal(!freeze)
	node.set_process_unhandled_input(!freeze)
	node.set_process_unhandled_key_input(!freeze)

func freeze_scene(node, freeze):
	freeze_node(node, freeze)
	if not node: return
	for c in node.get_children():
		if not c: return
		freeze_scene(c, freeze)


# --------- EXECUTE AFTER --------


func execute_after(object, method, timer):
	if not object and not is_instance_valid(object): return
	tween.interpolate_callback(self, timer, "_on_execute_after", object, method)
	tween.start()

func _on_execute_after(object, method):
	if not object or not is_instance_valid(object): return
	object.call_deferred(method)
	

func interpolate(object, event, start, finish, speed = 0.1):
	if not object or not is_ready or not is_instance_valid(object): return
	tween.interpolate_property(object, event, start, finish, speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.start()

# --------- Fade In -----------

func fade_in(object, speed = 0.1):
	if not object or not is_instance_valid(object): return
	speed = float(speed)
	tween.interpolate_property(object, "modulate", Color(1,1,1,0), Color(1,1,1,1), speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_callback(self, speed + 0.05, "_on_fade_in")
	tween.start()

func _on_fade_in():
	emit_signal("fade_in_complete")


# --------- Fade Out -----------

func fade_out(object, speed = 0.1):
	if not object or not is_instance_valid(object) or not is_ready: return
	speed = float(speed)
	tween.interpolate_property(object, "modulate", Color(1,1,1,1), Color(1,1,1,0), speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_callback(self, speed + 0.05, "_on_fade_in")
	tween.start()

func _on_fade_out():
	emit_signal("fade_out_complete")


func hide_object(object):
	fade_out(object, 0.0005)

func show_object(object):
	fade_in(object, 0.0005)

# --------- Fade Expand Code -----------

func fade_expand(object, size, speed = 0.3):
	if not object or not is_instance_valid(object): return
	tween.interpolate_property(object, "rect_size", Vector2(0, 0), Vector2(size.x, 10), speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_property(object, "modulate", Color(1,1,1,0), Color(1,1,1,1), speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_callback(self, speed + 0.05, "_on_fade_expand", object, size, speed)
	tween.start()

func _on_fade_expand(object, size, speed = 0.3):
	if not object or not is_instance_valid(object): return
	tween.interpolate_property(object, "rect_size", Vector2(size.x, 10), size, speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_callback(self, speed + 0.05, "_on_fade_expand_finish")
	tween.start()

func _on_fade_expand_finish():
	emit_signal("fade_expand_complete")



# --------- Fade Collapse Code -----------

func fade_collapse(object, speed = 0.3):
	if not object or not is_instance_valid(object): return
	tween.interpolate_property(object, "rect_size", object.rect_size, Vector2(10, object.rect_size.y), speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_callback(self, speed + 0.05, "_on_fade_collapse", object, speed)
	tween.start()

func _on_fade_collapse(object, speed = 0.3):
	if not object or not is_instance_valid(object): return
	tween.interpolate_property(object, "rect_size", Vector2(10, object.rect_size.y), Vector2(10, 10), speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_property(object, "modulate", Color(1,1,1,1), Color(1,1,1,0), speed, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
	tween.interpolate_callback(self, speed + 0.05, "_on_fade_collapse_finish")
	tween.start()

func _on_fade_collapse_finish():
	emit_signal("fade_collapse_complete")



# --------- OTHERS -----------

func file_exist(file):
	var exists = false
	var fileitem = File.new()
	if fileitem.file_exists(file) or fileitem.file_exists(file + ".import"): exists = true
	fileitem.close()
	return exists


func merge_dict(dest, source):
	for key in source:                     # go via all keys in source
		if dest.has(key):                  # we found matching key in dest
			var dest_value = dest[key]     # get value 
			var source_value = source[key] # get value in the source dict           
			if typeof(dest_value) == TYPE_DICTIONARY:       
				if typeof(source_value) == TYPE_DICTIONARY: 
					merge_dict(dest_value, source_value)  
				else:
					dest[key] = source_value # override the dest value
			else:
				dest[key] = source_value     # add to dictionary 
		else:
			dest[key] = source[key]          # just add value to the dest


func seconds_to_timer(seconds):
	
	var hour = 0
	var minute = 0
	var second = 0
	
	while seconds > 3599:
		hour = hour + 1
		seconds = seconds - 3600
	while seconds > 59:
		minute = minute + 1
		seconds = seconds - 60
	second = seconds
	
	var time_string = ""
	
	#if hour < 10:
	#	time_string = "0"
	#time_string = time_string + str(hour) + ":"
	#if minute < 10:
	#	time_string = time_string + "0"
	time_string = time_string + str(minute) + ":"
	if second < 10:
		time_string = time_string + "0"
	time_string = time_string + str(second)
	
	return time_string

func random(counter):
	randomize()
	return randi() % counter

func load_file(file_path):
	return ResourceLoader.load(file_path, "", true)

func has_file(file):
	var save_file = File.new()
	var exists = save_file.file_exists(file)
	save_file.close()
	return exists


func get_sprite_rect2(object):
	return Rect2(object.position, object.texture.get_size() * object.scale)

# --------- OTHERS -----------

func _ready():
	tween = Tween.new()
	add_child(tween)
	#call_deferred("add_child", tween)
	pause_mode = Node2D.PAUSE_MODE_PROCESS
	is_ready = true
