using Verse;
using RimWorld;

namespace SCE
{
    public class RitualPosition_RelativeThingCentre : RitualPosition_VerticalThingCenter
    {
        public Rot4 facing = Rot4.Invalid;
        public Rot4 side = Rot4.Invalid;
        public CellRect rectOverride = CellRect.Empty;

        private Rot4 thingRot = Rot4.Invalid;

        public override PawnStagePosition GetCell(IntVec3 spot, Pawn p, LordJob_Ritual ritual)
        {
            var thing = ritual.selectedTarget.Thing;
            if (thing != null)
            {
                thingRot = thing.Rotation;
            }
            
            var result =  base.GetCell(spot, p, ritual);
            if (facing.IsValid)
            {
                result.orientation = facing.RotatedBy(thingRot);
            }
            return result;
        }

        protected override CellRect GetRect(CellRect thingRect)
        {
            IntVec3 absOffset = offset.RotatedBy(thingRot);

            CellRect rect;
            if (!rectOverride.IsEmpty)
            {
                rect = rectOverride.RotatedBy(thingRot);
                return rect.MovedBy(thingRect.CenterCell + absOffset);
            }

            if (side.IsValid)
            {
                // Convert to SpectateRectSide for some nice readable constants
                rect = side.RotatedBy(thingRot).AsSpectateSide switch
                {
                    SpectateRectSide.Up     => new CellRect(thingRect.minX, thingRect.maxZ + 1, thingRect.Width, 1),
                    SpectateRectSide.Right  => new CellRect(thingRect.maxX + 1, thingRect.minZ, 1, thingRect.Height),
                    SpectateRectSide.Down   => new CellRect(thingRect.minX, thingRect.minZ - 1, thingRect.Width, 1),
                    SpectateRectSide.Left   => new CellRect(thingRect.minX - 1, thingRect.minZ, 1, thingRect.Height),
                    _ => CellRect.Empty     // Not actually possible, but it shuts the compiler up.
                };

                return rect.MovedBy(absOffset);
            }

            return CellRect.SingleCell(thingRect.CenterCell + absOffset);
        }

        public override void ExposeData()
        {
            base.ExposeData();
            Scribe_Values.Look(ref facing, "facing", Rot4.Invalid);
            Scribe_Values.Look(ref side, "side", Rot4.Invalid);
            Scribe_Values.Look(ref rectOverride, "rectOverride", CellRect.Empty);
        }
    }
}