tool
extends PanelContainer
class_name SummerDayCanvas

onready var MeshContainer := $Render/RenderLayer/Container
onready var InteractionHint := $Render/RenderLayer/InteractionHint

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


func _ready():
	SummerDay.canvas_state = canvas_state
	SummerDay.interaction_hint = InteractionHint
	SummerDay.debug_info = $Render/DebugInfo
	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):
	tool_pool.run_most_prior(event)


# _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:
		SummerDay.document.add_track(instance)


func _on_SummerDay_document_changed(new_doc):
	new_doc.connect("track_added",
		MeshContainer, "_on_Document_add_track")
	new_doc.setup()
	canvas_state.update_fill_transform()
	new_doc.connect("resolution_changed",
		self, "_on_scene_aspect_ratio_changed")


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


func _on_scene_aspect_ratio_changed(new_aspect_ratio):
	canvas_state.update_fill_transform()


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 l 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 l is MeshInstance:
			var mesh = l.mesh
			for i in range(mesh.get_surface_count()):
				var mat = mesh.surface_get_material(i)
				mat.set_shader_param("canvas_transform", basis)
		else:
			if l.has_method("get_material"):
				l.get_material().set_shader_param("canvas_transform", basis)
			else:
				l.material_override.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
