/*
 * Slicer - slices a big image into smaller ones
 *
 * by Adam Doppelt
 * http://www.cs.brown.edu/people/amd/
 */
import java.awt.*;
import java.awt.image.*;
import java.applet.Applet;
import java.net.*;

public class Slicer implements ImageObserver {
    MediaTracker tracker_;
    Applet applet_;
    Image big_, cells_[][];
    int rows_, cols_, cellWidth_, cellHeight_, id_;
    
    public Slicer(Applet applet, String url, int rows, int cols) {
	URL u = null;
	try {
	    u = new URL(url);
	} catch (MalformedURLException e) { ; }
	big_ = applet.getImage(u);

	applet_ = applet;
	int width = big_.getWidth(this);
	
	// Big Bug fixed here.
	int height = big_.getHeight(this);

	if (width != -1)
	    cellWidth_ = width / cols;
	else
	    cellWidth_ = -1;

	if (height != -1)
	    cellHeight_ = height / rows;
	else
	    cellHeight_ = -1;

	rows_ = rows;
	cols_ = cols;
	cells_ = new Image[cols][rows];
	tracker_ = new MediaTracker(applet);
	id_ = 0;
    }

    public synchronized Image GetCell(int row, int col, boolean wait) {
	if (cells_[col][row] == null) {
	    if (cellWidth_ == -1 || cellHeight_ == -1) {
		try {
		    wait();
		} catch (InterruptedException e) { ; }
	    }

	    if (cellWidth_ == -1 || cellHeight_ == -1)
		return null;
	    
	    ImageFilter cropper = new CropImageFilter(col * cellWidth_,
						      row * cellHeight_,
						      cellWidth_, cellHeight_);
	    
	    Image cell = applet_.createImage(
		new FilteredImageSource(big_.getSource(), cropper));
	    
	    if (wait) {
		++id_;
		tracker_.addImage(cell, id_);
		try {
		    tracker_.waitForID(id_);
		} catch (InterruptedException e) { ; }
	    }

	    cells_[col][row] = cell;
	    return cell;
	}
	else
	    return cells_[col][row];
    }

    public synchronized Image[][] GetAllCells(boolean wait) {
	if (cellWidth_ == -1 || cellHeight_ == -1) {
	    try {
		wait();
	    } catch (InterruptedException e) { ; }
	}
	
	if (cellWidth_ == -1 || cellHeight_ == -1)
	    return null;

	for (int row = 0; row < rows_; ++row)
	    for (int col = 0; col < cols_; ++col) {
		if (cells_[col][row] == null) {
		    ImageFilter cropper = new CropImageFilter(
			col * cellWidth_, row * cellHeight_,
			cellWidth_, cellHeight_);
		    
		    cells_[col][row] = applet_.createImage(
			new FilteredImageSource(big_.getSource(), cropper));

		    if (wait) {
			++id_;
			tracker_.addImage(cells_[col][row], id_);
		    }
		}
	    }

	if (wait) {
	    try {
		tracker_.waitForAll();
	    } catch (InterruptedException e) { ; }
	}

	return cells_;
    }
    
    public synchronized boolean imageUpdate(Image image, int infoflags,
                               int x, int y, int width, int height) {
	if (image == big_) {
	    if (cellWidth_ == -1 || cellHeight_ == -1) {
		if ((infoflags & (WIDTH + HEIGHT)) != 0) {
		    cellWidth_ = width / cols_;
		    cellHeight_ = height / rows_;
		    notifyAll();
		    return false;
		}
		else if ((infoflags & ERROR) != 0) {
		    notifyAll();
		    return false;
		}
		else
		    return true;
	    }
	}
	return false;
    }
}
