/*
 * Copyright (c) 1997, Subrahmanyam Allamaraju. All Rights Reserved.
 * 
 * Permission to use, copy, modify, and distribute this software for
 * NON-COMMERCIAL purposes and without fee is hereby granted provided that this
 * copyright notice appears in all copies.
 *
 * This software is intended for demonstration purposes only, and comes without
 * any explicit or implicit warranty.
 *
 * Please report any bugs to subrahmanyam@geocities.com
 *
 */


import java.awt.*;
import java.awt.image.*;
import java.applet.*;
import java.util.*;
import java.net.*;
import java.io.*;



public class SleekButton extends Canvas 
{

    /*
     * Static variables common to all buttons.
     */
    static ButtonBar parent;
    static Color borderColor = new Color(0, 0, 0);
    static Font font = null;
    static Color textColor;
    static String target;
    static int buttonWidth = 0;
    static int buttonHeight = 0;
    String position = "left";
    static String align = "left";
    static int borderWidth = 2;
    /*
     * Private variables specific to a button.
     */
    String label;
    URL url = null;
    ThreeDBorder buttonBorder;
    int xpos, ypos;
    Rectangle hintRect;
    int hxpos, hypos;
    Font sFont = null;
    String hint = null;
    
    /*
     * Local variables.
     */
    boolean gotFocus = false;
    boolean pressed = false;
    
    boolean shadow, isActive;
    static String FILL = "MX";
    
    /*
     * A dummy constructor.
     */
    SleekButton() 
	{
	    super();
	}
    
    /*
     * Construct a button.
     */
    SleekButton(String label, String document, boolean Shadow, String hint) 
	{
	    this.label = label;
	    this.shadow = shadow;
	    try {
		this.url = new URL(document);
	    }
	    catch(MalformedURLException e) {
		System.out.println("Hell got loose!");
	    }
	    
	    buttonBorder = new ThreeDBorder(0, 0, size().width, size().height,
					    this.borderWidth, borderColor);
	    this.hint = hint;
	    
	}
    
    public void setFont(String font, int size) 
	{
	    this.font = new Font(font, Font.BOLD, size);
	}
    
    public void setParent(ButtonBar parent) 
	{
	    this.parent = parent;
	}
    
    public void setTarget(String target) 
	{
	    this.target = target;
	}
    
    public void setBorderWidth(int borderWidth) 
	{
	    this.borderWidth = (borderWidth > 0) ? borderWidth : 2;
	}

    public void setBorderColor(Color borderColor) 
	{
	    this.borderColor = borderColor;
	}
    
    public void setTextColor(Color color) 
	{
	    this.textColor = color;
	}
    
    public void setAlign(String align) 
	{
	    this.align = align;
	}
    
    public void setShadow(boolean shadow) 
	{
	    this.shadow = shadow;
	}

    /*
     * Should be called after all the set methods have been called.
     */
    public void setButton() 
	{
	    /*
	     * Compute the maximum width and height of the button.
	     */
	    FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
	    
	    buttonWidth = this.size().width;
	    
	    buttonWidth = (fm.stringWidth(FILL + label + FILL) > buttonWidth)
		? fm.stringWidth(FILL + label + FILL) : buttonWidth;
	    
	    buttonHeight = fm.getHeight() + 2 * (fm.getDescent() +
						 fm.getLeading());

	    /*
	     * Construct the border.
	     */
	    buttonBorder = null;
	    
	    buttonBorder = new ThreeDBorder(0, 0, size().width, size().height,
					    this.borderWidth, this.borderColor);
	    
	    /* 
	     * Compute the text position.
	     */
	    int height = fm.getHeight();
	    int ascent = fm.getAscent();
	    int leading = fm.getLeading();
	    int verMarzin = (size().height - height)/2;
	    
	    if(align.equals("left")) {
		xpos = fm.stringWidth(FILL);
		ypos = verMarzin + ascent + leading;
	    }
	    else if(align.equals("right")) {
		xpos = this.buttonWidth - fm.stringWidth(label + FILL);
		ypos = verMarzin + ascent + leading;
	    }
	    else if(align.equals("center")) {
		xpos = (this.buttonWidth - fm.stringWidth(label))/2;
		ypos = verMarzin + ascent + leading;
	    }
	    
	    if(hint != null) {
		sFont = new Font("Helvetica", Font.PLAIN, 11);
		//gr.setFont(sFont);
		fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
		if(align.equals("left")) {
		    hintRect = new Rectangle(10, this.size().height -
					     fm.getHeight() - 4,
					     fm.stringWidth(hint) + 2, 
					     fm.getHeight() + 2);
		    hxpos = 11;
		    hypos = hintRect.y + hintRect.height - 4;
		}
		else if(align.equals("right")) {
		    hintRect = new Rectangle(this.buttonWidth -
					     fm.stringWidth(hint) - 12, 
					     this.size().height -
					     fm.getHeight()- 4,
					     fm.stringWidth(hint) + 2,
					     fm.getHeight() + 2); 
		    hxpos = hintRect.x + 1;
		    hypos = hintRect.y + hintRect.height - 4;
		}
		else if(align.equals("center")) {
		    hintRect = new Rectangle(this.buttonWidth -
					     fm.stringWidth(hint) -12,
					     this.size().height - 
					     fm.getHeight() - 4, 
					     fm.stringWidth(hint) + 2,
					     fm.getHeight() + 2);
		    hxpos = hintRect.x + 1;
		    hypos = hintRect.y + hintRect.height - 4;
		}
	    }
	}
    

    
    public int getHeight() 
	{
	    return this.buttonHeight;
	}

    public int getWidth() 
	{
	    return this.buttonWidth;
	}
        
    public void paint(Graphics g) 
	{
	    update(g);
	}

    
    public void update(Graphics g) 
	{
	    this.setButton();
	    
	    g.setColor(textColor);
	    
	    if(gotFocus && !pressed) {
		buttonBorder.setStatus(ThreeDBorder.FOCUSSED);

	    }
	    else if(pressed && gotFocus) {
		buttonBorder.setStatus(ThreeDBorder.DEPRESSED);
	    }
	    else {
		buttonBorder.setStatus(ThreeDBorder.DEFAULT);
	    }
	    
	    buttonBorder.setWidth(size().width);
	    buttonBorder.setHeight(size().height);
	    
	    buttonBorder.paint(g);
	    
	    g.setFont(font);
	    
	    if(shadow) {
		if(gotFocus && !pressed) {
		    g.setColor(VColor.brighterShade(textColor));
		    g.drawString(label, xpos, ypos);
		    
		    g.setColor(textColor);
		    g.drawString(label, xpos + borderWidth, ypos + borderWidth);
		}
		else {
		    g.setColor(textColor);
		    g.drawString(label, xpos, ypos);
		    
		}
	    } else {
		g.setColor(textColor);
		g.drawString(label, xpos, ypos);
	    }
	    if(gotFocus && !pressed) showHint(g);
		
	}
        

    public boolean mouseDown(Event evt, int x, int y) 
	{
	    this.pressed = true;
	    this.repaint();
	    parent.getAppletContext().showDocument(url, target); 
	    return true;
	}

    public boolean mouseUp(Event evt, int x, int y) 
	{
	    this.pressed = false;
	    this.repaint();
	    return true;
	}

    public boolean mouseEnter(Event evt, int x, int y) 
	{
	    this.gotFocus = true;
	    this.repaint();
	    parent.showStatus("Go to " + url.toString());
	    return true;
	} 

    public boolean mouseExit(Event evt, int x, int y) 
	{
	    this.gotFocus = false;
	    this.repaint();
	    parent.showStatus(" ");
	    return true;
	} 

    private void showHint(Graphics g) 
	{
	    if(hintRect != null && hint != null) {
		g.setColor(Color.black);
		g.drawRect(hintRect.x - 1, hintRect.y - 1, hintRect.width + 1,
			   hintRect.height + 1);
		g.setColor(Color.yellow);
		g.fillRect(hintRect.x, hintRect.y, hintRect.width,
			   hintRect.height); 
		g.setColor(Color.black);
		g.setFont(sFont);
		
		g.drawString(hint, hxpos, hypos);
		
	    }
	}
    
}
