extends Reference
class_name SummerDayCanvasState

signal fill_transform_changed(fill_transform)
signal canvas_transform_changed(canvas_transform)
signal view_transform_changed(view_transform, spatial_transform)

signal canvas_polygon_changed(polygon)

var rect_size: Vector2

var fill_transform := Transform2D.IDENTITY
var canvas_transform := Transform2D.IDENTITY setget _set_canvas_transform
var view_transform := Transform2D.IDENTITY # canvas_transform * fill_transform
var inverse_view_transform := Transform2D.IDENTITY

# For spacial transform.
var clip_space_view_transform := Transform2D.IDENTITY
var canvas_to_clip_space := Transform2D.IDENTITY

var _canvas_polygon: PoolVector2Array # The polygon, that forms the canvas rect.


func _init():
	connect("fill_transform_changed", self, "_update_view_transformation")
	connect("canvas_transform_changed", self, "_update_view_transformation")


func update_fill_transform():
	var doc = SummerDay.document
	if doc == null:
		fill_transform = Transform2D.IDENTITY
	else:
		var aspect_ratio = doc.resolution.x / doc.resolution.y
		
		var size_ratio = rect_size.x / rect_size.y
		
		var scale
		var translation = Vector2.ZERO
		if aspect_ratio <= size_ratio:
			scale = rect_size.y
			translation.x = rect_size.x * 0.5 - aspect_ratio * scale * 0.5
		else:
			scale = rect_size.x / aspect_ratio
			translation.y = rect_size.y * 0.5 - scale * 0.5
		
		fill_transform = Transform2D.IDENTITY.scaled(Vector2(scale, scale))
		fill_transform = fill_transform.translated(translation)
		fill_transform = Transform2D(
			Vector2(scale, 0.0),
			Vector2(0.0, scale),
			translation
		)
		
	#_update_canvas_polygon()
		
	emit_signal("fill_transform_changed", fill_transform)


func update_canvas_to_clip_space():
	canvas_to_clip_space = Transform2D(
		Vector2(2.0 / rect_size.x, 0.0),
		Vector2(0.0, -2.0 / rect_size.y),
		Vector2(-1.0, 1.0)
	)


func _update_view_transformation(transform):
	view_transform = canvas_transform * fill_transform
	inverse_view_transform = view_transform.affine_inverse()
	clip_space_view_transform = canvas_to_clip_space * view_transform
	
	emit_signal(
		"view_transform_changed", view_transform, clip_space_view_transform
		)


func _set_canvas_transform(new_canvas_transform):
	canvas_transform = new_canvas_transform
	emit_signal("canvas_transform_changed", canvas_transform)


func _update_canvas_polygon():
	var doc = SummerDay.document
	if doc == null:
		_canvas_polygon = PoolVector2Array()
		return
	_canvas_polygon = PoolVector2Array(
		[
			Vector2.ZERO,
			Vector2(doc.raw_aspect_ratio, 0.0),
			Vector2(doc.raw_aspect_ratio, 1.0),
			Vector2(0.0, 1.0)
		]
	)
	
	emit_signal("canvas_polygon_changed", _canvas_polygon)
