Editor/Data/ArchOpeningPreset.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Sandbox;

namespace Sunless.Architecture;

public sealed class ArchOpeningPreset {
	public string Name { get; set; } = "door";
	public OpeningKind Kind { get; set; } = OpeningKind.Door;
	public float Width { get; set; } = 48f;
	public float Height { get; set; } = 96f;
	public float SillHeight { get; set; }
	public bool Cased { get; set; } = true;
	public bool HasSill { get; set; }
	public bool Leaf { get; set; } = true;
	public bool StartOpen { get; set; }
	public float CasingWidth { get; set; }
	public bool Glazed { get; set; }
	public bool AutoLayout { get; set; } = true;
	public int Lights { get; set; } = 1;
	public int Sashes { get; set; } = 2;
	public int PanesAcross { get; set; } = 2;
	public int PanesDown { get; set; } = 3;
	public GlassState Glass { get; set; } = GlassState.Intact;
	public bool Breakable { get; set; }
	public OpeningFurniture Furniture { get; set; }
	public OpeningHood Hood { get; set; }
	public string LeafPrefab { get; set; } = "";
	public Vector3 LeafAnchor { get; set; }
	public Vector3 LeafAnchorAlong { get; set; }
	public Angles LeafAnchorTurn { get; set; }
	public bool LeafFits { get; set; }
	public string LeafMaterialGroup { get; set; } = "";

	public bool IsGlazed => Glazed && Kind.Glazes();
	public bool IsSilled => HasSill && Kind.Sills();
	public bool IsHung => Leaf && Kind.Hangs();
	public ArchAimedPrefab LeafArt => new( LeafPrefab, LeafAnchor, LeafAnchorAlong, LeafAnchorTurn, LeafFits );
	public OpeningFurniture Fitted => Kind.Carries( Furniture ) ? Furniture : OpeningFurniture.None;
	public OpeningHood Hooded => Kind.Wears( Hood ) ? Hood : OpeningHood.None;

	// Every member is a scalar, an enum or a string, so a shallow clone IS a copy - four hand-written
	// twenty-field initialisers drifted apart before this.
	public ArchOpeningPreset Copy() => (ArchOpeningPreset)MemberwiseClone();

	public ArchOpening Spawn( int id, float offset ) {
		return Dress( new ArchOpening { Id = id }, offset );
	}

	// Everything but identity, so a unit an affector already owns can be re-dressed where it stands and
	// still come back exactly as a fresh spawn would - which is how a retyped preset reaches a standing hole.
	public ArchOpening Dress( ArchOpening opening, float offset ) {
		opening.Preset = Name;
		opening.Kind = Kind;
		opening.Offset = offset;
		opening.Width = Width;
		opening.Height = Height;
		opening.SillHeight = SillHeight;
		opening.Cased = Cased;
		opening.HasSill = HasSill;
		opening.CasingWidth = CasingWidth;
		opening.Leaf = Leaf;
		opening.StartOpen = StartOpen;
		opening.Glazed = Glazed;
		opening.AutoLayout = AutoLayout;
		opening.Lights = Lights;
		opening.Sashes = Sashes;
		opening.PanesAcross = PanesAcross;
		opening.PanesDown = PanesDown;
		opening.Glass = Glass;
		opening.Breakable = Breakable;
		opening.Furniture = Furniture;
		opening.Hood = Hood;
		opening.LeafPrefab = LeafPrefab;
		opening.LeafAnchor = LeafAnchor;
		opening.LeafAnchorAlong = LeafAnchorAlong;
		opening.LeafAnchorTurn = LeafAnchorTurn;
		opening.LeafFits = LeafFits;
		opening.LeafMaterialGroup = LeafMaterialGroup;

		return opening;
	}
}