/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

/*
 * (C) Copyright IBM Corp. 1999-2003, All Rights Reserved
 *
 */

package sun.font;

import java.util.Map;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;

import java.awt.font.TextAttribute;

import java.awt.geom.Area;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;

import static sun.font.AttributeValues.*;
import static sun.font.EAttribute.*;

/**
 * This class handles underlining, strikethrough, and foreground and
 * background styles on text.  Clients simply acquire instances
 * of this class and hand them off to ExtendedTextLabels or GraphicComponents.
 */
public class Decoration {

    /**
     * This interface is implemented by clients that use Decoration.
     * Unfortunately, interface methods have to public;  ideally these
     * would be package-private.
     */
    public interface Label {
        CoreMetrics getCoreMetrics();
        Rectangle2D getLogicalBounds();

        void handleDraw(Graphics2D g2d, float x, float y);
        Rectangle2D handleGetCharVisualBounds(int index);
        Rectangle2D handleGetVisualBounds();
        Shape handleGetOutline(float x, float y);
    }

    private Decoration() {
    }

    /**
     * Return a Decoration which does nothing.
     */
    public static Decoration getPlainDecoration() {

        return PLAIN;
    }

    private static final int VALUES_MASK =
        AttributeValues.getMask(EFOREGROUND, EBACKGROUND, ESWAP_COLORS,
                                ESTRIKETHROUGH, EUNDERLINE, EINPUT_METHOD_HIGHLIGHT,
                                EINPUT_METHOD_UNDERLINE);

    public static Decoration getDecoration(AttributeValues values) {
        if (values == null || !values.anyDefined(VALUES_MASK)) {
            return PLAIN;
        }

        values = values.applyIMHighlight();

        return new DecorationImpl(values.getForeground(),
                                  values.getBackground(),
                                  values.getSwapColors(),
                                  values.getStrikethrough(),
                                  Underline.getUnderline(values.getUnderline()),
                                  Underline.getUnderline(values.getInputMethodUnderline()));
    }

    /**
     * Return a Decoration appropriate for the the given Map.
     * @param attributes the Map used to determine the Decoration
     */
    public static Decoration getDecoration(Map attributes) {
        if (attributes == null) {
            return PLAIN;
        }
        return getDecoration(AttributeValues.fromMap(attributes));
    }

    public void drawTextAndDecorations(Label label,
                                Graphics2D g2d,
                                float x,
                                float y) {

        label.handleDraw(g2d, x, y);
    }

    public Rectangle2D getVisualBounds(Label label) {

        return label.handleGetVisualBounds();
    }

    public Rectangle2D getCharVisualBounds(Label label, int index) {

        return label.handleGetCharVisualBounds(index);
    }

    Shape getOutline(Label label,
                     float x,
                     float y) {

        return label.handleGetOutline(x, y);
    }

    private static final Decoration PLAIN = new Decoration();

    private static final class DecorationImpl extends Decoration {

        private Paint fgPaint = null;
        private Paint bgPaint = null;
        private boolean swapColors = false;
        private boolean strikethrough = false;
        private Underline stdUnderline = null; // underline from TextAttribute.UNDERLINE_ON
        private Underline imUnderline = null; // input method underline

        DecorationImpl(Paint foreground,
                       Paint background,
                       boolean swapColors,
                       boolean strikethrough,
                       Underline stdUnderline,
                       Underline imUnderline) {

            fgPaint = (Paint) foreground;
            bgPaint = (Paint) background;

            this.swapColors = swapColors;
            this.strikethrough = strikethrough;

            this.stdUnderline = stdUnderline;
            this.imUnderline = imUnderline;
        }

        private static boolean areEqual(Object lhs, Object rhs) {

            if (lhs == null) {
                return rhs == null;
            }
            else {
                return lhs.equals(rhs);
            }
        }

        public boolean equals(Object rhs) {

            if (rhs == this) {
                return true;
            }
            if (rhs == null) {
                return false;
            }

            DecorationImpl other = null;
            try {
                other = (DecorationImpl) rhs;
            }
            catch(ClassCastException e) {
                return false;
            }

            if (!(swapColors == other.swapColors &&
                        strikethrough == other.strikethrough)) {
                return false;
            }

            if (!areEqual(stdUnderline, other.stdUnderline)) {
                return false;
            }
            if (!areEqual(fgPaint, other.fgPaint)) {
                return false;
            }
            if (!areEqual(bgPaint, other.bgPaint)) {
                return false;
            }
            return areEqual(imUnderline, other.imUnderline);
        }

        public int hashCode() {

            int hc = 1;
            if (strikethrough) {
                hc |= 2;
            }
            if (swapColors) {
                hc |= 4;
            }
            if (stdUnderline != null) {
                hc += stdUnderline.hashCode();
            }
            return hc;
        }

        /**
        * Return the bottom of the Rectangle which encloses pixels
        * drawn by underlines.
        */
        private float getUnderlineMaxY(CoreMetrics cm) {

            float maxY = 0;
            if (stdUnderline != null) {

                float ulBottom = cm.underlineOffset;
                ulBottom += stdUnderline.getLowerDrawLimit(cm.underlineThickness);
                maxY = Math.max(maxY, ulBottom);
            }

            if (imUnderline != null) {

                float ulBottom = cm.underlineOffset;
                ulBottom += imUnderline.getLowerDrawLimit(cm.underlineThickness);
                maxY = Math.max(maxY, ulBottom);
            }

            return maxY;
        }

        private void drawTextAndEmbellishments(Label label,
                                               Graphics2D g2d,
                                               float x,
                                               float y) {

            label.handleDraw(g2d, x, y);

            if (!strikethrough && stdUnderline == null && imUnderline == null) {
                return;
            }

            float x1 = x;
            float x2 = x1 + (float)label.getLogicalBounds().getWidth();

            CoreMetrics cm = label.getCoreMetrics();
            if (strikethrough) {
                Stroke savedStroke = g2d.getStroke();
                g2d.setStroke(new BasicStroke(cm.strikethroughThickness,
                                              BasicStroke.CAP_BUTT,
                                              BasicStroke.JOIN_MITER));
                float strikeY = y + cm.strikethroughOffset;
                g2d.draw(new Line2D.Float(x1, strikeY, x2, strikeY));
                g2d.setStroke(savedStroke);
            }

            float ulOffset = cm.underlineOffset;
            float ulThickness = cm.underlineThickness;

            if (stdUnderline != null) {
                stdUnderline.drawUnderline(g2d, ulThickness, x1, x2, y + ulOffset);
            }

            if (imUnderline != null) {
                imUnderline.drawUnderline(g2d, ulThickness, x1, x2, y + ulOffset);
            }
        }

        public void drawTextAndDecorations(Label label,
                                    Graphics2D g2d,
                                    float x,
                                    float y) {

            if (fgPaint == null && bgPaint == null && swapColors == false) {
                drawTextAndEmbellishments(label, g2d, x, y);
            }
            else {
                Paint savedPaint = g2d.getPaint();
                Paint foreground, background;

                if (swapColors) {
                    background = fgPaint==null? savedPaint : fgPaint;
                    if (bgPaint == null) {
                        if (background instanceof Color) {
                            Color bg = (Color)background;
                            // 30/59/11 is standard weights, tweaked a bit
                            int brightness = 33 * bg.getRed()
                                + 53 * bg.getGreen()
                                + 14 * bg.getBlue();
                            foreground = brightness > 18500 ? Color.BLACK : Color.WHITE;
                        } else {
                            foreground = Color.WHITE;
                        }
                    } else {
                        foreground = bgPaint;
                    }
                }
                else {
                    foreground = fgPaint==null? savedPaint : fgPaint;
                    background = bgPaint;
                }

                if (background != null) {

                    Rectangle2D bgArea = label.getLogicalBounds();
                    bgArea = new Rectangle2D.Float(x + (float)bgArea.getX(),
                                                y + (float)bgArea.getY(),
                                                (float)bgArea.getWidth(),
                                                (float)bgArea.getHeight());

                    g2d.setPaint(background);
                    g2d.fill(bgArea);
                }

                g2d.setPaint(foreground);
                drawTextAndEmbellishments(label, g2d, x, y);
                g2d.setPaint(savedPaint);
            }
        }

        public Rectangle2D getVisualBounds(Label label) {

            Rectangle2D visBounds = label.handleGetVisualBounds();

            if (swapColors || bgPaint != null || strikethrough
                        || stdUnderline != null || imUnderline != null) {

                float minX = 0;
                Rectangle2D lb = label.getLogicalBounds();

                float minY = 0, maxY = 0;

                if (swapColors || bgPaint != null) {

                    minY = (float)lb.getY();
                    maxY = minY + (float)lb.getHeight();
                }

                maxY = Math.max(maxY, getUnderlineMaxY(label.getCoreMetrics()));

                Rectangle2D ab = new Rectangle2D.Float(minX, minY, (float)lb.getWidth(), maxY-minY);
                visBounds.add(ab);
            }

            return visBounds;
        }

        Shape getOutline(Label label,
                         float x,
                         float y) {

            if (!strikethrough && stdUnderline == null && imUnderline == null) {
                return label.handleGetOutline(x, y);
            }

            CoreMetrics cm = label.getCoreMetrics();

            // NOTE:  The performace of the following code may
            // be very poor.
            float ulThickness = cm.underlineThickness;
            float ulOffset = cm.underlineOffset;

            Rectangle2D lb = label.getLogicalBounds();
            float x1 = x;
            float x2 = x1 + (float)lb.getWidth();

            Area area = null;

            if (stdUnderline != null) {
                Shape ul = stdUnderline.getUnderlineShape(ulThickness,
                                                          x1, x2, y+ulOffset);
                area = new Area(ul);
            }

            if (strikethrough) {
                Stroke stStroke = new BasicStroke(cm.strikethroughThickness,
                                                  BasicStroke.CAP_BUTT,
                                                  BasicStroke.JOIN_MITER);
                float shiftY = y + cm.strikethroughOffset;
                Line2D line = new Line2D.Float(x1, shiftY, x2, shiftY);
                Area slArea = new Area(stStroke.createStrokedShape(line));
                if(area == null) {
                    area = slArea;
                } else {
                    area.add(slArea);
                }
            }

            if (imUnderline != null) {
                Shape ul = imUnderline.getUnderlineShape(ulThickness,
                                                         x1, x2, y+ulOffset);
                Area ulArea = new Area(ul);
                if (area == null) {
                    area = ulArea;
                }
                else {
                    area.add(ulArea);
                }
            }

            // area won't be null here, since at least one underline exists.
            area.add(new Area(label.handleGetOutline(x, y)));

            return new GeneralPath(area);
        }


        public String toString() {
            StringBuffer buf = new StringBuffer();
            buf.append(super.toString());
            buf.append("[");
            if (fgPaint != null) buf.append("fgPaint: " + fgPaint);
            if (bgPaint != null) buf.append(" bgPaint: " + bgPaint);
            if (swapColors) buf.append(" swapColors: true");
            if (strikethrough) buf.append(" strikethrough: true");
            if (stdUnderline != null) buf.append(" stdUnderline: " + stdUnderline);
            if (imUnderline != null) buf.append(" imUnderline: " + imUnderline);
            buf.append("]");
            return buf.toString();
        }
    }
}
