public FrameCompare(IVFilter ivBase,
                            List <uint> natures,
                            int ability,
                            bool shinyOnly,
                            bool synchOnly,
                            bool dreamWorld,
                            List <int> encounterSlots,
                            GenderFilter genderFilter)
        {
            if (ivBase != null)
            {
                hpValue    = ivBase.hpValue;
                hpCompare  = ivBase.hpCompare;
                atkValue   = ivBase.atkValue;
                atkCompare = ivBase.atkCompare;
                defValue   = ivBase.defValue;
                defCompare = ivBase.defCompare;
                spaValue   = ivBase.spaValue;
                spaCompare = ivBase.spaCompare;
                spdValue   = ivBase.spdValue;
                spdCompare = ivBase.spdCompare;
                speValue   = ivBase.speValue;
                speCompare = ivBase.speCompare;
            }
            Natures             = natures;
            this.ability        = ability;
            this.shinyOnly      = shinyOnly;
            this.synchOnly      = synchOnly;
            this.dreamWorld     = dreamWorld;
            this.encounterSlots = encounterSlots;

            GenderFilter = genderFilter;
        }
        public FrameCompare(
            uint compareHpA,
            uint compareAtkA,
            uint compareDefA,
            uint compareSpaA,
            uint compareSpdA,
            uint compareSpeA,
            uint compareHpB,
            uint compareAtkB,
            uint compareDefB,
            uint compareSpaB,
            uint compareSpdB,
            uint compareSpeB,
            IVFilter ivBase,
            List <uint> natures,
            int ability,
            bool shinyOnly,
            bool checkparents,
            GenderFilter genderFilter)
        {
            comparers = new List <FrameCompare>();

            this.compareHpA  = compareHpA;
            this.compareAtkA = compareAtkA;
            this.compareDefA = compareDefA;
            this.compareSpaA = compareSpaA;
            this.compareSpdA = compareSpdA;
            this.compareSpeA = compareSpeA;

            this.compareHpB  = compareHpB;
            this.compareAtkB = compareAtkB;
            this.compareDefB = compareDefB;
            this.compareSpaB = compareSpaB;
            this.compareSpdB = compareSpdB;
            this.compareSpeB = compareSpeB;

            hpValue        = ivBase.hpValue;
            hpCompare      = ivBase.hpCompare;
            atkValue       = ivBase.atkValue;
            atkCompare     = ivBase.atkCompare;
            defValue       = ivBase.defValue;
            defCompare     = ivBase.defCompare;
            spaValue       = ivBase.spaValue;
            spaCompare     = ivBase.spaCompare;
            spdValue       = ivBase.spdValue;
            spdCompare     = ivBase.spdCompare;
            speValue       = ivBase.speValue;
            speCompare     = ivBase.speCompare;
            Natures        = natures;
            this.ability   = ability;
            this.shinyOnly = shinyOnly;
            ABcheck        = checkparents;
            GenderFilter   = genderFilter;
        }
        public FrameCompare(
            uint hpValue,
            CompareType hpCompare,
            uint atkValue,
            CompareType atkCompare,
            uint defValue,
            CompareType defCompare,
            uint spaValue,
            CompareType spaCompare,
            uint spdValue,
            CompareType spdCompare,
            uint speValue,
            CompareType speCompare,
            List <uint> natures,
            int ability,
            bool shinyOnly,
            bool synchOnly,
            bool dreamWorld,
            List <int> encounterSlots,
            GenderFilter genderFilter)
        {
            this.hpValue        = hpValue;
            this.hpCompare      = hpCompare;
            this.atkValue       = atkValue;
            this.atkCompare     = atkCompare;
            this.defValue       = defValue;
            this.defCompare     = defCompare;
            this.spaValue       = spaValue;
            this.spaCompare     = spaCompare;
            this.spdValue       = spdValue;
            this.spdCompare     = spdCompare;
            this.speValue       = speValue;
            this.speCompare     = speCompare;
            Natures             = natures;
            this.ability        = ability;
            this.shinyOnly      = shinyOnly;
            this.synchOnly      = synchOnly;
            this.dreamWorld     = dreamWorld;
            this.encounterSlots = encounterSlots;

            GenderFilter = genderFilter;
        }
        private GenderFilter constructGenderFilter()
        {
            var criteria = (GenderCriteria) comboBoxCapGender.SelectedIndex;
            uint ratio = 0;

            switch (comboBoxCapGenderRatio.SelectedIndex)
            {
                case 0:
                    ratio = 255;
                    break;
                case 1:
                    ratio = 127;
                    break;
                case 2:
                    ratio = 191;
                    break;
                case 3:
                    ratio = 63;
                    break;
                case 4:
                    ratio = 31;
                    break;
                case 5:
                    ratio = 0;
                    break;
            }

            var filter = new GenderFilter("", ratio, criteria);

            return filter;
        }
        // We're making this public
        // So they can be accessed when calculating Entralink PIDs
        public FrameCompare(
            uint compareHpA,
            uint compareAtkA,
            uint compareDefA,
            uint compareSpaA,
            uint compareSpdA,
            uint compareSpeA,
            uint compareHpB,
            uint compareAtkB,
            uint compareDefB,
            uint compareSpaB,
            uint compareSpdB,
            uint compareSpeB,
            uint hpValue,
            CompareType hpCompare,
            uint atkValue,
            CompareType atkCompare,
            uint defValue,
            CompareType defCompare,
            uint spaValue,
            CompareType spaCompare,
            uint spdValue,
            CompareType spdCompare,
            uint speValue,
            CompareType speCompare,
            List<uint> natures,
            int ability,
            bool shinyOnly,
            bool checkparents,
            GenderFilter genderFilter)
        {
            comparers = new List<FrameCompare>();

            this.compareHpA = compareHpA;
            this.compareAtkA = compareAtkA;
            this.compareDefA = compareDefA;
            this.compareSpaA = compareSpaA;
            this.compareSpdA = compareSpdA;
            this.compareSpeA = compareSpeA;

            this.compareHpB = compareHpB;
            this.compareAtkB = compareAtkB;
            this.compareDefB = compareDefB;
            this.compareSpaB = compareSpaB;
            this.compareSpdB = compareSpdB;
            this.compareSpeB = compareSpeB;

            this.hpValue = hpValue;
            this.hpCompare = hpCompare;
            this.atkValue = atkValue;
            this.atkCompare = atkCompare;
            this.defValue = defValue;
            this.defCompare = defCompare;
            this.spaValue = spaValue;
            this.spaCompare = spaCompare;
            this.spdValue = spdValue;
            this.spdCompare = spdCompare;
            this.speValue = speValue;
            this.speCompare = speCompare;
            Natures = natures;
            this.ability = ability;
            this.shinyOnly = shinyOnly;
            ABcheck = checkparents;
            GenderFilter = genderFilter;
        }
        public FrameCompare(IVFilter ivBase,
                            List<uint> natures,
                            int ability,
                            bool shinyOnly,
                            bool synchOnly,
                            bool dreamWorld,
                            List<int> encounterSlots,
                            GenderFilter genderFilter)
        {
            if (ivBase != null)
            {
                hpValue = ivBase.hpValue;
                hpCompare = ivBase.hpCompare;
                atkValue = ivBase.atkValue;
                atkCompare = ivBase.atkCompare;
                defValue = ivBase.defValue;
                defCompare = ivBase.defCompare;
                spaValue = ivBase.spaValue;
                spaCompare = ivBase.spaCompare;
                spdValue = ivBase.spdValue;
                spdCompare = ivBase.spdCompare;
                speValue = ivBase.speValue;
                speCompare = ivBase.speCompare;
            }
            Natures = natures;
            this.ability = ability;
            this.shinyOnly = shinyOnly;
            this.synchOnly = synchOnly;
            this.dreamWorld = dreamWorld;
            this.encounterSlots = encounterSlots;

            GenderFilter = genderFilter;
        }
        public FrameCompare(
            uint hpValue,
            CompareType hpCompare,
            uint atkValue,
            CompareType atkCompare,
            uint defValue,
            CompareType defCompare,
            uint spaValue,
            CompareType spaCompare,
            uint spdValue,
            CompareType spdCompare,
            uint speValue,
            CompareType speCompare,
            List<uint> natures,
            int ability,
            bool shinyOnly,
            bool synchOnly,
            bool dreamWorld,
            List<int> encounterSlots,
            GenderFilter genderFilter)
        {
            this.hpValue = hpValue;
            this.hpCompare = hpCompare;
            this.atkValue = atkValue;
            this.atkCompare = atkCompare;
            this.defValue = defValue;
            this.defCompare = defCompare;
            this.spaValue = spaValue;
            this.spaCompare = spaCompare;
            this.spdValue = spdValue;
            this.spdCompare = spdCompare;
            this.speValue = speValue;
            this.speCompare = speCompare;
            Natures = natures;
            this.ability = ability;
            this.shinyOnly = shinyOnly;
            this.synchOnly = synchOnly;
            this.dreamWorld = dreamWorld;
            this.encounterSlots = encounterSlots;

            GenderFilter = genderFilter;
        }
        public bool Compare(Frame frame)
        {
            //  Check the nature first
            if (Natures != null)
            {
                // If the frame can be synchronized, it doesn't need to pass the check
                if (frame.EncounterMod != EncounterMod.Synchronize)
                {
                    bool test = Natures.Any(nature => nature == frame.Nature);
                    if (!test)
                    {
                        return(false);
                    }
                }
            }

            if (synchOnly)
            {
                if (!frame.Synchable)
                {
                    return(false);
                }
            }

            if (!GenderFilter.Filter(frame.GenderValue))
            {
                return(false);
            }

            if (!GenderFilter.Filter(frame.EncounterMod))
            {
                return(false);
            }

            // For 3rd Gen eggs - if an egg is not generated on that frame, ignore it
            if (frame.FrameType == FrameType.RSBredLower)
            {
                // need to replace this now that we're using numbered natures
                if (frame.Number == 0)
                {
                    return(false);
                }
            }

            //  Go through and check each IV against what the user has required.
            //  Skip if it's a FrameType that doesn't use IVs
            if (frame.FrameType != FrameType.Method5Natures &&
                frame.FrameType != FrameType.Gen4Normal &&
                frame.FrameType != FrameType.Gen4International &&
                frame.FrameType != FrameType.RSBredLower)
            {
                if (ABcheck)
                {
                    uint frameIv = frame.Hp;

                    if (frame.DisplayHp == "A")
                    {
                        frameIv = compareHpA;
                    }
                    if (frame.DisplayHp == "B")
                    {
                        frameIv = compareHpB;
                    }

                    if (!CompareIV(hpCompare, frameIv, hpValue))
                    {
                        return(false);
                    }


                    frameIv = frame.Atk;
                    if (frame.DisplayAtk == "A")
                    {
                        frameIv = compareAtkA;
                    }
                    if (frame.DisplayAtk == "B")
                    {
                        frameIv = compareAtkB;
                    }

                    if (!CompareIV(atkCompare, frameIv, atkValue))
                    {
                        return(false);
                    }


                    frameIv = frame.Def;
                    if (frame.DisplayDef == "A")
                    {
                        frameIv = compareDefA;
                    }
                    if (frame.DisplayDef == "B")
                    {
                        frameIv = compareDefB;
                    }


                    if (!CompareIV(defCompare, frameIv, defValue))
                    {
                        return(false);
                    }


                    frameIv = frame.Spa;
                    if (frame.DisplaySpa == "A")
                    {
                        frameIv = compareSpaA;
                    }
                    if (frame.DisplaySpa == "B")
                    {
                        frameIv = compareSpaB;
                    }


                    if (!CompareIV(spaCompare, frameIv, spaValue))
                    {
                        return(false);
                    }


                    frameIv = frame.Spd;
                    if (frame.DisplaySpd == "A")
                    {
                        frameIv = compareSpdA;
                    }
                    if (frame.DisplaySpd == "B")
                    {
                        frameIv = compareSpdB;
                    }


                    if (!CompareIV(spdCompare, frameIv, spdValue))
                    {
                        return(false);
                    }


                    frameIv = frame.Spe;
                    if (frame.DisplaySpe == "A")
                    {
                        frameIv = compareSpeA;
                    }
                    if (frame.DisplaySpe == "B")
                    {
                        frameIv = compareSpeB;
                    }


                    if (!CompareIV(speCompare, frameIv, speValue))
                    {
                        return(false);
                    }
                }

                else
                {
                    if (frame.DisplayHp != "A" && frame.DisplayHp != "B")
                    {
                        if (!CompareIV(hpCompare, frame.Hp, hpValue))
                        {
                            return(false);
                        }
                    }

                    if (frame.DisplayAtk != "A" && frame.DisplayAtk != "B")
                    {
                        if (!CompareIV(atkCompare, frame.Atk, atkValue))
                        {
                            return(false);
                        }
                    }

                    if (frame.DisplayDef != "A" && frame.DisplayDef != "B")
                    {
                        if (!CompareIV(defCompare, frame.Def, defValue))
                        {
                            return(false);
                        }
                    }

                    if (frame.DisplaySpa != "A" && frame.DisplaySpa != "B")
                    {
                        if (!CompareIV(spaCompare, frame.Spa, spaValue))
                        {
                            return(false);
                        }
                    }

                    if (frame.DisplaySpd != "A" && frame.DisplaySpd != "B")
                    {
                        if (!CompareIV(spdCompare, frame.Spd, spdValue))
                        {
                            return(false);
                        }
                    }

                    if (frame.DisplaySpe != "A" && frame.DisplaySpe != "B")
                    {
                        if (!CompareIV(speCompare, frame.Spe, speValue))
                        {
                            return(false);
                        }
                    }
                }
            }
            if (shinyOnly)
            {
                if (!frame.Shiny)
                {
                    return(false);
                }
            }

            if (dreamWorld)
            {
                if (!frame.DreamAbility)
                {
                    return(false);
                }
            }

            if (encounterSlots != null)
            {
                bool test = false;
                foreach (int slot in encounterSlots)
                {
                    if (slot == frame.EncounterSlot)
                    {
                        test = true;
                        break;
                    }
                }

                if (!test)
                {
                    return(false);
                }
            }

            if (ability != -1)
            {
                if ((ability == 0) && (frame.Ability != 0))
                {
                    return(false);
                }

                if ((ability == 1) && (frame.Ability != 1))
                {
                    return(false);
                }
            }

            return(true);
        }