public enum Fog
{
	public enum Mode
	{
		case distance
		case depth
	}

	public enum RangeType
	{
		case linear
		case smooth
	}

	public enum FactorType
	{
		case exp
		case exp2
	}

	case none
	case range(colour: Colour, mode: Mode, type: RangeType, start: Float, end: Float)
	case factor(colour: Colour, mode: Mode, type: FactorType, density: Float)
}

public enum Light
{
	case directional(colour: Colour, direction: Vec3f)
	case point(colour: Colour, position: Vec3f, intensity: Float)
}

public struct Environment
{
	public var fog: Fog = .none
	public var ambient: Colour = .black
	public var lights: [Light] = .init()

	public init() {}

	public init(fog: Fog, ambient: Colour, lights: [Light])
	{
		self.fog = fog
		self.ambient = ambient
		self.lights = lights
	}
}

public extension Environment
{
	enum FogFalloff
	{
		case range(type: Fog.RangeType, start: Float, end: Float)
		case factor(type: Fog.FactorType, density: Float)
	}

	mutating func setFog(colour: Colour, mode: Fog.Mode, falloff: FogFalloff)
	{
		fog = switch falloff
		{
		case .range(let type, let start, let end):
			.range(colour: colour, mode: mode, type: type, start: start, end: end)
		case .factor(let type, let density):
			.factor(colour: colour, mode: mode, type: type, density: density)
		}
	}

	mutating func addAmbientLight(colour: Colour)
	{
		ambient = colour
	}

	mutating func addDirectionalLight(direction: Vec3f, colour: Colour)
	{
		lights.append(.directional(colour: colour, direction: direction))
	}

	mutating func addPointLight(position: Vec3f, colour: Colour, intensity: Float)
	{
		lights.append(.point(colour: colour, position: position, intensity: intensity))
	}
}
