/*
         * //TODO Recursion is required for this (to have X nested loops), so for now, we brute code GetStraight<T>
         * //Unfortunately, in the occurence of a straight or
         * public static IList<IList<T>> GetXConsecutive<T>(this IList<T> self, int x) where T : IGambleCard
         * {
         *  List<List<T>>
         *      allStraights = new List<List<T>>();
         *  if (!self.HasXConsecutive(x))
         *  {
         *      return new List<IList<T>>();
         *  }
         *
         *  Dictionary<GambleCardValue, IList<T>>
         *      occurences = self.GetValueOccurenceList();
         *
         *  bool found = true;
         *  for (int i = 13 - (x-1); i >= 0; i--)
         *  {
         *      for (int j = i + (x-1); j >= i ; j--)
         *      {
         *          if (j < 0)
         *          {
         *              found = false;
         *              break;
         *          }
         *          GambleCardValue current = GambleCardExtended.CalculateGambleCardValue(j);
         *          if (occurences[current].Count <= 0)
         *          {
         *              found = false;
         *              break;
         *          }
         *          else
         *          {
         *              found = true;
         *          }
         *      }
         *      if (found)
         *      {
         *      }
         *  }
         *  //We dont need to sort since we start at ACE, go to King, and then loop back down to ACE
         *  //(We skip the last ace since we cant start with an Low-Ace, (we can with a High-Ace), because Low-Ace is the lowest card
         *
         *  //Cant do an implicit conversion, and explicit didn't work last time i checked, but this does :D
         *  IList<IList<T>> ret = new List<IList<T>>(allStraights);
         *  return ret;
         * }
         */
        //Generic Gets
        public static T GetHighCard <T>(this IGambleCardHand <T> self) where T : IGambleCard
        {
            if (self.Count <= 0)
            {
                return(default(T));
            }
            Dictionary <GambleCardFace, IList <T> > occurences = self.GetValueOccurenceList();

            for (int i = 13; i > 0; i--)
            {
                GambleCardFace val = GambleCardExtended.CalculateGambleCardValue(i);
                if (occurences[val].Count > 0)
                {
                    return(occurences[val][0]);
                }
            }
            return(default(T));
        }
        public static bool HasXConsecutive <T>(this IGambleCardHand <T> self, int x) where T : IGambleCard
        {
            if (x < 2)
            {
                //if x <= 1, then this is useless to call, still we return false
                return(false);
            }
            Dictionary <GambleCardFace, int> occurences = self.GetValueOccurenceCount();
            bool found = true;

            for (int i = 0; i <= 13 - (x - 1); i++)
            {
                for (int j = i; j < i + x; j++)
                {
                    if (j > 13)
                    {
                        found = false;
                        break;
                    }
                    GambleCardFace current = GambleCardExtended.CalculateGambleCardValue(j);
                    if (occurences[current] <= 0)
                    {
                        found = false;
                        break;
                    }
                    else
                    {
                        found = true;
                    }
                }
                if (found)
                {
                    return(true);
                }
            }
            return(found);
        }
        //We dont return a list of a list?
        //Unlike other Gets, we only care about the best case scenario
        public static IList <IList <T> > GetXOfAKind <T>(this IGambleCardHand <T> self, int x) where T : IGambleCard
        {
            Dictionary <GambleCardFace, IList <T> >
            myOccurences = self.GetValueOccurenceList();
            List <IList <T> >
            myListOfKinds = new List <IList <T> >();

            if (!self.HasXOfAKind(x))
            {
                return(new List <IList <T> >());
            }

            for (int i = 13; i > 0; i--)
            {
                GambleCardFace val = GambleCardExtended.CalculateGambleCardValue(i);
                IList <T>
                    tempOccurenceList = myOccurences[val];
                int occurences        = tempOccurenceList.Count;
                if (occurences >= x)
                {
                    for (int j = 0; j < occurences; j++)
                    {
                        List <T>
                        myList = new List <T>();
                        for (int k = j; k < x + j && k < occurences; k++)
                        {
                            myList.Add(tempOccurenceList[k]);
                        }
                        if (myList.Count >= x)
                        {
                            myList.Sort(
                                delegate(T a, T b)
                            {
                                return(a.CompareTo(b));
                            }
                                );
                            myListOfKinds.Add(myList);
                        }
                    }
                }
            }
            if (myListOfKinds.Count <= 0)
            {
                return(new List <IList <T> >());
            }
            myListOfKinds.Sort(
                delegate(IList <T> a, IList <T> b)
            {
                int ret = 0;
                for (int i = 0; i < a.Count && i < b.Count; i++)
                {
                    ret = -a[i].CompareTo(b[i]);
                    if (ret != 0)
                    {
                        return(ret);
                    }
                }
                return(-a.Count.CompareTo(b.Count));
            }
                );
            IList <IList <T> > returnList = (IList <IList <T> >)(myListOfKinds);

            return(returnList);
        }
        public static IList <IList <T> > GetXConsecutive <T>(this IGambleCardHand <T> self) where T : IGambleCard
        {
            int x = 5;
            List <IList <T> >
            allStraights = new List <IList <T> >();

            if (!self.HasXConsecutive(x))
            {
                return(new List <IList <T> >());
            }

            Dictionary <GambleCardFace, IList <T> >
            occurences = self.GetValueOccurenceList();

            bool found = true;

            for (int i = 13 - (x - 1); i >= 0; i--)
            {
                for (int j = i + (x - 1); j >= i; j--)
                {
                    if (j < 0)
                    {
                        found = false;
                        break;
                    }
                    GambleCardFace current = GambleCardExtended.CalculateGambleCardValue(j);
                    if (occurences[current].Count <= 0)
                    {
                        found = false;
                        break;
                    }
                    else
                    {
                        found = true;
                    }
                }
                if (found)
                {
                    GambleCardFace
                        aVal = GambleCardExtended.CalculateGambleCardValue(i + (x - 1) - 0),
                        bVal = GambleCardExtended.CalculateGambleCardValue(i + (x - 1) - 1),
                        cVal = GambleCardExtended.CalculateGambleCardValue(i + (x - 1) - 2),
                        dVal = GambleCardExtended.CalculateGambleCardValue(i + (x - 1) - 3),
                        eVal = GambleCardExtended.CalculateGambleCardValue(i + (x - 1) - 4);

                    for (int a = 0; a < occurences[aVal].Count; a++)
                    {
                        for (int b = 0; b < occurences[bVal].Count; b++)
                        {
                            for (int c = 0; c < occurences[cVal].Count; c++)
                            {
                                for (int d = 0; d < occurences[dVal].Count; d++)
                                {
                                    for (int e = 0; e < occurences[eVal].Count; e++)
                                    {
                                        List <T> temp = new List <T>();

                                        temp.Add(occurences[aVal][a]);
                                        temp.Add(occurences[bVal][b]);
                                        temp.Add(occurences[cVal][c]);
                                        temp.Add(occurences[dVal][d]);
                                        temp.Add(occurences[eVal][e]);

                                        allStraights.Add(temp);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //We dont need to sort since we start at ACE, go to King, and then loop back down to ACE
            //(We skip the last ace since we cant start with an Low-Ace, (we can with a High-Ace), because Low-Ace is the lowest card

            //Cant do an implicit conversion, and explicit didn't work last time i checked, but this does :D
            IList <IList <T> > ret = (IList <IList <T> >)(allStraights);

            return(ret);
        }