/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw.gui.handle;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Stroke;

import net.sf.jaxodraw.object.JaxoHandle;
import net.sf.jaxodraw.util.JaxoColor;
import net.sf.jaxodraw.util.graphics.JaxoGraphics2D;


/** An abstract class for handles.
 * @since 2.0
 */
public abstract class AbstractJaxoHandle implements JaxoHandle {
    /** The default size of a handle. */
    public static final int DEFAULT_SIZE = 8;

    /** The default stroke for a handle. */
    public static final Stroke DEFAULT_STROKE = new BasicStroke(1.f);

    /** The default color of a handle: JaxoColor.RED. */
    public static final Color DEFAULT_COLOR = JaxoColor.RED;

    /** The default secondary color of a handle: JaxoColor.NAVY_BLUE. */
    public static final Color DEFAULT_SECONDARY_COLOR = JaxoColor.NAVY_BLUE;

    /** The default fill color of a handle: JaxoColor.GRAYSCALE150. */
    public static final Color DEFAULT_FILL_COLOR = JaxoColor.GRAYSCALE150;

    // private fields
    private int size = DEFAULT_SIZE;
    private Stroke stroke = DEFAULT_STROKE;
    private Color color = DEFAULT_COLOR;
    private Color secondaryColor = DEFAULT_SECONDARY_COLOR;
    private Color fillColor = DEFAULT_FILL_COLOR;

    /** Returns the color of this handle.
     * @return The color of this handle.
     */
    public final Color getColor() {
        return color;
    }

    /** Sets the color of this handle.
     * @param c The color of this handle.
     */
    public final void setColor(final Color c) {
        this.color = c;
    }

    /** Returns the fill color of this handle.
     * @return The fill color of this handle.
     */
    public final Color getFillColor() {
        return fillColor;
    }

    /** Sets the fill color of this fhandle.
     * @param c The color to be set as fill color.
     */
    public final void setFillColor(final Color c) {
        this.fillColor = c;
    }

    /** Returns the secondary color of this handle.
     * @return The secondary color of this handle.
     */
    public final Color getSecondaryColor() {
        return secondaryColor;
    }

    /** Sets the secondary color of this handle.
     * @param c The secondary color of this handle.
     */
    public final void setSecondaryColor(final Color c) {
        this.secondaryColor = c;
    }

    /** The handle size. The exact meaning of 'size'
     * has to be defined by the implementation.
     * @return The size of the handle.
     */
    public final int getSize() {
        return size;
    }

    /** Sets the handle size.
     * @param value The new size.
     */
    public void setSize(final int value) {
        this.size = value;
    }

    /** Returns the stroke of this handle.
     * @return The stroke of this handle.
     */
    public final Stroke getStroke() {
        return stroke;
    }

    /** Sets the stroke of this handle.
     * @param newStroke The stroke property of thishandle.
     */
    public final void setStroke(final Stroke newStroke) {
        this.stroke = newStroke;
    }

    /** Paints an unmarked handle at (x, y).
     * @param g2 The graphics context to paint to.
     * @param x The x position of the handle.
     * @param y The y position of the handle.
     */
    public void paint(final JaxoGraphics2D g2, final int x, final int y) {
        paint(g2, x, y, false, color);
    }

    /** Paints a handle at (x, y).
     * @param g2 The graphics context to paint to.
     * @param x The x position of the handle.
     * @param y The y position of the handle.
     * @param marked True if the handle should be marked (selected).
     */
    public void paint(final JaxoGraphics2D g2, final int x, final int y, final boolean marked) {
        paint(g2, x, y, marked, color);
    }

    /** {@inheritDoc} */
    public void paint(final JaxoGraphics2D g2, final int x, final int y, final boolean marked,
        final boolean secondary) {
        if (secondary) {
            paint(g2, x, y, marked, secondaryColor);
        } else {
            paint(g2, x, y, marked, color);
        }
    }

    /** Paints an unmarked handle in secondary color at (x, y).
     * @param g2 The graphics context to paint to.
     * @param x The x position of the handle.
     * @param y The y position of the handle.
     */
    public void paintSecondary(final JaxoGraphics2D g2, final int x, final int y) {
        paint(g2, x, y, false, secondaryColor);
    }

    /** Paints a handle in secondary color at (x, y).
     * @param g2 The graphics context to paint to.
     * @param x The x position of the handle.
     * @param y The y position of the handle.
     * @param marked True if the handle should be marked (selected).
     */
    public void paintSecondary(final JaxoGraphics2D g2, final int x, final int y, final boolean marked) {
        paint(g2, x, y, marked, secondaryColor);
    }

    /** Paints the handle to the given graphics context.
     * @param g2 The graphics context to paint to.
     * @param x The x position of the handle.
     * @param y The y position of the handle.
     * @param marked True if the handle should be marked (selected).
     * @param handleColor The color of the handle.
     */
    public abstract void paint(JaxoGraphics2D g2, int x, int y,
        boolean marked, Color handleColor);

    /**
     * {@inheritDoc}
     *
     * This default implementation returns
     * a square of length {@link #getSize()} around the handle point.
     */
    public Rectangle getBounds(final int x, final int y) {
        return new Rectangle(x - getSize() / 2, y - getSize() / 2,
            x + getSize() / 2 + 1, y + getSize() / 2 + 1);
    }
}
