using System;
using System.Collections.Generic;
using Verse;
using static SCE.SexRole;

namespace SCE
{
    public enum SexRole
    {
        VagiIni, VagiRec,	//  0,  1
        AnalIni, AnalRec,	//  2,  3
        CunnIni, CunnRec,	//  4,  5
        RimmIni, RimmRec,	//  6,  7 
        FellIni, FellRec,	//  8,  9
        DoubIni, DoubRec,	// 10, 11
        BresIni, BresRec,	// 12, 13
        HandIni, HandRec,	// 14, 15
        FootIni, FootRec,	// 16, 17
        FingIni, FingRec,	// 18, 19
        ScisIni, ScisRec,	// 20, 21
        MutuIni, MutuRec,	// 22, 23
        FistIni, FistRec,	// 24, 25
        SixtIni, SixtRec	// 26, 27
    }

    public static class SexRoleUtility
    {
        public static readonly SexRole[] allRoles = (SexRole[]) Enum.GetValues(typeof(SexRole));

        private static readonly List<SexRole> givingRoles = new List<SexRole>()
        {
            VagiIni, VagiRec, AnalIni, AnalRec,
            CunnIni, RimmIni,
            FellIni, DoubIni, DoubRec,
            BresIni, HandIni,
            FootIni, FingIni,
            ScisIni, ScisRec, MutuIni, MutuRec,
            FistIni, SixtIni, SixtRec
        };

        private static readonly List<SexRole> buttStuffRoles = new List<SexRole>()
        {
            AnalIni, AnalRec, RimmIni, RimmRec,
            DoubIni, DoubRec, FistIni, FistRec
        };

        public static SexRole Complement(this SexRole role)
        {
            int val = (int) role;
            // Increment if even, decrement if odd.
            int complementVal = val + 1 - 2 * (val % 2);
            return (SexRole) complementVal;
        }

        public static bool GivesPleasure(this SexRole role) => givingRoles.Contains(role);

        public static bool ReceivesPleasure(this SexRole role) => role.Complement().GivesPleasure();
        
        public static bool IsAnal(this SexRole role) => buttStuffRoles.Contains(role);

        public static float GetRoleScore(this List<float> scores, SexRole role) {
            if (!ValidateScores(scores))
                return -1f;

            return scores[(int)role];
        }
        public static void SetRoleScore(this List<float> scores, SexRole role, float value)
        {
            if (!ValidateScores(scores))
                return;
                
            scores[(int)role] = value;
        }

        public static bool ValidateScores(List<float> scores)
        {
            if (scores.Count != allRoles.Length)
            {
                Log.Error("A list of sex scores was of the wrong length.");
                return false;
            }
            return true;
        }

        public static bool IsViable(this List<float> scores, bool allowDP = false)
        {
            if (!ValidateScores(scores))
                return false;

            for (int i = 0; i < scores.Count; i++)
            {
                if (!allowDP && ((SexRole) scores[i] == DoubIni || (SexRole) scores[i] == DoubRec))
                    continue;

                if (scores[i] > 0)
                    return true;
            }
            return false;
        }
    }
}