/*
 * $Id: GlossPainter.java,v 1.2 2008/07/12 11:36:42 dbarashev Exp $
 *
 * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle,
 * Santa Clara, California 95054, U.S.A. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

package org.jdesktop.swingx.painter;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Rectangle;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;

/**
 * <p>A Painter implementation that simulates a gloss effect. The gloss can
 * be positionned at the top or bottom of the drawing area. To fill the gloss,
 * this painter uses a Paint instance which can be used to fill with a color
 * (opaque or translucent), a texture, a gradient...</p>
 * <p>The following example creates a white gloss at the top of the drawing
 * area:</p>
 * <pre>
 *  GlossPainter p = new GlossPainter();
 *  p.setPaint(new Color(1.0f, 1.0f, 1.0f, 0.2f);
 *  p.setPosition(GlossPainter.GlossPosition.TOP);
 *  panel.setBackgroundPainter(p);
 * </pre>
 * <p>The values shown in this examples are the values used by default if
 * they are not specified.</p>
 *
 * @author Romain Guy <romain.guy@mac.com>
 */
public class GlossPainter<T> extends AbstractPainter<T> {
    /**
     * <p>Used to define the position of the gloss on the painted area.</p>
     */
    public enum GlossPosition {
        TOP, BOTTOM
    }
    
    private Paint paint;
    private GlossPosition position;
    
    /**
     * <p>Creates a new gloss painter positionned at the top of the painted
     * area with a 20% translucent white color.</p>
     */
    public GlossPainter() {
        this(new Color(1.0f, 1.0f, 1.0f, 0.2f), GlossPosition.TOP);
    }
    
    /**
     * <p>Creates a new gloss painter positionned at the top of the painted
     * area with the specified paint.</p>
     *
     * @param paint The paint to be used when filling the gloss
     */
    public GlossPainter(Paint paint) {
        this(paint, GlossPosition.TOP);
    }
    
    /**
     * <p>Creates a new gloss painter positionned at the specified position
     * and using a white, 20% translucent paint.</p>
     *
     * @param position The position of the gloss on the painted area
     */
    public GlossPainter(GlossPosition position) {
        this(new Color(1.0f, 1.0f, 1.0f, 0.2f), position);
    }
    
    /**
     * <p>Creates a new gloss painter positionned at the specified position
     * and painted with the specified paint.</p>
     *
     * @param paint The paint to be used when filling the gloss
     * @param position The position of the gloss on the painted area
     */
    public GlossPainter(Paint paint, GlossPosition position) {
        this.setPaint(paint);
        this.setPosition(position);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void doPaint(Graphics2D g, T component, int width, int height) {
        if (getPaint() != null) {
            Ellipse2D ellipse = new Ellipse2D.Double(-width / 2.0,
                height / 2.7, width * 2.0,
                height * 2.0);

            Area gloss = new Area(ellipse);
            if (getPosition() == GlossPosition.TOP) {
                Area area = new Area(new Rectangle(0, 0,
                    width, height));
                area.subtract(new Area(ellipse));
                gloss = area;
            }
            /*
            if(getClip() != null) {
                gloss.intersect(new Area(getClip()));
            }*/
            g.setPaint(getPaint());
            g.fill(gloss);
        }
    }

    /**
     * <p>Returns the paint currently used by the painter to fill the gloss.</p>
     *
     * @return the current Paint instance used by the painter
     */
    public Paint getPaint() {
        return paint;
    }

    /**
     * <p>Changes the paint to be used to fill the gloss. When the specified
     * paint is null, nothing is painted. A paint can be an instance of
     * Color.</p>
     *
     * @param paint The Paint instance to be used to fill the gloss
     */
    public void setPaint(Paint paint) {
        Paint old = this.paint;
        this.paint = paint;
        setDirty(true);
        firePropertyChange("paint", old, getPaint());
    }

    /**
     * <p>Returns the position at which the gloss is painted.</p>
     *
     * @return the position of the gloss in the painted area
     */
    public GlossPosition getPosition() {
        return position;
    }

    /**
     * <p>Changes the position of the gloss in the painted area. Only the
     * values defined in the GlossPosition enum are valid.</p>
     *
     * @param position The position at which the gloss is painted
     */
    public void setPosition(GlossPosition position) {
        GlossPosition old = this.position;
        this.position = position;
        setDirty(true);
        firePropertyChange("position", old, getPosition());
    }
}
