/* @(#)FifteenPuzzleUsingImage.java   9 October 2008 */

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;
import edu.neu.ccs.codec.*;
import edu.neu.ccs.console.*;
import edu.neu.ccs.filter.*;
import edu.neu.ccs.jpf.*;
import edu.neu.ccs.parser.*;
import edu.neu.ccs.pedagogy.*;
import edu.neu.ccs.quick.*;
import edu.neu.ccs.util.*;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.awt.image.*;

import javax.swing.*;
import javax.swing.border.*;
import java.io.*;
import java.util.*;
import java.math.*;
import java.beans.*;
import java.lang.reflect.*;
import java.net.URL;
import java.util.regex.*;
import java.text.ParseException;

public class FifteenPuzzleUsingImage
    extends FifteenPuzzle
{
    /////////////////
    // Static Data //
    /////////////////
    
    /** The image path on the web. */
    public static final String path = "http://www.ccs.neu.edu/jpt/archive/2.8.0/images/";
    
    /** The image file name. */
    public static final  String file = "YellowRose.jpg";
    
    /** The image URL object. */
    protected static URL url = null;
    
    /** The image as an ImagePaintable. */
    protected static ImagePaintable image = null;
    
    
    ///////////////////////////
    // Static Initialization //
    ///////////////////////////
    
    static { initImage(); }
    
    
    /////////////////
    // Member Data //
    /////////////////
    
    /** The action to show the final image in a separate panel. */
    protected SimpleAction showImageAction = new SimpleAction("Show Rose Image") {
        public void perform() { showImage(); }
    };
    
    
    /////////////////
    // Constructor //
    /////////////////
    
    /** The constructor. */
    public FifteenPuzzleUsingImage() {
        initializePanelSupplement();
    }
    
    
    ////////////////////
    // Member Methods //
    ////////////////////
    
    /**
     * The code to make the puzzle pieces.
     * 
     * This overrides the method in the base class.
     */
    protected void makePuzzlePieces() {
        boolean error = (image == null) || (image.getImageWidth() <= 1);
        
        if (error) {
            super.makePuzzlePieces();
            return;
        }
        
        for (int i = 0; i < count; i++) {
            int row = i / size;
            int col = i % size;
            
            pieces[i] = makeImageBlock(row, col);
        }
    }
    
    
    /** The code to make one image block at the given row and col. */
    protected ImagePaintable makeImageBlock(int row, int col) {
        BufferedImage bi =
            new BufferedImage
                (blockSize, blockSize, BufferedImage.TYPE_INT_RGB);
        
        int x = blockSize * col;
        int y = blockSize * row;
        
        Graphics2D g = (Graphics2D) bi.getGraphics();
        
        image.paintAt(g, -x, -y);   // Note the minus signs
        
        return new ImagePaintable(bi);
    }
    
    
    /**
     * Supplement to
     * the code to initialize and install the main panel.
     */
    protected void initializePanelSupplement() {
        int next = mainPanel.getRowCount() + 1;
        mainPanel.addObject(showImageAction, next);
    }
    
    
    /** The code to show the final image in a separate panel. */
    protected void showImage() {
        boolean error = (image == null) || (image.getImageWidth() <= 1);
        
        if (error) {
            GeneralDialog.showOKDialog("Rose Image Failed To Load", "Error");
            return;
        }
        
        DisplayPanel imagePanel = new DisplayPanel();
        imagePanel.addObject(image);
        imagePanel.frame("Rose Image", EAST);
    }
    
    
    ////////////////////
    // Static Methods //
    ////////////////////
    
    static void initImage() {
        try {
            url = new URL(path + file);
        }
        catch (Exception ex) {
            String message = "URL constructor failed\n"
                + "Path: " + path + "\n"
                + "File: " + file + "\n";
            
            GeneralDialog.showOKDialog(message, "Error");
            return;
        }
        
        image = new ImagePaintable(url);
    }
    
    
    ///////////////////////////////////////////////////////
    // The method main: Entry point to start the program //
    ///////////////////////////////////////////////////////
    
    /** The main method. */
    public static void main(String[] args) {
        new FifteenPuzzleUsingImage().frame("15 Puzzle Using Image");
    }
    
}
