extends TextureRect
#extends Sprite2D
## The card class
##
## Represents an instance of a card to be displayed on the tabletop.
## Contains helper text for the text, the cards ID, and the image path.

enum pivot {
	ROTATE_0,
	ROTATE_90,
	ROTATE_180,
	ROTATE_270
}

var current_pivot = pivot.ROTATE_0

var card_id: String
var card_name: String
var card_type: String
var oracle_text: String

var is_dragging = false
var is_pivot = false

var delay = 5.0
var mouse_offset: Vector2



func _pivot() -> int:
	var deg: int
	match current_pivot:
		pivot.ROTATE_0:
			deg = 0
		pivot.ROTATE_90:
			deg = 90
		pivot.ROTATE_180:
			deg = 180
		pivot.ROTATE_270:
			deg = 270
	return deg
	

func _physics_process(delta: float) -> void:
	if is_dragging == true:
		var tween = get_tree().create_tween()
		tween.tween_property(self, "position", get_global_mouse_position() - mouse_offset.rotated(deg_to_rad(-1.0 * _pivot())), delay * delta)
	if is_pivot == true:
		var tween = get_tree().create_tween()
		tween.tween_property(self, "rotation_degrees", _pivot(), delta * delay)
		is_pivot = false
		

func _gui_input(event: InputEvent) -> void:
	if event is not InputEventMouseButton:
		return
	match event.button_index:
		MOUSE_BUTTON_LEFT:
			if event.pressed:
				is_dragging = true 
				mouse_offset = get_global_mouse_position() - global_position
			else:
				is_dragging = false
		MOUSE_BUTTON_RIGHT:
			pass

	
func _unhandled_key_input(event: InputEvent) -> void:
	if not event.is_action_pressed("default_action"):
		return
	if current_pivot == pivot.ROTATE_0:
		current_pivot = pivot.ROTATE_90
		is_pivot = true
	else:
		current_pivot = pivot.ROTATE_0
		is_pivot = true

func _card_error(error_type: String) -> String:
	return "ERROR::CARD::%s::%s::%s::\n" % [card_id, card_name, error_type]


func init(id: String) -> void:
	card_id = id
	

func _ready() -> void:
	var load_status = _load_card()
	if load_status != OK:
		# TODO: No need to push another error as the failure state of loading does that already,
		# if the card is not cached, perhaps a placeholder blank card can be used instead?
		# Setting that up can be put here later...
		push_error("Failed to load card.")
	
	set_pivot_offset(size / 2)


func _load_card() -> Error:
	if _load_data() != OK:
		return FAILED

	if _load_image() != OK:
		return FAILED

	return OK


func _load_data() -> Error:
	var cached_json = FileAccess.get_file_as_string("user://card_cache/" + card_id + "/card.json")

	if cached_json.is_empty():
		push_error("%s\nCard json data was not found in cache" % _card_error("CACHE"))
		return FAILED

	var card_json = JSON.parse_string(cached_json)

	if card_json == null:
		push_error("%s\nCard json data is could not be parsed as valid json" % _card_error("DATA"))
		return FAILED

	card_name = card_json["name"]
	card_type = card_json["type_line"]
	oracle_text = card_json["oracle_text"]

	return OK


func _load_image() -> Error:
	# NOTE: Assuming we're going with using the .png cards on board.
	var cached_img = FileAccess.get_file_as_bytes("user://card_cache/" + card_id + "/card.png")

	if cached_img.is_empty():
		push_error("%sCard on-board image was not found in cache" % _card_error("CACHE"))
		return FAILED

	var image = Image.new()
	var image_status: Error = image.load_png_from_buffer(cached_img)

	if image_status != OK:
		push_error("%sCard on-board image failed to load correctly" % _card_error("IMAGE"))
		return FAILED


	# TODO: Get the size from the node or some constant variable.
	image.resize(int(size.x), int(size.y), Image.INTERPOLATE_LANCZOS)
	
	

	var image_texture = ImageTexture.new()
	image_texture.set_image(image)

	#expand_mode = TextureRect.EXPAND_FIT_WIDTH
	texture = image_texture

	return OK