import acm.program.*;
import acm.graphics.*;
import acm.util.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;

public class XKCDColor extends GraphicsProgram {

	public static final int APPLICATION_HEIGHT = 650;
	public static final int APPLICATION_WIDTH = 750;

	public void run() {
		setBackground(Color.GRAY);
		initColorTable();
		initColorWheel();
		colorLabel = new GLabel("");
		colorLabel.setColor(Color.WHITE);
		colorLabel.setFont("SansSerif-14");
		add(colorLabel);
		addMouseListeners();
	}
	
	public void mousePressed(MouseEvent e) {
		int x = e.getX() - x0;
		int y = e.getY() - y0;
		if (x >= 0 && x < wheelWidth && y >= 0 && y < wheelHeight) {
			String name = colorTable.get(new Color(colorPixels[y][x]));
			if (name == null) {
				colorLabel.setLabel("");
			} {
				colorLabel.setLabel("  " + name);
				colorLabel.setLocation(e.getX(), e.getY() + LABEL_DY);
				repaint();
			}
		}
	}

	public void mouseDragged(MouseEvent e) {
		mousePressed(e);
	}

	private void initColorTable() {
		colorTable = new HashMap<Color,String>();
		try {
			BufferedReader rd = new BufferedReader(new FileReader(COLOR_DATA));
			while (true) {
				String line = rd.readLine();
				if (line == null) break;
				addColorTableEntry(line);
			}
		} catch (IOException ex) {
			throw new ErrorException(ex);
		}
	}
	
	private void addColorTableEntry(String line) {
		StringTokenizer tokenizer = new StringTokenizer(line, "[,] ");
		int r = Integer.parseInt(tokenizer.nextToken());
		int g = Integer.parseInt(tokenizer.nextToken());
		int b = Integer.parseInt(tokenizer.nextToken());
		String name = tokenizer.nextToken();
		while (tokenizer.hasMoreTokens()) {
			name += " " + tokenizer.nextToken();
		}
		colorTable.put(new Color(r, g, b), name);
	}

	private void initColorWheel() {
		GImage colorWheel = new GImage("ColorWheel.png");
		colorPixels = colorWheel.getPixelArray();
		wheelWidth = GMath.round(colorWheel.getWidth());
		wheelHeight = GMath.round(colorWheel.getHeight());
		x0 = GMath.round((getWidth() - wheelWidth) / 2);
		y0 = GMath.round((getHeight() - wheelHeight) / 2);
		add(colorWheel, x0, y0);
	}

/* Constants */
	private static final String COLOR_DATA = "XKCDColorSurvey.txt";
	private static final double LABEL_DY = 4;
	
/* Instance variables */
	private int x0;
	private int y0;
	private int wheelWidth;
	private int wheelHeight;
	private GLabel colorLabel;
	private HashMap<Color,String> colorTable;
	private int[][] colorPixels;
}
