/*
 Javier Kohen's Java Framework Classes.
 Copyright (C) 2000  Javier Kohen <jkohen at tough.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 package ar.com.jkohen.awt;
 
 import java.awt.*;
 import java.awt.event.*;
 
 import ar.com.jkohen.util.Resources;
 
 public class ImageButton extends Canvas implements MouseListener, MouseMotionListener
 {
 	public final static int NORMAL = 0;
 	public final static int PRESSED = 1;
 	public final static int DISABLED = 2;
 	public final static int ALERT = 3;
 	
 	public final static int STATES = 4;
 
 	private ActionListener actionListener;
 
 	Graphics gr;
 	Image image;
 
 	private Image stateImages[];
 	private String text;
 	private Image icon;
 	private int shift;
 	private int button_width = 0, button_height = 0;
 	private int leftBorder = 3, topBorder = 3;
 	private boolean pos_icon = true;
 
 	private FontMetrics fm;
 	private int baseline;
 	private int text_height = 0, text_width = 0, text_base = 0;
 
 	protected String action_command;
 
 	protected int state = NORMAL;
 
 	protected boolean mouseOver = false;
 	protected boolean mousePressed = false;
 	
 	private static boolean hasWindowFocus = true;
 
 	public ImageButton()
 	{
 		setButtonType(true);
 	}
 	
 	public ImageButton(boolean b)
 	{
 		setButtonType(b);
 	}
 
 	public ImageButton(String t)
 	{
 		setButtonType(true);
 		setText(t);
 	}
 	
 	public ImageButton(String t, Image i)
 	{
 		setButtonType(true);		
 		setText(t);
 		setIcon(i);
 	}
 	
 	public void setButtonType(boolean b)
 	{
 		this.stateImages = new Image[STATES];
 		this.action_command = "";
 
 		addMouseListener(this);
 		addMouseMotionListener(this);
 		
 		if (b)
 		{
 			setImage(NORMAL, Resources.LARGE_NORMAL);
 			setImage(PRESSED, Resources.LARGE_PRESSED);
 			setImage(DISABLED, Resources.LARGE_DISABLED);
 			setImage(ALERT, Resources.LARGE_ALERT);
 		}
 		else
 		{
 			setImage(NORMAL, Resources.SMALL_NORMAL);
 			setImage(PRESSED, Resources.SMALL_PRESSED);
 			setImage(DISABLED, Resources.SMALL_DISABLED);
 		}
 	}
 	
 	public void setImage(int st, Image i)
 	{
 		this.stateImages[st] = i;
 	}
 
 	public void setIcon(Image i)
 	{
 		this.icon = i;
 	}
 	
 	public void setText(String t)
 	{
 		this.text = t;
 		fm = null;
 	}
 
 	public void setIconPosition(boolean b)
 	{
 		this.pos_icon = b;
 	}
 	
 	public void setWaitType()
 	{
 		setImage(DISABLED, Resources.LARGE_WAIT);
 	}
 	
 	private void createImageBuffer(Dimension size)
 	{
 		image = createImage(size.width, size.height);
 		if (gr != null)
 			gr.dispose();
 
 		gr = image.getGraphics();
 		
 		if (NewGraphics2D.hasRenderingHints)
 			NewGraphics2D.setRendering(gr);
 	}
 	
 	public void update(Graphics g)
 	{
 		paint(g);
 	}
 	
 	public void paint(Graphics g)
 	{
 		paintButton();
 		paintText();
 		g.drawImage(image, 0, 0, this);
 	}
 
 	public void paintButton()
 	{
 		Dimension size = getSize();
 		if (size.height > 0 && size.width > 0 && (gr == null || size.height != image.getHeight(this) || size.width != image.getWidth(this)))
 			createImageBuffer(size);
 			
 		if (!isEnabled())
 			this.state = DISABLED;
 
 		if (stateImages[state] != null)
 		{
 			gr.setColor(getBackground());
 			gr.fillRect(0, 0, getSize().width, getSize().height);
 
 			if (pos_icon || icon == null)
 				gr.drawImage(stateImages[state], 0, 0, this);
 			else
 				gr.drawImage(stateImages[state], icon.getWidth(this), 0, this);
 
 			button_width = stateImages[state].getWidth(this);
 			button_height = stateImages[state].getHeight(this);
 		}
 			
 		shift = 0;
 		if (state == DISABLED || state == PRESSED)
 			shift = 1;
 			
    		if (icon != null)
 		{
 			if (pos_icon)
 				gr.drawImage(icon, leftBorder + shift, topBorder + shift, this);
 			else
 				gr.drawImage(icon, 0, 0, this);
 		}
 		
 	}
 	
 	public void paintText()
 	{
 		if (gr == null) return;
 
 		gr.setColor(Color.black);
 		if (mouseOver)
 			gr.setColor(Color.blue);
 		if (state == DISABLED)
 			gr.setColor(Color.gray);
 			
 		if (text != null)
 		{
 			fm = gr.getFontMetrics();
 			text_height = fm.getMaxAscent() + fm.getMaxDescent() + fm.getLeading();
    		 	text_width = fm.stringWidth(text);
 			text_base = fm.getMaxAscent() + fm.getLeading();
 			
 			if (icon != null)
  				gr.drawString(text, (button_width - text_width - icon.getWidth(this)) / 2 + shift + icon.getWidth(this), (button_height - text_height - topBorder * 2) / 2 + text_base + topBorder + shift);
 			else
  				gr.drawString(text, (button_width - text_width) / 2 + shift, (button_height - text_height - topBorder * 2) / 2 + text_base + topBorder + shift);
 		}
 		
 	}
 	
 	public static void setWindowFocus(boolean b)
 	{
 		ImageButton.hasWindowFocus = b;
 	}
 	
 	public void mouseMoved(MouseEvent e)
 	{
 		if (!ImageButton.hasWindowFocus)
 			return;
 			
 		setCursor(new Cursor(Cursor.HAND_CURSOR));
 
 		this.mouseOver = true;
 		if (state == PRESSED)
 			return;
 			
 		this.state = mousePressed ? PRESSED : NORMAL;
 		
 		repaint();
 	}
 	
 	public void mouseDragged(MouseEvent e)
 	{
 	}
 
 	public void mouseClicked(MouseEvent e)
 	{
 	}
 		
 	public void mouseEntered(MouseEvent e)
 	{
 	}
 
 	public void mouseExited(MouseEvent e)
 	{
 		setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
 
 		this.mouseOver = false;
 		this.state = NORMAL;
 		
 		repaint();
 	}
 
 	public void mousePressed(MouseEvent e)
 	{
 		this.mousePressed = true;
 		this.state = PRESSED;
   		repaint();
 	}
 
 	public void mouseReleased(MouseEvent e)
 	{
 		this.mousePressed = false;
 		this.state = NORMAL;
 		repaint();
 		processActionEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED, action_command, e.getModifiers()));
 	}
 
 	public Dimension getPreferredSize()
 	{
 		int w = -1, h = -1;
 		w = stateImages[state].getWidth(this);
 		h = stateImages[state].getHeight(this);
 		
 		if (!pos_icon && icon != null)
 			w += icon.getWidth(this);
 		
 		return(new Dimension(w, h));
 	}
 
 	public Dimension getMinimumSize()
 	{
 		return(getPreferredSize());
 	}
 
 	public void setEnabled(boolean active)
 	{
 		if (isEnabled() != active)
 		{
 			this.state = NORMAL;
 			this.mouseOver = false;
 			super.setEnabled(active);
    			repaint();
 		}
 	}
 
 	public void setFont(Font f)
 	{
 		if (gr != null)
 			gr.setFont(f);
 		repaint();
 	}
 	
 	public void addActionListener(ActionListener l)
 	{
 		if (null != l)
 			actionListener = AWTEventMulticaster.add(actionListener, l);
 	}
 
 	public void removeActionListener(ActionListener l)
 	{
 		if (null != l)
 			actionListener = AWTEventMulticaster.remove(actionListener, l);
 	}
 
 	public String getActionCommand()
 	{
 		return action_command;
 	}
 
 	public void setActionCommand(String action)
 	{
 		this.action_command = action;
 	}
 
 	protected void processActionEvent(ActionEvent e)
 	{
 		if (actionListener != null)
 			actionListener.actionPerformed(e);
 	}
 }