class_name Terrain
## Tools for working with different terrain types.
## This provides a unified interface to Terrain3D and regular meshes.

## Basic terrain materials
enum Type {
	NONE,
	ROUGH,
	FAIRWAY,
	GREEN,
	SAND,
	CONCRETE,
	ROCK,
	WOOD,
	METAL,
	GLASS,
}

const DEFAULT_MATERIAL := Type.CONCRETE


## Get the `Terrain.Type` value which corresponds to the given Terrain3D texture ID.
##
## Note that this relies on the ordering of textures in our Terrain3DAsset resource!
## If the order textures are defined in changes, this will break!
static func from_texture_id(tex_id: int) -> Type:
	match tex_id:
		0:
			return Type.ROUGH
		1:
			return Type.FAIRWAY
		2:
			return Type.SAND
		3:
			return Type.GREEN
		4:
			return Type.ROCK
		_:
			return DEFAULT_MATERIAL


## Get the `Terrain.Type` value associated with a collision body.
##
## This returns the type stored in the first `TerrainMarker` direct child of the body.
## Use this method to set the terrain type of arbitrary bodies!
static func from_body(body: Node) -> Type:
	for n: Node in body.get_children():
		if n is TerrainMarker:
			return (n as TerrainMarker).type
	return DEFAULT_MATERIAL


## Get the `Terrain.Type` value at the given position in a Terrain3D node.
static func at_position(global_position: Vector3, terrain3d: Terrain3D) -> Type:
	var blend := terrain3d.data.get_texture_id(global_position)
	var id: int
	if terrain3d.data.get_control_auto(global_position):
		id = int(blend.x if blend.z > 0 else blend.y)
	else:
		id = int(blend.x)
	return from_texture_id(id)


## Get the Terrain.Type value at the given position for the given body.
##
## Position is only used when colliding with a Terrain3D node.
## Other bodies will have one material type for the entire body node.
static func from_collision(global_position: Vector3, body: Node) -> Type:
	if body is Terrain3D:
		return Terrain.at_position(global_position, body as Terrain3D)
	return Terrain.from_body(body)
