/* @(#)PlayingCards.java   19 September 2006 */

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;
import edu.neu.ccs.util.*;

import java.awt.*;
import javax.swing.*;

/**
 * <p>Class <code>PlayingCards</code> displays images of the
 * 52 traditional cards in the suits hearts, diamonds, spades,
 * and clubs, plus 2 card backs and 2 jokers.</p>
 */
public class PlayingCards
    extends DisplayPanel
{
    /** The default size of the graphics window. */
    public static int SIZE = 600;
    
    /** The minimum size of the graphics window. */
    public static int MINIMUM_SIZE = 400;
    
    /** The table panel gap. */
    private int gap = 20;
    
    
    /** The BufferedPanel window. */
    BufferedPanel window = null;
    
    
    /** The window width. */
    private int w0;
    
    /** The window height. */
    private int h0;
    
    
    /** The card width. */
    private int w1;
    
    /** The card height. */
    private int h1;
    
    
    /** The minimum x position for a card. */
    private int minX;
    
    /** The maximum x position for a card. */
    private int maxX;
    
    /** The minimum y position for a card. */
    private int minY;
    
    /** The maximum y position for a card. */
    private int maxY;
    
    
    /** The JFitz card deck URL. */
    private String cardsURL  =
        "http://www.ccs.neu.edu/jpt/images/jfitz_cards/";
    
    /** The image list file name for reading the cards. */
    private String cardsList =
        "imagelist.txt";
    
    /** The JFitz card deck as an ImagePaintableLite[]. */
    private ImagePaintableLite[] cards =
        WebImageTools.readImagesAsPaintableLite
            (cardsURL, cardsList);
    
    /** The size of the card deck. */
    private int N;
    
    
    /** The action to show random cards. */
    private SimpleAction randomCards =
        new SimpleAction("Random Cards") {
            public void perform() { showRandomCards(); }
    };
    
    
    /** The default constructor. */
    public PlayingCards() {
        this(SIZE, SIZE);
    }
    
    
    /**
     * The constructor that specifies the width and height
     * of the graphics window as a single value size.
     * 
     * @param size the width and the height of the window
     */
    public PlayingCards(int size) {
        this(size, size);
    }
    
    
    /**
     * The constructor that specifies the width and height
     * of the graphics window separately.
     * 
     * @param width  the width  of the window
     * @param height the height of the window
     */
    public PlayingCards(int width, int height) {
        w0 = (width  < MINIMUM_SIZE) ? MINIMUM_SIZE : width;
        h0 = (height < MINIMUM_SIZE) ? MINIMUM_SIZE : height;
        
        initialize();
    }
    
    
    /** Initialize the playing cards. */
    private void initialize() {
        // obtain the size of the playing cards array
        N = cards.length;
        
        // exit if the cards could not be read
        if (N == 0) {
            String message = "The Playing Cards Failed to Load";
            
            GeneralDialog.showOKDialog(message, "Load Failure");
            
            return;
        }
        
        // initialize window
        window = new BufferedPanel(w0, h0);
        window.installSimpleMouseActions(true);
        
        // initialize constants for randomizing
        w1 = cards[0].getImageWidth();
        h1 = cards[0].getImageHeight();
        
        minX = 5;
        maxX = w0 - w1 - minX;
        
        minY = 5;
        maxY = h0 - h1 - minY;
        
        // create the GUI
        createGUI();
        
        // show playing cards in random positions
        showRandomCards();
    }
    
    
    /** Create GUI. */
    private void createGUI() {
        window.lineBorder(2);
        window.setBufferBackground(Colors.tan);
        
        JButton cardsButton = new JButton(randomCards);
        cardsButton.setBackground(Colors.tan);
        
        Object[] stuff = { window, cardsButton };
        VTable table = new VTable(stuff, gap, gap, CENTER);
        table.emptyBorder(gap);
        
        add(table);
    }
    
    
    /** Show playing cards in random positions. */
    public void showRandomCards() {
        // exit if the cards could not be read
        if (N == 0)
            return;
        
        // clear the window and paint its background
        window.clearPanelAndSequence();
        
        // obtain a permutation for randomizing the cards
        int[] permutation = ProbStatTools.randomPermutation(N);
        
        for (int i = 0; i < N; i++) {
            // pick a random card using the permutation
            int k = permutation[i];
            Paintable card = cards[k];
            
            // compute a random position for this card
            int x = MathUtilities.randomInt(minX, maxX);
            int y = MathUtilities.randomInt(minY, maxY);
            
            // move this card
            card.moveCornerTo(x, y);
            
            // append this card to the window sequence
            window.appendPaintable(card);
        }
        
        // make all changes visible
        window.repaint();
    }
    
    
    /**
     * <p>Construct a <code>PlayingCards</code> panel and put
     * it in its own frame.</p>
     * 
     * <p>This method allows this class to launch itself as a
     * Java application.</p>
     * 
     * @param args ignored here but nevertheless required
     */
    public static void main(String[] args) {
        new PlayingCards().frame("Playing Cards");
    }
    
}

