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


// @(#)LineWidget.java, 1.1, 10/01/96





package marimba.gui;





import java.awt.*;





import marimba.persist.*;





/**


 * A simple line widget.


 *


 * @author	Klaas Waslander


 * @version 	1.1, 10/01/96


 */


public class LineWidget extends ShapeWidget {


    /**


     * A line can have a horizontal, vertical or diagonal orientation.


     * @see #getOrientation


     * @see #setOrientation


     * @see #orientationOptions


     */


    public int  orientation = HORIZONTAL;





    /**


     * The possible options for the orientation.


     * @see #getOrientationOptions


     */


    public static Options  orientationOptions = new Options();


    static {


	orientationOptions.add("horizontal", HORIZONTAL);


	orientationOptions.add("vertical", VERTICAL);


	orientationOptions.add("diagonal", DIAGONAL);


    }





    /**


     * When a line is diagonal, it can go up or down.


     * @see #getDiagonal


     * @see #setDiagonal


     * @see #diagonalOptions


     */


    public int  diagonal = DOWN;





    /**


     * The possible options when a line is diagonal.


     * @see #getDiagonalOptions


     */


    public static Options  diagonalOptions = new Options();


    static {


	diagonalOptions.add("down", DOWN);


	diagonalOptions.add("up", UP);


    }





    /**


     * The linewidth in pixels.


     * @see #getLineWidth


     * @see #setLineWidth


     */


    public int lineWidth = 3;





    /**


     * The line can be displayed in a 3D-style


     * @see #is3D


     * @see #set3D


     */


    public boolean threeD = true;








    /**


     * Constructor.


     */


    public LineWidget() {


	filled = false;


    }





    /**


     * Get the properties of this widget.


     */


    public void getProperties(PropertyList list) {


	super.getProperties(list);


	list.setOption("orientation", orientationOptions, orientation, HORIZONTAL);


	list.setOption("diagonal", diagonalOptions, diagonal, DOWN);


	list.setInteger("linewidth", lineWidth, 1);


	list.setBoolean("3D", threeD, true);


    }





    /**


     * Set the properties.


     */


    public void setProperties(PropertyList list) {


	super.setProperties(list);


	orientation = list.getOption("orientation", orientationOptions, HORIZONTAL);


	diagonal = list.getOption("diagonal", diagonalOptions, DOWN);


	lineWidth = list.getInteger("linewidth", 1);


	threeD = list.getBoolean("3D", true);


    }





    /**


     * Get the possible options for the orientation.


     * @see #orientationOptions


     */


    public Options getOrientationOptions() {


	return orientationOptions;


    }





    /**


     * Get the current orientation.


     * @see #orientation


     */


    public int getOrientation() {


	return orientation;


    }





    /**


     * Set the orientation to horizontal, vertical or diagonal.


     * @see #orientation


     */


    public void setOrientation(int orientation) {


	if (orientation!= this.orientation) {


	    if (orientation==HORIZONTAL || orientation==VERTICAL || orientation == DIAGONAL) {


		this.orientation = orientation;


		repaint();


	    }


	}


    }





    /**


     * Get the possible options when a line is diagonal.


     * @see #diagonalOptions


     */


    public Options getDiagonalOptions() {


	return diagonalOptions;


    }





    /**


     * Get the direction when the line is diagonal, up or down.


     * @see #diagonal


     */


    public int getDiagonal() {


	return diagonal;


    }





    /**


     * Set the direction to up or down when the line is diagonal.


     * @see #diagonal


     */


    public void setDiagonal(int diagonal) {


	if (this.diagonal != diagonal) {


	    if (diagonal == UP || diagonal == DOWN) {


		this.diagonal = diagonal;


		if (orientation == DIAGONAL) {


		    repaint();


		}


	    }


	}


    }





    /**


     * Get the linewidth.


     * @see #lineWidth


     */


    public int getLineWidth() {


	return lineWidth;


    }





    /**


     * Set the linewidth to the given number of pixels.


     * @see #lineWidth


     */


    public void setLineWidth(int lineWidth) {


	if (this.lineWidth != lineWidth) {


	    this.lineWidth = Math.max(1, lineWidth);


	    repaint();


	}


    }





    /**


     * Check whether the line is three-dimensional.


     * @see #threeD


     */


    public boolean is3D() {


	return threeD;


    }





    /**


     * Toggle the 3D mode.


     */


    public void set3D(boolean threeD) {


	if (this.threeD != threeD) {


	    this.threeD = threeD;


	    repaint();


	}


    }





    /**


     * Paint the line.


     */


    public void paint(Graphics g) {


	if (!line) {


	    return;


	}





	int  x1 = 0, y1 = 0, x2 = 0, y2 = 0, x3 = 0, y3 = 0, x4 = 0, y4 = 0;


	switch(orientation) {


	    case VERTICAL:


		y1 = 0 - lineWidth;


		y2 = height + lineWidth;


		x1 = x2 = width / 2;


		break;





	    case DIAGONAL:


		int  cosinus = (int) (Math.cos(45)*lineWidth);


		if (diagonal == UP) {


		    x1 = 0;


		    x2 = cosinus;


		    x3 = width;


		    x4 = width - cosinus;


		    y1 = height - cosinus;


		    y2 = height;


		    y3 = cosinus;


		    y4 = 0;


		} else {


		    x1 = cosinus;


		    x2 = 0;


		    x3 = width - cosinus;


		    x4 = width;


		    y1 = 0;


		    y2 = cosinus;


		    y3 = height;


		    y4 = height - cosinus;


		}


		break;





	    default:


		x1 = 0 - lineWidth;


		x2 = width + lineWidth;


		y1 = y2 = height / 2;


		break;


	}





	g.setColor(foreground);


	if (!threeD) {


	    if (!(orientation == DIAGONAL)) {


		int  skip = 0;


		for (int index = 0; index < lineWidth; index++) {


		    if (index % 2 == 0) {


			g.drawLine(x1+skip, y1+skip, x2+skip, y2+skip);


			skip++;


		    } else {


			g.drawLine(x1-skip, y1-skip, x2-skip, y2-skip);


		    }


		}


	    } else {


		Polygon  pol = new Polygon();


		pol.addPoint(x1, y1);


		pol.addPoint(x2, y2);


		pol.addPoint(x3, y3);


		pol.addPoint(x4, y4);


		pol.addPoint(x1, y1);


		g.fillPolygon(pol);


	    }


	} else {


	    if (!(orientation == DIAGONAL)) {


		int  half = lineWidth/2;


		if (orientation == HORIZONTAL) {


		    g.setColor(background.darker().darker());


		    g.drawLine(0, y1-half, width-1, y2-half);


		    g.drawLine(0, y1-half, 0, y2+half);


		    g.setColor(background.brighter());


		    g.drawLine(0, y1+half, width-1, y2+half);


		    g.drawLine(width-1, y2+half, width-1, y2-half);


		    if (filled) {


			g.setColor(hilite);


			g.fillRect(1, y1-half+1, width-2, lineWidth - ((lineWidth%2==0)?1:2));


		    }


		} else {


		    g.setColor(background.darker().darker());


		    g.drawLine(x1-half, 0, x2-half, height-1);


		    g.drawLine(x1-half, 0, x1+half, 0);


		    g.setColor(background.brighter());


		    g.drawLine(x1+half, 0, x2+half, height-1);


		    g.drawLine(x2+half, height-1, x2-half, height-1);


		    if (filled) {


			g.setColor(hilite);


			g.fillRect(x1-half+1, 1, lineWidth - ((lineWidth%2==0)?1:2), height-2);


		    }


		}


	    } else {


		g.setColor(background.darker().darker());


		g.drawLine(x1, y1, x2, y2);


		g.drawLine(x1, y1, x4, y4);


		g.setColor(background.brighter());


		g.drawLine(x2, y2, x3, y3);


		g.drawLine(x3, y3, x4, y4);


		if (filled) {


		    g.setColor(hilite);


		    if (diagonal == UP) {


			x1 += 1;


			y2 -= 1;


			x3 -= 1;


			y4 += 1;


		    } else {


			y1 += 1;


			x2 += 1;


			y3 -= 1;


			x4 -= 1;


		    }


		    Polygon  pol = new Polygon();


		    pol.addPoint(x1, y1);


		    pol.addPoint(x2, y2);


		    pol.addPoint(x3, y3);


		    pol.addPoint(x4, y4);


		    pol.addPoint(x1, y1);


		    g.fillPolygon(pol);


		}


	    }


	}


    }   


}


