extends ConfirmationDialog

var aspect_ratio := 1.0
var recent_sizes := []
var templates: Array[Template] = [
	# Basic
	Template.new(Vector2i(16, 16)),
	Template.new(Vector2i(32, 32)),
	Template.new(Vector2i(64, 64)),
	Template.new(Vector2i(128, 128)),
	# Nintendo
	Template.new(Vector2i(160, 144), "GB"),
	Template.new(Vector2i(240, 160), "GBA"),
	Template.new(Vector2i(256, 224), "NES (NTSC)"),
	Template.new(Vector2i(256, 240), "NES (PAL)"),
	Template.new(Vector2i(512, 448), "SNES (NTSC)"),
	Template.new(Vector2i(512, 480), "SNES (PAL)"),
	Template.new(Vector2i(646, 486), "N64 (NTSC)"),
	Template.new(Vector2i(786, 576), "N64 (PAL)"),
	# Sega
	Template.new(Vector2i(256, 192), "SMS (NTSC)"),
	Template.new(Vector2i(256, 224), "SMS (PAL)"),
	Template.new(Vector2i(160, 144), "GG"),
	Template.new(Vector2i(320, 224), "MD (NTSC)"),
	Template.new(Vector2i(320, 240), "MD (PAL)"),
	# NEC
	Template.new(Vector2i(256, 239), "PC Engine"),  #256×224 to 512×242 (mostly 256×239)
	# DOS
	Template.new(Vector2i(320, 200), "DOS EGA"),
	Template.new(Vector2i(320, 200), "DOS VGA"),
	Template.new(Vector2i(620, 480), "DOS SVGA"),
	Template.new(Vector2i(640, 200), "DOS CGA (2-Colour)"),
	Template.new(Vector2i(320, 200), "DOS CGA (4-Colour)"),
	Template.new(Vector2i(160, 240), "DOS CGA (Composite)"),
	Template.new(Vector2i(160, 240), "Tandy"),
	# Commodore
	Template.new(Vector2i(320, 200), "Amiga OCS LowRes (NTSC)"),
	Template.new(Vector2i(320, 256), "Amiga OCS LowRes (PAL)"),
	Template.new(Vector2i(640, 200), "Amiga OCS HiRes  (NTSC)"),
	Template.new(Vector2i(640, 256), "Amiga OCS HiRes  (PAL)"),
	Template.new(Vector2i(1280, 200), "Amiga ECS Super-HiRes  (NTSC)"),
	Template.new(Vector2i(1280, 256), "Amiga ECS SuperHiRes  (PAL)"),
	Template.new(Vector2i(640, 480), "Amiga ECS Multiscan"),
	Template.new(Vector2i(320, 200), "C64"),
	# Sinclair
	Template.new(Vector2i(256, 192), "ZX Spectrum"),
]

@onready var templates_options := %TemplatesOptions as OptionButton
@onready var ratio_box := %AspectRatioButton as TextureButton
@onready var width_value := %WidthValue as SpinBox
@onready var height_value := %HeightValue as SpinBox
@onready var portrait_button := %PortraitButton as Button
@onready var landscape_button := %LandscapeButton as Button
@onready var fill_color_node := %FillColor as ColorPickerButton
@onready var recent_templates_list := %RecentTemplates as ItemList


class Template:
	var resolution: Vector2i
	var name: String

	func _init(_resolution: Vector2i, _name := "") -> void:
		resolution = _resolution
		name = _name


func _ready() -> void:
	width_value.value = Global.default_width
	height_value.value = Global.default_height
	aspect_ratio = width_value.value / height_value.value
	fill_color_node.color = Global.default_fill_color
	fill_color_node.get_picker().presets_visible = false

	_create_option_list()


func _on_CreateNewImage_about_to_show():
	recent_sizes = Global.config_cache.get_value("templates", "recent_sizes", [])
	_create_recent_list()


func _create_option_list() -> void:
	var i := 1
	for template in templates:
		if template.name != "":
			templates_options.add_item(
				"{width}x{height} - {name}".format(
					{
						"width": template.resolution.x,
						"height": template.resolution.y,
						"name": template.name
					}
				),
				i
			)
		else:
			templates_options.add_item(
				"{width}x{height}".format(
					{"width": template.resolution.x, "height": template.resolution.y}
				),
				i
			)

		i += 1


func _create_recent_list() -> void:
	recent_templates_list.clear()
	for recent_size in recent_sizes:
		recent_templates_list.add_item(
			"{width}x{height}".format({"width": recent_size.x, "height": recent_size.y})
		)


func _on_CreateNewImage_confirmed() -> void:
	var width: int = width_value.value
	var height: int = height_value.value
	var image_size := Vector2i(width, height)
	if image_size in recent_sizes:
		recent_sizes.erase(image_size)
	recent_sizes.insert(0, image_size)
	if recent_sizes.size() > 10:
		recent_sizes.resize(10)
	Global.config_cache.set_value("templates", "recent_sizes", recent_sizes)
	var fill_color: Color = fill_color_node.color

	var proj_name: String = $VBoxContainer/ProjectName/NameInput.text
	if !proj_name.is_valid_filename():
		proj_name = tr("untitled")

	var new_project := Project.new([], proj_name, image_size)
	new_project.layers.append(PixelLayer.new(new_project))
	new_project.fill_color = fill_color
	new_project.frames.append(new_project.new_empty_frame())
	Global.projects.append(new_project)
	Global.tabs.current_tab = Global.tabs.get_tab_count() - 1
	Global.canvas.camera_zoom()


func _on_AspectRatioButton_toggled(_button_pressed: bool) -> void:
	aspect_ratio = width_value.value / height_value.value


func _on_SizeValue_value_changed(value: float) -> void:
	if ratio_box.button_pressed:
		if width_value.value == value:
			height_value.value = width_value.value / aspect_ratio
		if height_value.value == value:
			width_value.value = height_value.value * aspect_ratio

	toggle_size_buttons()


func toggle_size_buttons() -> void:
	portrait_button.toggled.disconnect(_on_PortraitButton_toggled)
	landscape_button.toggled.disconnect(_on_LandscapeButton_toggled)
	portrait_button.button_pressed = width_value.value < height_value.value
	landscape_button.button_pressed = width_value.value > height_value.value

	portrait_button.toggled.connect(_on_PortraitButton_toggled)
	landscape_button.toggled.connect(_on_LandscapeButton_toggled)


func _on_TemplatesOptions_item_selected(id: int) -> void:
	# If a template is chosen while "ratio button" is pressed then temporarily release it
	var temporary_release := false
	if ratio_box.button_pressed:
		ratio_box.button_pressed = false
		temporary_release = true

	if id > 0:
		width_value.value = templates[id - 1].resolution.x
		height_value.value = templates[id - 1].resolution.y
	else:
		width_value.value = Global.default_width
		height_value.value = Global.default_height

	if temporary_release:
		ratio_box.button_pressed = true


func _on_RecentTemplates_item_selected(id):
	#if a template is chosen while "ratio button" is pressed then temporarily release it
	var temporary_release = false
	if ratio_box.button_pressed:
		ratio_box.button_pressed = false
		temporary_release = true

	width_value.value = recent_sizes[id].x
	height_value.value = recent_sizes[id].y

	if temporary_release:
		ratio_box.button_pressed = true


func _on_PortraitButton_toggled(button_pressed: bool) -> void:
	if !button_pressed or height_value.value > width_value.value:
		toggle_size_buttons()
		return
	switch_width_height()


func _on_LandscapeButton_toggled(button_pressed: bool) -> void:
	if !button_pressed or width_value.value > height_value.value:
		toggle_size_buttons()
		return
	switch_width_height()


func switch_width_height() -> void:
	width_value.value_changed.disconnect(_on_SizeValue_value_changed)
	height_value.value_changed.disconnect(_on_SizeValue_value_changed)

	var height := height_value.value
	height_value.value = width_value.value
	width_value.value = height
	toggle_size_buttons()

	width_value.value_changed.connect(_on_SizeValue_value_changed)
	height_value.value_changed.connect(_on_SizeValue_value_changed)


func _on_visibility_changed() -> void:
	if not visible:
		Global.dialog_open(false)
