using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using Verse;
using RimWorld;

namespace SCE
{
    public static class Extensions
    {
        public static bool CaresAboutEvent(this Pawn pawn, HistoryEventDef ev, bool onlyIfParticipating = false)
        {
            return pawn.Ideo?.CaresAboutEvent(ev, onlyIfParticipating) ?? false;
        }

        public static bool CaresAboutEvent(this Ideo ideo, HistoryEventDef ev, bool onlyIfParticipating = false)
        {
            foreach (var precept in ideo.PreceptsListForReading)
            {
                foreach (var comp in precept.def.comps)
                {
                    if ((comp is PreceptComp_SexMemory partiComp && partiComp.eventDef == ev) 
                        || (comp is PreceptComp_SelfTookMemoryThought selfComp && selfComp.eventDef == ev)
                        || (!onlyIfParticipating && ((comp is PreceptComp_ConditionalMemoryThought condComp && condComp.eventDef == ev)
                            || (comp is PreceptComp_KnowsMemoryThought witnessComp && witnessComp.eventDef == ev))))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public static CellRect RotatedBy(this CellRect rect, Rot4 rot)
        {
            IntVec3 p1 = rect.Min, p2 = rect.Max;
            return CellRect.FromLimits(p1.RotatedBy(rot), p2.RotatedBy(rot));
        }

        public static CellRect RotatedInPlaceBy(this CellRect rect, Rot4 rot)
        {
            if (rot.IsHorizontal)
            {
                return new CellRect(rect.minZ, rect.minX, rect.Height, rect.Width);
            }
            return rect;
        }

        public static Rot4 RotatedBy(this Rot4 r1, Rot4 r2) => new(r1.AsByte + r2.AsByte);

        public static Rot4 ToRot4(this SpectateRectSide side)
        {
            return side switch
            {
                SpectateRectSide.Up     => Rot4.North,
                SpectateRectSide.Right  => Rot4.East,
                SpectateRectSide.Down   => Rot4.South,
                SpectateRectSide.Left   => Rot4.West,
                _ => Rot4.Invalid
            };
        }
    }
}