package widget;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;



/**
 * The View (from the Model-View-Controller pattern)
 * for a Button.
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class ButtonView extends AbstractButtonView
{
    protected Button           button;
    protected Color            downColor, upColor;

    /**
     * Constructor
     *
     * @param button        The button this view belongs to
     * @param width         The width of the button (in pixels)
     * @param height        The height of the button (in pixels)
     */
    public ButtonView(Button button, int width, int height)
    {
	super(width, height);
	this.button = button;

	getWidget().setSize(width, height);

	button.setSize(new Dimension(width, height));
	button.setFont(new Font("Sans Serif", Font.PLAIN, 20));

	button.setBackground(ColorScheme.FRAME);

	setColors(ColorScheme.getButtonColors());

	downColor = Color.red;
	upColor   = Color.gray;
    }



    /**
     * Get the Button associated with this view
     *
     * @return   The Button
     */
    public Widget getWidget()
    {
	return button;
    }




    /**
     * Paint this component
     *
     * @param g  The Graphics context to use
     */
    public void paint(Graphics g)
    {
	paintBackground(g);
	paintText(g);
	paintBorder(g);
    }




    /**
     * Paint the background
     *
     * @param g   The Graphics context to use
     */
    protected void paintBackground(Graphics g)
    {
	Color      bgColor;
	Dimension  size;
	int        buttonType, h, w, x, y;


	size = button.getSize();


	// Fill the background
	bgColor = button.getBackground();
	g.setColor(bgColor);
	g.fillRect(0,0,size.width,size.height);


	// Fill the button
	if (button.hasFocus()) g.setColor(colors[FOCUSED][BACKGROUND]);
	else                   g.setColor(colors[UNFOCUSED][BACKGROUND]);

	if (shape == button.RECTANGLE)
        {
	    g.fillRect(0,0,size.width,size.height);
	}
        else if (shape == button.ROUNDED_RECTANGLE)
        {
	    g.fillRoundRect(0,0,size.width,size.height,
			    arcWidth,arcHeight);
	}


	// Render the icon (if one exists)
	//
	if (enabledIcon != null)
        {
	    h = enabledIcon.getHeight(null);
	    w = enabledIcon.getWidth(null);
	    x = (size.width  - w)/2;
	    y = (size.height - h)/2;

	    // Modify the icon location based on whether 
	    // the button is UP or DOWN
	    if (viewState == DOWN)
            {
		x += 2;
		y += 2;
	    }
	

	    g.drawImage(enabledIcon, x, y, null);
	}


	// Render the state indicator (if it's a toggle button)
	buttonType = button.getButtonType();

	if (buttonType == Button.TOGGLE)
        {
	    x = size.width -  25;
	    y = 5;
	    if (viewState == UP)
            {
		g.setColor(upColor);
	    } 
            else if (viewState == DOWN)
            {
		g.setColor(downColor);
		x += 2;
		y += 2;
	    }

	    g.fillRect(x, y, 20, 5);
	}
    }




     /**
     * Paint the border
     *
     * @param g   The Graphics context to use
     */
    protected void paintBorder(Graphics g)
    {
	Dimension  size;


	size = button.getSize();


	g.setColor(colors[FOCUSED][BORDER]);

	if (shape == button.RECTANGLE)
        {
	    g.drawRect(0,0,size.width-1,size.height-1);
	} 
        else if (shape == button.ROUNDED_RECTANGLE)
        {
	    g.drawRoundRect(0,0,size.width-1,size.height-1,
			    arcWidth,arcHeight);
	}
    }



    /**
     * Paint the text
     *
     * @param g   The Graphics context to use
     */
    protected void paintText(Graphics g)
    {
	Dimension  size;
	int        h, w, x, y;


	size = button.getSize();


	
	// Short circuit if no text
	if ((text == null) || (text.equals(""))) return;
	
	// Determine the size of the text
	if (textSize == null)
        {
	    fm = g.getFontMetrics();
	    h = fm.getMaxAscent();
	    w = fm.stringWidth(text);
	    setTextSize(new Dimension(w, h));
	}
	
	// Determine the horizontal location
	if (horizontalTextPosition == button.LEFT)
        {
	    x = 0;
	} 
        else if (horizontalTextPosition==button.RIGHT)
        {
	    x = size.width - textSize.width;
	} 
        else 
        { 
	    x = (size.width - textSize.width)/2;
	}
	
	// Determine the vertical location
	if (verticalTextPosition == button.TOP) 
        {
	    y = textSize.height;
	} 
        else if (verticalTextPosition==button.BOTTOM) 
        {
	    y=size.height - fm.getMaxDescent();
	} 
        else 
        {
	    y = (size.height + textSize.height)/2;
	}
	
	
	// Modify the text location based on whether the button is UP or DOWN
	if (viewState == DOWN) 
        {
	    x += 1;
	    y -= 1;
	}
	
	
	// Render the text
	g.setFont(button.getFont());

	
	if (!button.isEnabled())  
        {
	    g.setColor(colors[DISABLED][FOREGROUND]);
	} 
        else if (button.hasFocus()) 
        {
	    g.setColor(colors[FOCUSED][FOREGROUND]);
	} 
        else 
        {
	    g.setColor(colors[UNFOCUSED][FOREGROUND]);
	}
	
	g.drawString(text, x, y);
    }
    


    /**
     * Set the color used for different view states
     *
     * @param state   The view state (DOWN or UP)
     * @param color   The Color
     */
    public void setViewStateColor(int state, Color color)
    {
	if (state == DOWN)    downColor = color;
	else if (state == UP) upColor = color;
    }
}

