﻿using System;
using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using RimWorld;
using Verse;
using rjw;

namespace Rimworld_Animations
{

    [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "Start")]
    static class HarmonyPatch_JobDriver_SexBaseInitiator_Start
    {
        public static void Postfix(ref JobDriver_SexBaseInitiator __instance)
        {

            Pawn pawn = __instance.pawn;
            Pawn partner = __instance.Target as Pawn;

            List<Pawn> participants = 
                (partner?.jobs?.curDriver as JobDriver_SexBaseReciever)?.parteners.Append(partner).ToList() ?? // list of all participants including partner
                ((__instance is JobDriver_Masturbate) ?  new List<Pawn>() { pawn } : null); //solo pawn for masturbation anim

            GroupAnimationDef groupAnimation = AnimationUtility.FindGroupAnimation(participants, out int reorder);

            if (groupAnimation != null)
            {
                Thing anchor = (Thing)__instance.Bed ?? partner;

                AnimationUtility.StartGroupAnimation(participants, groupAnimation, reorder, anchor);
                int animTicks = AnimationUtility.GetAnimationLength(pawn);

                foreach (Pawn participant in participants)
                {
                    if (RJWAnimationSettings.debugMode)
                    {
                        Log.Message("Participant: " + participant.Name);
                        Log.Message("JobDriver: " + participant.CurJobDef.defName);
                    }

                    //null ref check for pawns that might have lost their jobs or become null for some reason
                    if (participant?.jobs?.curDriver is JobDriver_Sex participantJobDriver)
                    {
                        participantJobDriver.ticks_left = animTicks;
                        participantJobDriver.sex_ticks = animTicks;
                        participantJobDriver.orgasmStartTick = animTicks;
                        participantJobDriver.duration = animTicks;
                    }
                }
            }

            else
            {

                //backup check for if masturbation doesn't have anim
                //reset duration and ticks_left to the regular RJW values
                //because of HarmonyPatch_JobDriver_Masturbate setting the values large to prevent early stoppage
                foreach (Pawn participant in participants)
                {
                    if (participant?.jobs?.curDriver is JobDriver_Sex participantJobDriver)
                    {
                        participantJobDriver.duration = (int)(xxx.is_frustrated(participant) ? (2500f * Rand.Range(0.2f, 0.7f)) : (2500f * Rand.Range(0.2f, 0.4f)));
                        participantJobDriver.ticks_left = participantJobDriver.duration;

                    }

                }
            }

        }

        static IEnumerable<String> NonSexActRulePackDefNames = new String[]
        {
            "MutualHandholdingRP",
            "MutualMakeoutRP",
        };

        public static bool NonSexualAct(JobDriver_SexBaseInitiator sexBaseInitiator)
        {
            if (NonSexActRulePackDefNames.Contains(sexBaseInitiator.Sexprops.rulePack))
            {
                return true;
            }
            return false;
        }
    }


    [HarmonyPatch(typeof(JobDriver_SexBaseInitiator), "End")]
    static class HarmonyPatch_JobDriver_SexBaseInitiator_End
    {

        public static void Prefix(ref JobDriver_SexBaseInitiator __instance)
        {
            //stop pawn animating
            AnimationUtility.StopGroupAnimation(__instance.pawn);

            //stop partner animating
            if (__instance.Partner is Pawn partner)
            {
                AnimationUtility.StopGroupAnimation(partner);
            }

            //stop partner's other partners (threesome pawns) animating
            //added null ref checks for instances when pawns get nulled or lose their jobs
            if (__instance.Partner?.jobs?.curDriver is JobDriver_SexBaseReciever partnerReceiverJob)
            {
                foreach (Pawn pawn in partnerReceiverJob.parteners)
                {
                    if (pawn != null) AnimationUtility.StopGroupAnimation(pawn);
                }
            }
        }
    }
}

1.5/Source/Patches/RJWPatches/JobDrivers/HarmonyPatch_JobDriver_SexBaseInitiator.cs