/* @(#)GamePaintables.java    25 September 2007 */

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;

import java.awt.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;


/**
 * <p>The class for the Concentration game paintable objects.</p>
 * 
 * <p>Uses Java Power Tools 2.6.0.</p>
 * 
 * <p>Copyright, Richard Rasala, 2007.</p>
 * 
 * @author Richard Rasala
 */
public class GamePaintables {
    
    /** The game image data for creating the image paintables. */
    protected GameImageData imageData = new GameImageData();
    
    
    /** The array of image paintables for Concentration. */
    protected Paintable[] imagePaintables = null;
    
    
    /** The array of shape paintables for Concentration. */
    protected Paintable[] shapePaintables = null;
    
    
    /** The array of letter paintables for Concentration. */
    protected Paintable[] letterPaintables = null;
    
    
    /** The array of number paintables for Concentration. */
    protected Paintable[] numberPaintables = null;
    
    
    /** The tile size: 100. */
    protected int size = 100;
    
    
    /** The middle of a tile in the x or y direction: 50. */
    protected int middle = size/2;
    
    
    /** The common bounds for all paintables: 0,0,100,100. */
    protected XRect bounds = new XRect(0, 0, size, size);
    
    
    /** The common center for image and shape paintables: 50,50. */
    protected XPoint2D center = new XPoint2D(middle, middle);
    
    
    /** The font size of the large font for letters and numbers: 72. */
    protected int fontSize = 72;
    
    
    /** The large font for letters and numbers: serif, plain, 72. */
    protected Font largeFont = new Font("serif", Font.PLAIN, fontSize);
    
    
    /**
     * The height of the letter A in the large font
     * for centering text vertically within a tile.
     */
    protected int heightOfA = getHeightOfA();
    
    
    /**
     * The y baseline for text in the large font
     * within a tile.
     */
    protected int baseline = (size + heightOfA)/2;
    
    
    /** The stroke for stroked game shapes: size 10 and rounded. */
    protected Stroke stroke = 
        new BasicStroke(10, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
    
    
    /** The colors for game shapes: black, red, green, blue. */
    protected Color[] colors = {
            Colors.black,
            Colors.red,
            Colors.green,
            Colors.blue
       };
    
    
    /**
     * <p>The default constructor that uses the default
     * game image data.</p>
     */
    public GamePaintables() {
        this(null);
    }
    
    
    /**
     * <p>The constructor that uses the given game image data
     * provided that this data is non-<code>null</code>.</p>
     *
     */
    public GamePaintables(GameImageData data) {
        if (data != null)
            imageData = data;
    }
    
    
    /** Return the tile size in pixels used for all paintables. */
    public int getTileSize() {
        return size;
    }
    
    
    /**
     * Return the image paintable array or <code>null</code>
     * if the image paintables cannot be built from web images.
     */
    public Paintable[] getImagePaintables() {
        if (imagePaintables == null)
            makeImagePaintables();
        
        return imagePaintables;
    }
    
    
    /** Return the shape paintable array. */
    public Paintable[] getShapePaintables() {
        if (shapePaintables == null)
            makeShapePaintables();
        
        return shapePaintables;
    }
    
    
    /** Return the letter paintable array. */
    public Paintable[] getLetterPaintables() {
        if (letterPaintables == null)
            makeLetterPaintables();
        
        return letterPaintables;
    }
    
    
    /** Return the number paintable array. */
    public Paintable[] getNumberPaintables() {
        if (numberPaintables == null)
            makeNumberPaintables();
        
        return numberPaintables;
    }
    
    
    /** Make the image paintable array. */
    protected void makeImagePaintables() {
        String imagesURL = imageData.getImagesURL();
        String name = imageData.getImageListFileName();
        
        imagePaintables =
            WebImageTools.readImagesAsPaintableLite(imagesURL, name);
        
        // return if images failed to load from the web
        if (imagePaintables == null)
            return;
        
        int length = imagePaintables.length;
        
        for (int k = 0; k < length; k++) {
            imagePaintables[k].setDefaultOriginalBounds2D(bounds);
            imagePaintables[k].setDefaultOriginalCenter(center);
        }
    }
    
    
    /** Make the shape paintable array. */
    protected void makeShapePaintables() {
        Shape[] filledshapes = GameShapes.getFilledGameShapes();
        Shape[] strokeshapes = GameShapes.getStrokeGameShapes();
        
        int f = filledshapes.length;
        int s = strokeshapes.length;
        int c = colors.length;
        
        int t = f + s;
        
        shapePaintables = new Paintable[t * c];
        
        for (int j = 0; j < c; j++) {
            Color color = colors[j];
            
            for (int i = 0; i < t; i++) {
                int k = t * j + i;
                
                if (i < f)
                    shapePaintables[k] = new ShapePaintable
                        (filledshapes[i], PaintMode.FILL, color);
                else
                    shapePaintables[k] = new ShapePaintable
                        (strokeshapes[i - f], PaintMode.DRAW, null, color, stroke);
                
                shapePaintables[k].setDefaultOriginalBounds2D(bounds);
                shapePaintables[k].setDefaultOriginalCenter(center);
            }
        }
    }
    
    
    /** Make the letter paintable array. */
    protected void makeLetterPaintables() {
        letterPaintables = new Paintable[26];
        
        int baseIndex = Character.getNumericValue('A');
        
        for (char c = 'A'; c <= 'Z'; c++) {
            int i = Character.getNumericValue(c) - baseIndex;
            
            letterPaintables[i] = makeTextPaintable("" + c);
        }
    }
    
    
    /** Make the number paintable array. */
    protected void makeNumberPaintables() {
        numberPaintables = new Paintable[100];
        
        for (int i = 0; i <= 99; i++) {
            numberPaintables[i] = makeTextPaintable("" + i);
        }
    }
    
    
    /**
     * Make a text paintable from a string centered in a tile
     * using the large text font.
     */
    protected Paintable makeTextPaintable(String s) {
        TextPaintable paintable =
            new TextPaintable
                (s, largeFont, Colors.black, TextBounds.TIGHT,
                 TextAnchor.CENTER_BASELINE, middle, baseline);
        
        paintable.setDefaultOriginalBounds2D(bounds);
        
        return paintable;
    }
    
    
    /** Find the text height of the letter A. */
    protected int getHeightOfA() {
        TextPaintable paintable =
            new TextPaintable
                ("A", largeFont, Colors.black, TextBounds.TIGHT,
                 TextAnchor.CENTER_BASELINE, 0, 0);
        
        Rectangle2D textbounds = paintable.getBounds2D();
        
        return (int) textbounds.getHeight();
    }
    
}

