package plots;

import java.awt.*;

// essentially an abstract class; mouse down/up should be redefined
/** There are many colours involved:
	background unpressed
	background pressed
	text pressed
	text unpressed
	shadow
	light
*/

public class ButtonCanvas extends Canvas {
	public final static int PRESSED = 0, UNPRESSED = 1;
	Image bg[];
	String text;
	int cbg = UNPRESSED;
	int w, h;
	Color unpressedTextColor = Color.black;
	Color pressedTextColor = new Color(1.0f, 1.0f, 0.0f);
	static int px = 2;

	static Color defaultUnpressedColor = Color.lightGray;
	static Color defaultPressedColor = new Color(0.7f, 0.7f, 0.7f);
	static Color defaultShadow = Color.gray;
	static Color defaultLight = new Color(0.9f, 0.9f, 0.9f);
	Color unpressedColor = defaultUnpressedColor;
	Color pressedColor = defaultPressedColor;
	Color shadow = defaultShadow;
	Color light = defaultLight;
	Image img0 = null, img1 = null;
	
	Graphics gfx;

	// img0, img1 are to be added later
	public ButtonCanvas(int w, int h, Image img0, Image img1) {
		this.w = w;
		this.h = h;
		this.img0 = img0;
		this.img1 = img1;
		text = null;
	}
	
	public ButtonCanvas(String text, int w, int h) {
		this.w = w;
		this.h = h;
		this.text = text;
	}
	
	public ButtonCanvas(String text, int w, int h, Color down, Color up) {
		this.w = w;
		this.h = h;
		this.text = text;
		pressedColor = down;
		unpressedColor = up;
	}
	
	public void addNotify() {
		super.addNotify();
		gfx = getGraphics();
		if (bg == null) {
			bg = new Image[2];
			mkImages();
		}
	}
	
	void mkImages() {
		bg[UNPRESSED] = buttonImage(this, w, h, UNPRESSED);
		bg[PRESSED] = buttonImage(this, w, h, PRESSED);
		if (text != null) {
			setText(bg[UNPRESSED], text, unpressedTextColor);
			setText(bg[PRESSED], text, pressedTextColor);
		} else if (img0 != null) {
			// add imgx to bg[x]
			int w0 = img0.getWidth(null);
			int h0 = img0.getHeight(null);
			Graphics g = bg[UNPRESSED].getGraphics();
			g.drawImage(img0, (w-w0)/2, (h - h0)/2, null);
			int w1 = img1.getWidth(null);
			int h1 = img1.getHeight(null);
			g = bg[PRESSED].getGraphics();
			g.drawImage(img1, (w-w1)/2, (h - h1)/2, null);
		}
	}
	
	public Image buttonImage(Component c, int w, int h, int mode) {
		Image img = c.createImage(w, h);
		Graphics gr = img.getGraphics();
		Color top, bottom, bg;
		if (mode == UNPRESSED) {
			top = defaultLight;
			bottom = defaultShadow;
			bg = unpressedColor;
		} else {
			// mode = PRESSED
			top = defaultShadow;
			bottom = defaultLight;
			bg = pressedColor;
		}
		gr.setColor(bg);
		gr.fillRect(px,px,w-2*px,h-2*px);
		// highlights px pixels wide
		// recall that (w,h) are coords of centre
		// ***********
		// #*********(w-1)
		// ##*******
		// ###
		//
		// ###
		// ##
		// #
		// (h-1)
		gr.setColor(top);
		for (int i=0;i<px;i++) {
			gr.drawLine(0, i, w-1-i, i);
		}
		for (int i=0;i<px;i++) {
			gr.drawLine(i, px, i, h-2-i);
		}
		gr.setColor(bottom);
		for (int i=0;i<px;i++) {
			gr.drawLine(i, h-1-i, w, h-1-i);
		}
		for (int i=0;i<px;i++) {
			gr.drawLine(w-i-1, i+1, w-i-1, h-px);
		}
		return(img);
	}
	
	public void setText(Image img, String text, Color c) {
		Graphics gr = img.getGraphics();
		gr.setColor(c);
		Font fn = gr.getFont();
		int fontSize = fn.getSize();
		int v = (h - fontSize)/2 + 1;
		FontMetrics fm = gr.getFontMetrics(gr.getFont());
		gr.drawString(text, (w - fm.stringWidth(text))/2, h - v);
	}
	
	public Dimension preferredSize() {
		return(new Dimension(w, h));
	}
	
	public Dimension minimumSize() {
		return(new Dimension(w, h));
	}
	
	// unpressed, pressed
	public void setColors(Color a, Color b) {
		unpressedColor = a; pressedColor = b;
	}
	
	public void setTextColors(Color a, Color b) {
		unpressedTextColor = a; pressedTextColor = b;
	}
	
	public void setText(String s) {
		text = s;
		mkImages();
	}
	
	public boolean isDown() {
		return(cbg == PRESSED);
	}
	
	/** Reverses the normal ordering of paint() and 
		update() for flicker-free performance. */
	public void paint(Graphics g) {
		update(g);
	}

	public void update() {
		update(getGraphics());
	}
	
	public void update(Graphics g) {
		g.drawImage(bg[cbg], 0, 0, null);
	}

	public void press() {
		cbg = PRESSED;
		update(getGraphics());
	}

	public void release() {
		cbg = UNPRESSED;
		update(getGraphics());
	}

	public boolean mouseDown(Event e, int x, int y) {
		if (cbg == UNPRESSED) {
			press();
		}
		return(super.mouseDown(e, x, y));
	}

	public boolean mouseUp(Event e, int x, int y) {
		// System.err.println("Up");
		if (cbg == PRESSED) {
			release();
		}
		return(super.mouseUp(e, x, y));	}

}
