// Copyright 1996, Marimba Inc. All Rights Reserved.


// @(#)Bevel.java, 1.19, 09/06/96





package marimba.gui;





import java.awt.*;





/**


 * A simple class for drawing bevelled edges. This class caches


 * the darker/lighter colors to avoid consuming heap space.


 *


 * @author	Arthur van Hoff


 * @version 	1.19, 09/06/96


 */


public final class Bevel {


    private static Color current;


    private static Color brighter;


    private static Color darker;





    /**


     * Never instanciated.


     */


    Bevel() {


    }





    /**


     * Get the bright color.


     */


    public static synchronized Color getBrighter(Color col, boolean raised) {


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}


	return raised ? brighter : darker;


    }





    /**


     * Get the darker color.


     */


    public static synchronized Color getDarker(Color col, boolean raised) {


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}


	return raised ? darker : brighter;


    }


    


    /**


     * Paint a 3DRect. The rectangle is drawn inside the specified rectangle.


     * You can specify the line width. It avoids allocating the same hilite


     * colors by keeping a handle on them.


     */


    public static synchronized void drawRect(Graphics g, int x1, int y1, int width, int height, boolean raised, int linewidth) {


	Color col = g.getColor();


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}





	int x2 = x1 + width - 1;


	int y2 = y1 + height - 1;





	g.setColor(raised ? brighter : darker);


	for (int i = 0 ; i < linewidth ; i++) {


	    g.drawLine(x1 + i, y1 + i, x1 + i, y2 - i);


	    g.drawLine(x1 + i, y1 + i, x2 - i, y1 + i);


	}


	g.setColor(raised ? darker : brighter);


	for (int i = 0 ; i < linewidth ; i++) {


	    g.drawLine(x1 + i, y2 - i, x2 - i, y2 - i);


	    g.drawLine(x2 - i, y1 + i, x2 - i, y2 - i);


	}


	g.setColor(col);


    }


    


    /**


     * Fill a 3DRect. The rectangle is drawn inside the specified rectangle.


     * You can specify the line width. It avoids allocating the same hilite


     * colors by keeping a handle on them.


     */


    public static void fillRect(Graphics g, int x1, int y1, int width, int height, boolean raised, int linewidth) {


	fillRect(g, x1, y1, width, height, raised, linewidth, g.getColor());


    }





    /**


     * Fill a 3DRect. The rectangle is drawn inside the specified rectangle.


     * You can specify the line width. It avoids allocating the same hilite


     * colors by keeping a handle on them.


     */


    public static void fillRect(Graphics g, int x1, int y1, int width, int height, boolean raised, int linewidth, Color fill) {


	Color col = g.getColor();


	g.setColor(fill);


	g.fillRect(x1+linewidth, y1+linewidth, width-2*linewidth, height-2*linewidth);


	g.setColor(col);


	drawRect(g, x1, y1, width, height, raised, linewidth);


    }


    


    /**


     * Paint a 3DOval. The oval is drawn inside the specified rectangle.


     * You can specify the line width. It avoids allocating the same hilite


     * colors by keeping a handle on them.


     */


    public static synchronized void drawOval(Graphics g, int x, int y, int width, int height, boolean raised, int linewidth) {


	Color col = g.getColor();


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}





	width--;


	height--;





	g.setColor(raised ? brighter : darker);


	for (int i = 0 ; i < linewidth ; i++) {


	    g.drawArc(x+i, y+i, width-i*2, height-i*2, 45, 180);


	}


	g.setColor(Color.black);


	g.setColor(raised ? darker : brighter);


	for (int i = 0 ; i < linewidth ; i++) {


	    g.drawArc(x+i, y+i, width-i*2, height-i*2, 45, -180);


	}


	g.setColor(col);


    }





    /**


     * Fill a 3DOval. 


     */


    public static void fillOval(Graphics g, int x, int y, int width, int height, boolean raised, int linewidth) {


	fillOval(g, x, y, width, height, raised, linewidth, g.getColor());


    }





    /**


     * Fill a 3DOval. 


     */


    public static void fillOval(Graphics g, int x, int y, int width, int height, boolean raised, int linewidth, Color fill) {


	Color col = g.getColor();


	g.setColor(fill);


	g.fillArc(x, y, width, height, 0, 360);


	g.setColor(col);


	drawOval(g, x, y, width, height, raised, linewidth);


    }


    


    /**


     * Paint a PC-style 3D Border. The rectangle is drawn inside the


     * specified rectangle.


     */


    public static synchronized void drawBorder(Graphics g, int x1, int y1, int width, int height, boolean raised) {


	Color col = g.getColor();


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}


	if (raised) {


	    g.setColor(brighter);


	    g.drawLine(x1, y1, x1 + width-2, y1);


	    g.drawLine(x1, y1, x1, y1 + height-2);


	    g.setColor(Color.black);


	    g.drawLine(x1, y1 + height-1, x1 + width-1, y1 + height-1);


	    g.drawLine(x1 + width-1, y1, x1 + width-1, y1 + height-1);


	    g.setColor(darker);


	    g.drawLine(x1+1, y1 + height-2, x1 + width-2, y1 + height-2);


	    g.drawLine(x1 + width-2, y1+1, x1 + width-2, y1 + height-2);


	} else {


	    g.setColor(Color.black);


	    g.drawLine(x1, y1, x1 + width-2, y1);


	    g.drawLine(x1, y1, x1, y1 + height-2);


	    g.setColor(brighter);


	    g.drawLine(x1, y1 + height-1, x1 + width-1, y1 + height-1);


	    g.drawLine(x1 + width-1, y1, x1 + width-1, y1 + height-1);


	    g.setColor(darker);


	    g.drawLine(x1+1, y1+1, x1 + width-2, y1+1);


	    g.drawLine(x1+1, y1+1, x1+1, y1 + height-2);


	}


	g.setColor(col);


    }





    /**


     * Fill a PC-style 3D Border. The rectangle is drawn inside the


     * specified rectangle.


     */


    public static void fillBorder(Graphics g, int x1, int y1, int width, int height, boolean raised) {


	g.fillRect(x1+1, y1+1, width-2, height-2);


	drawBorder(g, x1, y1, width, height, raised);


    }


    


    /**


     * Paint a PC-style 3D Border. The rectangle is drawn inside the


     * specified rectangle.


     */


    public static synchronized void drawFieldBorder(Graphics g, int x1, int y1, int width, int height) {


	Color col = g.getColor();


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}


	g.setColor(darker);


	g.drawLine(x1, y1, x1 + width-2, y1);


	g.drawLine(x1, y1, x1, y1 + height-2);


	g.setColor(brighter);


	g.drawLine(x1, y1 + height-1, x1 + width-1, y1 + height-1);


	g.drawLine(x1 + width-1, y1, x1 + width-1, y1 + height-1);


	g.setColor(Color.black);


	g.drawLine(x1+1, y1+1, x1 + width-2, y1+1);


	g.drawLine(x1+1, y1+1, x1+1, y1 + height-2);


	g.setColor(col);


	g.drawLine(x1+1, y1 + height-2, x1 + width-2, y1 + height-2);


	g.drawLine(x1 + width-2, y1+1, x1 + width-2, y1 + height-2);


    }





    /**


     * Fill a PC-style 3D Border. The rectangle is drawn inside the


     * specified rectangle.


     */


    public static void fillFieldBorder(Graphics g, int x1, int y1, int width, int height, Color fill) {


	drawFieldBorder(g, x1, y1, width, height);


	Color col = g.getColor();


	g.setColor(fill);


	g.fillRect(x1+2, y1+2, width-4, height-4);


	g.setColor(col);


    }


    


    /**


     * Paint a PC-style 3D Border. The rectangle is drawn inside the


     * specified rectangle.


     */


    public static synchronized void drawWindowBorder(Graphics g, int x1, int y1, int width, int height) {


	Color col = g.getColor();


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}


	g.drawLine(x1, y1, x1 + width-2, y1);


	g.drawLine(x1, y1, x1, y1 + height-2);


	g.setColor(Color.black);


	g.drawLine(x1, y1 + height-1, x1 + width-1, y1 + height-1);


	g.drawLine(x1 + width-1, y1, x1 + width-1, y1 + height-1);


	g.setColor(brighter);


	g.drawLine(x1+1, y1+1, x1 + width-2, y1+1);


	g.drawLine(x1+1, y1+1, x1+1, y1 + height-2);


	g.setColor(darker);


	g.drawLine(x1+1, y1 + height-2, x1 + width-2, y1 + height-2);


	g.drawLine(x1 + width-2, y1+1, x1 + width-2, y1 + height-2);


	g.setColor(col);


    }





    /**


     * Fill a PC-style 3D Border. The rectangle is drawn inside the


     * specified rectangle.


     */


    public static void fillWindowBorder(Graphics g, int x1, int y1, int width, int height, Color fill) {


	drawWindowBorder(g, x1, y1, width, height);


	Color col = g.getColor();


	g.setColor(fill);


	g.fillRect(x1+2, y1+2, width-4, height-4);


	g.setColor(col);


    }


    


    /**


     * Fill a 3DOval. 


     */


    public static synchronized void drawOptionBorder(Graphics g, int x, int y, int width, int height) {


	Color col = g.getColor();


	if (col != current) {


	    current = col;


	    brighter = col.brighter();


	    darker = col.darker();


	}


	g.setColor(darker);


	g.drawArc(x, y, width-1, height-1, 45, 180);


	g.setColor(brighter);


	g.drawArc(x, y, width-1, height-1, 45, -180);


	g.setColor(Color.black);


	g.drawArc(x+1, y+1, width-3, height-3, 45, 180);


	g.setColor(col);


	g.drawArc(x+1, y+1, width-3, height-3, 45, -180);


	g.setColor(col);


    }


    


    /**


     * Fill a 3DOval. 


     */


    public static void fillOptionBorder(Graphics g, int x, int y, int width, int height, Color fill) {


	Color col = g.getColor();


	g.setColor(fill);


	g.fillArc(x+1, y+1, width-3, height-3, 0, 360);


	g.setColor(col);


	drawOptionBorder(g, x, y, width, height);


    }


}


