# TileMap operations module
# Handles: set_tilemap_cell_op, get_tilemap_cell_op
# Corresponds to: test_input_tilemap_material.py (TileMap section)
class_name TilemapOps


## Set a cell in a TileMap node
static func set_tilemap_cell_op(ctx: SceneTree, params: Dictionary) -> void:
	print("Setting TileMap cell in scene: " + params.scene_path)
	
	# Ensure the scene path starts with res:// for Godot's resource system
	var full_scene_path: String = params.scene_path
	if not full_scene_path.begins_with("res://"):
		full_scene_path = "res://" + full_scene_path
	
	if ctx.debug_mode:
		print("Full scene path (with res://): " + full_scene_path)
	
	# Check if the scene file exists
	var scene_file_check: bool = FileAccess.file_exists(full_scene_path)
	if ctx.debug_mode:
		print("Scene file exists check: " + str(scene_file_check))
	
	if not scene_file_check:
		printerr("Scene file does not exist at: " + full_scene_path)
		var absolute_path: String = ProjectSettings.globalize_path(full_scene_path)
		printerr("Absolute file path that doesn't exist: " + absolute_path)
		ctx.quit(1)
	
	# Load the scene
	var scene: PackedScene = load(full_scene_path)
	if not scene:
		printerr("Failed to load scene: " + full_scene_path)
		ctx.quit(1)
	
	if ctx.debug_mode:
		print("Scene loaded successfully")
	
	# Instance the scene
	var scene_root: Node = scene.instantiate()
	if ctx.debug_mode:
		print("Scene instantiated")
	
	# Find the TileMap node
	var node_path: String = params.node_path
	if ctx.debug_mode:
		print("Original node path: " + node_path)
	
	var tilemap_node: Node = scene_root
	if node_path != "root" and node_path != "":
		var relative_path: String = node_path
		if relative_path.begins_with("root/"):
			relative_path = relative_path.substr(5)  # Remove "root/" prefix
		if ctx.debug_mode:
			print("Relative node path: " + relative_path)
		tilemap_node = scene_root.get_node(relative_path)
	
	if not tilemap_node:
		printerr("Node not found: " + node_path)
		ctx.quit(1)
	
	if ctx.debug_mode:
		print("TileMap node found: " + tilemap_node.name + " of type: " + tilemap_node.get_class())
	
	# Verify it's a TileMap or TileMapLayer
	if not (tilemap_node is TileMap or tilemap_node is TileMapLayer):
		printerr("Node is not a TileMap or TileMapLayer: " + tilemap_node.get_class())
		ctx.quit(1)
	
	# Get cell parameters
	var layer: int = params.layer if params.has("layer") else 0
	var x: int = params.x
	var y: int = params.y
	var source_id: int = params.source_id if params.has("source_id") else 0
	var atlas_x: int = params.atlas_x if params.has("atlas_x") else 0
	var atlas_y: int = params.atlas_y if params.has("atlas_y") else 0
	var alternative_tile: int = params.alternative_tile if params.has("alternative_tile") else 0
	
	if ctx.debug_mode:
		print("Setting cell at (" + str(x) + ", " + str(y) + ") layer " + str(layer))
		print("Source ID: " + str(source_id) + ", Atlas coords: (" + str(atlas_x) + ", " + str(atlas_y) + ")")
	
	# Set the cell based on node type
	var coords: Vector2i = Vector2i(x, y)
	var atlas_coords: Vector2i = Vector2i(atlas_x, atlas_y)
	
	if tilemap_node is TileMap:
		tilemap_node.set_cell(layer, coords, source_id, atlas_coords, alternative_tile)
		if ctx.debug_mode:
			print("Set cell on TileMap")
	elif tilemap_node is TileMapLayer:
		# TileMapLayer doesn't have layers, it IS a layer
		tilemap_node.set_cell(coords, source_id, atlas_coords, alternative_tile)
		if ctx.debug_mode:
			print("Set cell on TileMapLayer")
	
	# Pack and save the scene
	var packed_scene: PackedScene = PackedScene.new()
	var result: int = packed_scene.pack(scene_root)
	if ctx.debug_mode:
		print("Pack result: " + str(result) + " (OK=" + str(OK) + ")")
	
	if result == OK:
		if ctx.debug_mode:
			print("Saving scene to: " + full_scene_path)
		var error: int = ResourceSaver.save(packed_scene, full_scene_path)
		if ctx.debug_mode:
			print("Save result: " + str(error) + " (OK=" + str(OK) + ")")
		
		if error == OK:
			print("TileMap cell set successfully at (" + str(x) + ", " + str(y) + ")")
		else:
			printerr("Failed to save scene: " + str(error))
			ctx.quit(1)
	else:
		printerr("Failed to pack scene: " + str(result))
		ctx.quit(1)


## Get a cell from a TileMap node (read operation)
static func get_tilemap_cell_op(ctx: SceneTree, params: Dictionary) -> void:
	print("Getting TileMap cell from scene: " + params.scene_path)
	
	# Ensure the scene path starts with res:// for Godot's resource system
	var full_scene_path: String = params.scene_path
	if not full_scene_path.begins_with("res://"):
		full_scene_path = "res://" + full_scene_path
	
	if ctx.debug_mode:
		print("Full scene path (with res://): " + full_scene_path)
	
	# Check if the scene file exists
	var scene_file_check: bool = FileAccess.file_exists(full_scene_path)
	if not scene_file_check:
		printerr("Scene file does not exist at: " + full_scene_path)
		ctx.quit(1)
	
	# Load the scene
	var scene: PackedScene = load(full_scene_path)
	if not scene:
		printerr("Failed to load scene: " + full_scene_path)
		ctx.quit(1)
	
	# Instance the scene
	var scene_root: Node = scene.instantiate()
	
	# Find the TileMap node
	var node_path: String = params.node_path
	var tilemap_node: Node = scene_root
	if node_path != "root" and node_path != "":
		var relative_path: String = node_path
		if relative_path.begins_with("root/"):
			relative_path = relative_path.substr(5)
		tilemap_node = scene_root.get_node(relative_path)
	
	if not tilemap_node:
		printerr("Node not found: " + node_path)
		ctx.quit(1)
	
	# Verify it's a TileMap or TileMapLayer
	if not (tilemap_node is TileMap or tilemap_node is TileMapLayer):
		printerr("Node is not a TileMap or TileMapLayer: " + tilemap_node.get_class())
		ctx.quit(1)
	
	# Get cell parameters
	var layer: int = params.layer if params.has("layer") else 0
	var x: int = params.x
	var y: int = params.y
	var coords: Vector2i = Vector2i(x, y)
	
	if ctx.debug_mode:
		print("Getting cell at (" + str(x) + ", " + str(y) + ") layer " + str(layer))
	
	# Get cell data based on node type
	var result: Dictionary = {
		"x": x,
		"y": y,
		"layer": layer,
		"source_id": -1,
		"atlas_coords": {"x": -1, "y": -1},
		"alternative_tile": 0,
		"is_empty": true
	}
	
	if tilemap_node is TileMap:
		result["source_id"] = tilemap_node.get_cell_source_id(layer, coords)
		var atlas: Vector2i = tilemap_node.get_cell_atlas_coords(layer, coords)
		result["atlas_coords"] = {"x": atlas.x, "y": atlas.y}
		result["alternative_tile"] = tilemap_node.get_cell_alternative_tile(layer, coords)
		result["is_empty"] = result["source_id"] == -1
	elif tilemap_node is TileMapLayer:
		result["source_id"] = tilemap_node.get_cell_source_id(coords)
		var atlas: Vector2i = tilemap_node.get_cell_atlas_coords(coords)
		result["atlas_coords"] = {"x": atlas.x, "y": atlas.y}
		result["alternative_tile"] = tilemap_node.get_cell_alternative_tile(coords)
		result["is_empty"] = result["source_id"] == -1
		result["layer"] = 0  # TileMapLayer doesn't have layers
	
	print(JSON.stringify(result))
