'''
Brian Crabtree
CollectionOfUnoCards.py
Simulate the deck for the game "Uno"
'''

import random
from UnoCard import UnoCard

class CollectionOfUnoCards:

    MAXCARDS = 72

    # Creates an empty Collections.
    def  __init__(self):
        self.deck = []
        self.numCards = 0

    # Adds c to the end of this collection.
    def addCard(self, c):
        if self.numCards == CollectionOfUnoCards.MAXCARDS:
            return False
        
        self.deck.append(c)
        self.numCards += 1

    # Clears out this collection and fills it with all of the cards
    # in the deck. 
    def makeDeck(self):
        self.deck = []
        for i in range(0, 4):
            for j in range(1, 10):
                self.deck.append(UnoCard(i, j))
                self.deck.append(UnoCard(i, j))
                self.numCards += 2

    # Shuffles the cards in this collection. (This can be achieved
    # by repeatedly picking two cards at random and swapping them.
    # A couple hundred times should suffice.
    def shuffle(self):
        for i in range(1, 500):
            ind1 = random.randint(0, self.numCards - 1)
            ind2 = random.randint(0, self.numCards - 1)
            while ind1 == ind2:
                ind2 = random.randint(0, CollectionOfUnoCards.MAXCARDS - 1)
            temp = self.deck[ind1]
            self.deck[ind1] = self.deck[ind2]
            self.deck[ind2] = temp
            

    # Returns a String representation of the collection, as shown
    # in the example output.
    def __str__(self):

        result = ""
        for i in range(0, self.numCards - 1):
            result += str(str(i) + ". " + str(self.deck[i]) + "\n")
        return result

    # Returns the number of cards in the collection.
    def getNumCards(self):
        return self.numCards

    # Returns the top card in the collection without removing it.
    def getTopCard(self):
        if self.numCards > 0:
            return self.deck[self.numCards - 1]
        return None

    # Returns true if there exists at least one card in this 
    # collection that can be played on the card c.
    def canPlay(self, c):
        for i in range(0, self.numCards):
            if self.deck[i].canPlay(c):
                return True
        return False

    # Returns the card in location index of the collection.
    def getCard(self, index):
        if index < 0 or index >= self.numCards:
            return None
        return self.deck[index]
