tool
extends PanelContainer
class_name SummerDayCanvas

onready var MeshContainer := $Render/RenderLayer/Container
onready var EditHints := $Render/ForegroundLayer/EditHints

var document: SummerDayDocument
var scene: SummerDayScene
var canvas_state := SummerDayCanvasState.new()
var tool_pool := SummerDayCanvasToolPool.new()

var tool_context: SummerDayToolContext # Provided by plugin root.


func _ready():
	tool_context.canvas_state = canvas_state
	canvas_state.connect("view_transform_changed",
	self, "_on_view_transform_changed")
	canvas_state.connect("canvas_polygon_changed",
		self, "_on_canvas_polygon_changed")


func _gui_input(event):
	if event.has_method("get_position"):
		tool_context.position = canvas_state.view_transform.xform_inv(
			event.position
		)
	tool_pool.run_most_prior(event, tool_context)


# _gui_input() cannot receive screen touch released event by itself.
func _input(event):
	if event is InputEventScreenTouch and !event.is_pressed():
		_gui_input(event)
	tool_pool.pass_global_input(event)


func can_drop_data(position, data):
	return data.has("files")


func drop_data(position, data):
	var file_path = data["files"][0]
	var instance = load(file_path)
	if instance is SummerDayBlueprint:
		document.add_track(instance)


func _on_SummerDay_document_changed(new_doc):
	if new_doc != document:
		document = new_doc
		new_doc.connect("track_added",
			MeshContainer, "_on_Document_add_track")
		new_doc.setup_tracks()


func _on_SummerDay_scene_changed(new_scene):
	if new_scene != scene:
		scene = new_scene
		canvas_state.update_fill_transform(scene)
		scene.connect("aspect_ratio_changed",
			self, "_on_scene_aspect_ratio_changed")
		$Render/Label.text = str(scene) + "\n" + str(scene.aspect_ratio)
		canvas_state.update_fill_transform(scene)


func _on_Canvas_resized():
	canvas_state.rect_size = rect_size
	canvas_state.update_canvas_to_clip_space()
	canvas_state.update_fill_transform(scene)


func _on_scene_aspect_ratio_changed(new_aspect_ratio):
	canvas_state.update_fill_transform(scene)


func _on_view_transform_changed(canvas_transform, spatial_transform):
	var canvas_transform_listeners = get_tree().get_nodes_in_group(
		"SummerDayCanvasTransform"
		)
	for i in canvas_transform_listeners:
		if i is Viewport:
			i.canvas_transform = canvas_transform
	
	var spatial_transform_listeners = get_tree().get_nodes_in_group(
		"SummerDaySpatialTransform"
		)
	for i in spatial_transform_listeners:
		var basis = Basis(
			Vector3(spatial_transform.x.x, spatial_transform.x.y, 0.0),
			Vector3(spatial_transform.y.x, spatial_transform.y.y, 0.0),
			Vector3(spatial_transform.origin.x, spatial_transform.origin.y, 1.0)
		)
		if i is MeshInstance:
			var mat = i.material_override
			mat.set_shader_param("canvas_transform", basis)
		else:
			i.get_material().set_shader_param("canvas_transform", basis)
	
	
func _on_canvas_polygon_changed(new_polygon):
	var listeners = get_tree().get_nodes_in_group("SummerDayCanvasPolygon")
	for i in listeners:
		i.polygon = new_polygon
