# Hurry Curry! - a game about cooking
# Copyright (C) 2025 Hurry Curry! contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, version 3 of the License only.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
class_name TileFactory
extends Object


class TileName:
	var name# : String
	var variant #: String?
	var raw_name: String
	func _init(raw_name_: String):
		raw_name = raw_name_
		var c = Array(raw_name_.split(":"))
		name = c[0]; variant = c[1] if c.size() >= 2 else null # TODO Array.get throws errors

class TileCC:
	var tile_name: TileName
	var position: Vector2i
	var neighbors: Array
	var floor_meshers: Dictionary[String, FloorMesher]
	var server_context: Game.ServerContext

var floor_meshers: Dictionary[String, FloorMesher] = {
	"floor": FloorMesher.new(Floor.floor_mesh()),
	"path": FloorMesher.new(Path.floor_mesh()),
	"grass": GrassMesher.new(Grass.floor_mesh()),
	"street": FloorMesher.new(Street.floor_mesh())
}

func produce(raw_name: String, position: Vector2i, neighbors: Array, server_context: Game.ServerContext = null) -> Tile:
	var tile_name = TileName.new(raw_name)

	var ctx := TileCC.new()
	ctx.tile_name = tile_name
	ctx.position = position
	ctx.neighbors = neighbors.map(func(a):
		if a != null:
			return a.map(func(b): return null if b == null else TileName.new(b).name)
		else: return null
	)
	ctx.floor_meshers = floor_meshers
	ctx.server_context = server_context

	match tile_name.name:
		"book": return CounterBase.new(ctx, preload("res://map/tiles/book.tscn"))
		"ceiling-lamp": return GenericTile.new(ctx, preload("res://map/tiles/ceiling_lamp.tscn"))
		"chair": return Chair.new(ctx)
		"chandelier": return GenericTile.new(ctx, preload("res://map/tiles/chandelier.tscn"))
		"conveyor": return Conveyor.new(ctx)
		"counter-window": return CounterWindow.new(ctx)
		"counter-window-conveyor": return CounterWindowConveyor.new(ctx)
		"counter": return CounterBase.new(ctx, null)
		"cutting-board": return CuttingBoard.new(ctx)
		"door": return Door.new(ctx)
		"fence": return Fence.new(ctx)
		"floor": return Floor.new(ctx)
		"freezer": return Freezer.new(ctx)
		"grass": return Grass.new(ctx)
		"lamp": return Lamp.new(ctx)
		"oven": return Oven.new(ctx)
		"path": return Path.new(ctx)
		"rolling-board": return RollingBoard.new(ctx)
		"screen": return Screen.new(ctx)
		"deep-fryer": return GenericTile.new(ctx, preload("res://map/tiles/deep_fryer.tscn"))
		"sink": return Sink.new(ctx)
		"stove": return Stove.new(ctx)
		"street": return Street.new(ctx)
		"table": return Table.new(ctx)
		"trash": return Trash.new(ctx)
		"tree": return ExteriorTree.new(ctx)
		"wall-window": return WallWindow.new(ctx)
		"wall": return Wall.new(ctx)
		"white-hole-counter": return ItemPortal.new(ctx, 1)
		"white-hole": return PlayerPortal.new(ctx)
		"grey-hole-counter": return ItemPortal.new(ctx, 0)
		"grey-hole": return PlayerPortal.new(ctx)
		"black-hole-counter": return ItemPortal.new(ctx, -1)
		"black-hole": return PlayerPortal.new(ctx)

		"house-balcony": return HouseBalcony.new(ctx)
		"house-door": return HouseDoor.new(ctx)
		"house-oriel": return HouseOriel.new(ctx)
		"house-wall": return HouseWall.new(ctx)
		"house-side": return HouseSide.new(ctx)
		"house-roof": return HouseRoof.new(ctx)
		"house-roof-chimney": return HouseRoofChimney.new(ctx)

		"crate": return Crate.new(ctx)

		# TODO: update maps to use "crate:..."
		"bun-crate":
			ctx.tile_name.variant = "bun"
			return Crate.new(ctx)
		"cheese-crate":
			ctx.tile_name.variant = "cheese"
			return Crate.new(ctx)
		"coconut-crate":
			ctx.tile_name.variant = "coconut"
			return Crate.new(ctx)
		"fish-crate":
			ctx.tile_name.variant = "fish"
			return Crate.new(ctx)
		"flour-crate":
			ctx.tile_name.variant = "flour"
			return Crate.new(ctx)
		"leek-crate":
			ctx.tile_name.variant = "leek"
			return Crate.new(ctx)
		"lettuce-crate":
			ctx.tile_name.variant = "lettuce"
			return Crate.new(ctx)
		"mushroom-crate":
			ctx.tile_name.variant = "mushroom"
			return Crate.new(ctx)
		"noodles-crate":
			ctx.tile_name.variant = "noodles"
			return Crate.new(ctx)
		"steak-crate":
			ctx.tile_name.variant = "steak"
			return Crate.new(ctx)
		"rice-crate":
			ctx.tile_name.variant = "rice"
			return Crate.new(ctx)
		"strawberry-crate":
			ctx.tile_name.variant = "strawberry"
			return Crate.new(ctx)
		"tomato-crate":
			ctx.tile_name.variant = "tomato"
			return Crate.new(ctx)
		"potato-crate":
			ctx.tile_name.variant = "potato"
			return Crate.new(ctx)

		var t:
			push_warning("tile %s unknown" % t)
			return UnknownTile.new(ctx)
