import java.awt.*;
import java.awt.image.*;
import java.util.HashMap;

/** Represents a surface texture. Basically, this should be a
 * rectangle, usually something that is repeated across a
 * surface. */
public class Texture {
	private Dimension dim;
	private Image all;
	private Color mean;
	private TextureColumn[] columns;

	private Texture(Dimension dim, Image all, int[] src) {
		this.dim = dim;
		this.all = all;

		// compute mean color
		int r = 0;
		int g = 0;
		int b = 0;
		for(int i = 0; i < src.length; i++) {
			int p = src[i];
			r += (p >> 16) & 0xFF;
			g += (p >>  8) & 0xFF;
			b += (p      ) & 0xFF;
		}
		this.mean = new Color(r / src.length, g / src.length,
			b / src.length);

		// compute columns
		this.columns = new TextureColumn[dim.width];
		for(int i = 0; i < dim.width; i++) {
			this.columns[i] = new TextureColumn(src, i, dim.width,
									dim.height, mean);
		}
	}

	/** Returns the height of this texture, in pixels. */
	public int getHeight() { return dim.height; }

	/** Returns the width of this texture, in pixels. */
	public int getWidth() { return dim.width; }

	/** Returns the average color for this texture. */
	public Color getMeanColor() { return mean; }

	/** Returns a column of this texture. This column may then
	 * be mappped onto the screen. */
	public TextureColumn getColumn(int c) { return columns[c]; }

	private static HashMap<String, Texture> loaded
		= new HashMap<String, Texture>();

	/** Creates a texture for the given filename. The filename
	 * may be for a GIF or JPEG file. */
	public static Texture load(String filename) {
		Texture ret = (Texture) loaded.get(filename);
		if(ret != null) return ret;

		Toolkit tk = Toolkit.getDefaultToolkit();
		Image img = tk.createImage(filename);
		if(img == null) {
			System.out.println("null image");
			return null;
		}

		Dimension dim = ImageUtil.getDimension(img);
		if(dim.width <= 0 || dim.height <= 0) {
			System.out.println("empty image");
			return null;
		}

		// load pixels into memory
		int[] pix = new int[dim.width * dim.height];
		PixelGrabber grabber = new PixelGrabber(img,
				0, 0, dim.width, dim.height, pix, 0, dim.width);
		try {
			grabber.grabPixels();
		} catch(InterruptedException e) {
			System.out.println("not grabbed");
			return null;
		}
		if((grabber.getStatus() & ImageObserver.ABORT) != 0) {
			System.out.println("aborted");
			return null;
		}

		ret = new Texture(dim, img, pix);
		loaded.put(filename, ret);
		return ret;
	}
}
