tool
extends Control

signal return_dice(dice_number)
signal do_movement(movement_range)
signal do_damage(damage, damage_range)
signal do_effect(effect, effect_range)
signal card_removed(card_self)

const TYPE_COLORS = [
	Color("#db4758"), # DAMAGE
	Color("#3cc361"), # UTILITY
	Color("#bcb64f"), # SPECIAL
	Color("#bc5ec6"), # EFFECT
	Color("#a4a4a4"), # MOVEMENT
]

const dice_node = preload("res://UI/Dice.tscn")
const dice_texture_string : String = "res://Assets/Dice/Dice%s.png"

export (Resource) var card_info

var input_dice = []
var addition_dice_amount : int setget _set_addition_dice
var hovering_dice setget _set_hovering_dice


func _set_hovering_dice(dice_value):
	var input_dice0 = $VBox/AutoGrid.get_node_from_grid("InputDice0")
	
	if hovering_dice == dice_value:
		return
	
	hovering_dice = dice_value
	
	#remove the dice preview if not hovering
	if dice_value == null:
		var input_dice_children = input_dice0.get_children()
		if len(input_dice_children) <= 1:
			return
		var old_dice = input_dice_children[1]
		input_dice0.remove_child(old_dice)
		return
	
	var new_dice = dice_node.instance()
	new_dice.dice_value = dice_value
	input_dice0.add_child(new_dice)


func _set_addition_dice(new_amount):
	addition_dice_amount = new_amount
	$VBox/AutoGrid.get_node_from_grid("InputDice0").get_child("Number").text = String(new_amount)


func _ready():

	# change the color of the panel to match the appropriate type
	var card_style = $PanelContainer.get('custom_styles/panel').duplicate(true)
	card_style.set_bg_color(TYPE_COLORS[card_info.type])
	$PanelContainer.set('custom_styles/panel', card_style)
	
	# add more input dice if needed
	for i in range(1, card_info.number_of_dice):
		var new_input_dice = get_node("VBox/AutoGrid/InputDice0").duplicate(true)
		new_input_dice.name = "InputDice%s" % i
		$VBox/AutoGrid.add_child(new_input_dice)
	
	# change the name and description
	$VBox/Name.text = card_info.name
	$VBox/Description.text = card_info.description
	
	#maybe set the addition amount
	if card_info.addition_dice:
		self.addition_dice_amount = card_info.addition_amount
	
	# show the requirements for a dice
	# TODO more difference from addition, smaller font, >, <, etc. 
	if len(card_info.accepted_dice) != 0:
		var dice_string : String = ""
		for num in card_info.accepted_dice:
			dice_string += String(num)
			dice_string += ","
		
		dice_string = dice_string.trim_suffix(",")
		
		$VBox/AutoGrid/InputDice0/Number.text = dice_string


func dice_inputted(dice_number):
	
	# -- SINGLE DICE CHECKS --
	if dice_number == null:
		return
	
	#check if dice is within dice range
	if dice_number < 1 and dice_number > 6:
		return
	
	#if accepted dice is specified, check if the dice is in the list
	if (len(card_info.accepted_dice) != 0 and
		not dice_number in card_info.accepted_dice):
		emit_signal("return_dice", dice_number)
		return
	
	#add the dice to the input if it passes individual checks
	input_dice.append(dice_number)
	
	# -- MULTI DICE CHECKS --
	#if same dice requirement, then check if true
	if card_info.same_dice_requirement:
		var same_dice = true
		
		for i in range(1, len(input_dice)):
			if input_dice[i-1] != input_dice[i]:
				same_dice = false
				break
		
		# if not all the same dice then return all of the dice
		if not same_dice:
			for _i in len(input_dice):
				emit_signal("return_dice", input_dice[0])
				input_dice.remove(0)
	
	
	# Put the Dice in the slot
	var input_dice0 = $VBox/AutoGrid.get_node_from_grid("InputDice0")
	input_dice0.texture = load(dice_texture_string % dice_number)
	
	
	# -- RUN DICE CHECKS --
	if card_info.addition_dice:
		self.addition_dice_amount -= dice_number
		input_dice.remove(0)
		if addition_dice_amount > 0:
			return
		else:
			run_card()
	
	if (len(input_dice) == card_info.number_of_dice
		and not card_info.addition_dice):
		run_card()


func run_card():
	# calculate the damage amount
	var damage = card_info.damage_amount_addition
	for dice_number in input_dice:
		damage += card_info.damage_dice_multiplyer * dice_number
	emit_signal("do_damage", damage, card_info.effect_damage_range)
	
	# calculate the damage amount
	var movement = card_info.move_amount_addition
	for dice_number in input_dice:
		movement += card_info.move_dice_multiplyer * dice_number
	emit_signal("do_movement", movement)
	
	# do any utility dice returns
	for dice_number in input_dice:
		
		if Global.EFFECT.SPLIT in card_info.effects:
			var halfed_dice = float(dice_number)/2.0
			
			var new_dice1 = halfed_dice
			var new_dice2 = halfed_dice
			
			#if decimal value, then minus half and add half
			if decimals(halfed_dice) != 0:
				new_dice1 -= 0.5
				new_dice2 += 0.5
			
			emit_signal("return_dice", new_dice1)
			emit_signal("return_dice", new_dice2)
		
		if Global.EFFECT.DOUBLE in card_info.effects:
			var new_dice1 = dice_number * 2
			var new_dice2 = 0
			
			#dice has to be smaller than 7
			if new_dice1 > 6:
				new_dice1 -= 6
				new_dice2 = 6
				
			emit_signal("return_dice", new_dice1)
			if new_dice2 != 0: emit_signal("return_dice", new_dice1)
		
		if Global.EFFECT.HALF in card_info.effects:
			var new_dice = float(dice_number)/2.0
			
			#if decimal valued, add 0.5 or - 0.5 at random
			if decimals(new_dice) != 0:
				new_dice += round(randf()) - 0.5
				
			emit_signal("return_dice", new_dice)
		
		if Global.EFFECT.FLIP in card_info.effects:
			# all opposite sides of a dice add up to 7
			emit_signal("return_dice", 7 - dice_number)
		
		if Global.EFFECT.DUPLICATE in card_info.effects:
			emit_signal("return_dice", dice_number)
			emit_signal("return_dice", dice_number)
	
	# for each effect, emit do effect with the range
	for effect in card_info.effects:
		emit_signal("do_effect", effect, card_info.effect_damage_range)
	
	
	#clear the input dice
	input_dice = []
	
	#card is used, disappear
	emit_signal("card_removed", self)
	queue_free()

