/*
 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
 * 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.
 */

package com.sun.java.swing.plaf.motif;

import sun.swing.SwingUtilities2;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;

/**
 * Factory object that can vend Icons appropriate for the basic L & F.
 * <p>
 * <strong>Warning:</strong>
 * Serialized objects of this class will not be compatible with
 * future Swing releases.  The current serialization support is appropriate
 * for short term storage or RMI between applications running the same
 * version of Swing.  A future release of Swing will provide support for
 * long term persistence.
 *
 * @author Amy Fowler
 */
public class MotifBorders {

    public static class BevelBorder extends AbstractBorder implements UIResource {
        private Color darkShadow = UIManager.getColor("controlShadow");
        private Color lightShadow = UIManager.getColor("controlLtHighlight");
        private boolean isRaised;

        public BevelBorder(boolean isRaised, Color darkShadow, Color lightShadow) {
            this.isRaised = isRaised;
            this.darkShadow = darkShadow;
            this.lightShadow = lightShadow;
        }

        public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
            g.setColor((isRaised) ? lightShadow : darkShadow);
            g.drawLine(x, y, x+w-1, y);           // top
            g.drawLine(x, y+h-1, x, y+1);         // left

            g.setColor((isRaised) ? darkShadow : lightShadow);
            g.drawLine(x+1, y+h-1, x+w-1, y+h-1); // bottom
            g.drawLine(x+w-1, y+h-1, x+w-1, y+1); // right
        }

        public Insets getBorderInsets(Component c, Insets insets) {
            insets.set(1, 1, 1, 1);
            return insets;
        }

        public boolean isOpaque(Component c) {
            return true;
        }

    }


    public static class FocusBorder extends AbstractBorder implements UIResource {
        private Color focus;
        private Color control;

        public FocusBorder(Color control, Color focus) {
            this.control = control;
            this.focus = focus;
        }

        public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
            if (c.hasFocus()) {
                g.setColor(focus);
                g.drawRect(x, y, w-1, h-1);
            } else {
                g.setColor(control);
                g.drawRect(x, y, w-1, h-1);
            }
        }

        public Insets getBorderInsets(Component c, Insets insets) {
            insets.set(1, 1, 1, 1);
            return insets;
        }
    }


    public static class ButtonBorder extends AbstractBorder implements UIResource {
        protected Color focus = UIManager.getColor("activeCaptionBorder");
        protected Color shadow = UIManager.getColor("Button.shadow");
        protected Color highlight = UIManager.getColor("Button.light");
        protected Color darkShadow;

        public ButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
            this.shadow = shadow;
            this.highlight = highlight;
            this.darkShadow = darkShadow;
            this.focus = focus;
        }

        public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
            boolean isPressed = false;
            boolean hasFocus = false;
            boolean canBeDefault = false;
            boolean isDefault = false;

            if (c instanceof AbstractButton) {
                AbstractButton b = (AbstractButton)c;
                ButtonModel model = b.getModel();

                isPressed = (model.isArmed() && model.isPressed());
                hasFocus = (model.isArmed() && isPressed) ||
                           (b.isFocusPainted() && b.hasFocus());
                if (b instanceof JButton) {
                    canBeDefault = ((JButton)b).isDefaultCapable();
                    isDefault = ((JButton)b).isDefaultButton();
                }
            }
            int bx1 = x+1;
            int by1 = y+1;
            int bx2 = x+w-2;
            int by2 = y+h-2;

            if (canBeDefault) {
                if (isDefault) {
                    g.setColor(shadow);
                    g.drawLine(x+3, y+3, x+3, y+h-4);
                    g.drawLine(x+3, y+3, x+w-4, y+3);

                    g.setColor(highlight);
                    g.drawLine(x+4, y+h-4, x+w-4, y+h-4);
                    g.drawLine(x+w-4, y+3, x+w-4, y+h-4);
                }
                bx1 +=6;
                by1 += 6;
                bx2 -= 6;
                by2 -= 6;
            }

            if (hasFocus) {
                g.setColor(focus);
                if (isDefault) {
                    g.drawRect(x, y, w-1, h-1);
                } else {
                    g.drawRect(bx1-1, by1-1, bx2-bx1+2, by2-by1+2);
                }
            }

            g.setColor(isPressed? shadow : highlight);
            g.drawLine(bx1, by1, bx2, by1);
            g.drawLine(bx1, by1, bx1, by2);

            g.setColor(isPressed? highlight : shadow);
            g.drawLine(bx2, by1+1, bx2, by2);
            g.drawLine(bx1+1, by2, bx2, by2);
        }

        public Insets getBorderInsets(Component c, Insets insets) {
            int thickness = (c instanceof JButton && ((JButton)c).isDefaultCapable())? 8 : 2;
            insets.set(thickness, thickness, thickness, thickness);
            return insets;
        }

    }

    public static class ToggleButtonBorder extends ButtonBorder {

        public ToggleButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
             super(shadow, highlight, darkShadow, focus);
        }

        public void paintBorder(Component c, Graphics g, int x, int y,
                            int width, int height) {
            if (c instanceof AbstractButton) {
                AbstractButton b = (AbstractButton)c;
                ButtonModel model = b.getModel();

                if (model.isArmed() && model.isPressed() || model.isSelected()) {
                    drawBezel(g, x, y, width, height,
                              (model.isPressed() || model.isSelected()),
                              b.isFocusPainted() && b.hasFocus(), shadow, highlight, darkShadow, focus);
                } else {
                    drawBezel(g, x, y, width, height,
                              false, b.isFocusPainted() && b.hasFocus(),
                              shadow, highlight, darkShadow, focus);
                }
            } else {
                drawBezel(g, x, y, width, height, false, false,
                          shadow, highlight, darkShadow, focus);
            }
        }

        public Insets getBorderInsets(Component c, Insets insets) {
            insets.set(2, 2, 3, 3);
            return insets;
        }
    }

    public static class MenuBarBorder extends ButtonBorder {

        public MenuBarBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
            super(shadow, highlight, darkShadow, focus);
        }

        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            if (!(c instanceof JMenuBar)) {
                return;
            }
            JMenuBar menuBar = (JMenuBar)c;
            if (menuBar.isBorderPainted() == true) {
                // this draws the MenuBar border
                Dimension size = menuBar.getSize();
                drawBezel(g,x,y,size.width,size.height,false,false,
                          shadow, highlight, darkShadow, focus);
            }
        }

        public Insets getBorderInsets(Component c, Insets insets) {
            insets.set(6, 6, 6, 6);
            return insets;
        }
    }

    public static class FrameBorder extends AbstractBorder implements UIResource {

        JComponent jcomp;
        Color frameHighlight;
        Color frameColor;
        Color frameShadow;

        // The width of the border
        public final static int BORDER_SIZE = 5;

        /** Constructs an FrameBorder for the JComponent <b>comp</b>.
        */
        public FrameBorder(JComponent comp) {
            jcomp = comp;
        }

        /** Sets the FrameBorder's JComponent.
      */
        public void setComponent(JComponent comp) {
            jcomp = comp;
        }

        /** Returns the FrameBorder's JComponent.
          * @see #setComponent
          */
        public JComponent component() {
            return jcomp;
        }

        protected Color getFrameHighlight() {
            return frameHighlight;
        }

        protected Color getFrameColor() {
            return frameColor;
        }

        protected Color getFrameShadow() {
            return frameShadow;
        }

        public Insets getBorderInsets(Component c, Insets newInsets) {
            newInsets.set(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE);
            return newInsets;
        }

       /** Draws the FrameBorder's top border.
         */
        protected boolean drawTopBorder(Component c, Graphics g,
                                    int x, int y, int width, int height) {
            Rectangle titleBarRect = new Rectangle(x, y, width, BORDER_SIZE);
            if (!g.getClipBounds().intersects(titleBarRect)) {
                return false;
            }

            int maxX = width - 1;
            int maxY = BORDER_SIZE - 1;

            // Draw frame
            g.setColor(frameColor);
            g.drawLine(x, y + 2, maxX - 2, y + 2);
            g.drawLine(x, y + 3, maxX - 2, y + 3);
            g.drawLine(x, y + 4, maxX - 2, y + 4);

            // Draw highlights
            g.setColor(frameHighlight);
            g.drawLine(x, y, maxX, y);
            g.drawLine(x, y + 1, maxX, y + 1);
            g.drawLine(x, y + 2, x, y + 4);
            g.drawLine(x + 1, y + 2, x + 1, y + 4);

            // Draw shadows
            g.setColor(frameShadow);
            g.drawLine(x + 4, y + 4, maxX - 4, y + 4);
            g.drawLine(maxX, y + 1, maxX, maxY);
            g.drawLine(maxX - 1, y + 2, maxX - 1, maxY);

            return true;
        }

        /** Draws the FrameBorder's left border.
          */
        protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
                               int width, int height) {
            Rectangle borderRect =
                new Rectangle(0, 0, getBorderInsets(c).left, height);
            if (!g.getClipBounds().intersects(borderRect)) {
                return false;
            }

            int startY = BORDER_SIZE;

            g.setColor(frameHighlight);
            g.drawLine(x, startY, x, height - 1);
            g.drawLine(x + 1, startY, x + 1, height - 2);

            g.setColor(frameColor);
            g.fillRect(x + 2, startY, x + 2, height - 3);

            g.setColor(frameShadow);
            g.drawLine(x + 4, startY, x + 4, height - 5);

            return true;
        }

        /** Draws the FrameBorder's right border.
          */
        protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
                                int width, int height) {
            Rectangle borderRect = new Rectangle(
                width - getBorderInsets(c).right, 0,
                getBorderInsets(c).right, height);
            if (!g.getClipBounds().intersects(borderRect)) {
                return false;
            }

            int startX = width - getBorderInsets(c).right;
            int startY = BORDER_SIZE;

            g.setColor(frameColor);
            g.fillRect(startX + 1, startY, 2, height - 1);

            g.setColor(frameShadow);
            g.fillRect(startX + 3, startY, 2, height - 1);

            g.setColor(frameHighlight);
            g.drawLine(startX, startY, startX, height - 1);

            return true;
        }

        /** Draws the FrameBorder's bottom border.
          */
        protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
                                 int width, int height) {
            Rectangle    borderRect;
            int     marginHeight, startY;

            borderRect = new Rectangle(0, height - getBorderInsets(c).bottom,
                                  width, getBorderInsets(c).bottom);
            if (!g.getClipBounds().intersects(borderRect)) {
                return false;
            }

            startY = height - getBorderInsets(c).bottom;

            g.setColor(frameShadow);
            g.drawLine(x + 1, height - 1, width - 1, height - 1);
            g.drawLine(x + 2, height - 2, width - 2, height - 2);

            g.setColor(frameColor);
            g.fillRect(x + 2, startY + 1, width - 4, 2);

            g.setColor(frameHighlight);
            g.drawLine(x + 5, startY, width - 5, startY);

            return true;
        }

        // Returns true if the associated component has focus.
        protected boolean isActiveFrame() {
            return jcomp.hasFocus();
        }

        /** Draws the FrameBorder in the given Rect.  Calls
          * <b>drawTitleBar</b>, <b>drawLeftBorder</b>, <b>drawRightBorder</b> and
          * <b>drawBottomBorder</b>.
          */
        public void paintBorder(Component c, Graphics g,
                            int x, int y, int width, int height) {
            if (isActiveFrame()) {
                frameColor = UIManager.getColor("activeCaptionBorder");
            } else {
                frameColor = UIManager.getColor("inactiveCaptionBorder");
            }
            frameHighlight = frameColor.brighter();
            frameShadow = frameColor.darker().darker();

            drawTopBorder(c, g, x, y, width, height);
            drawLeftBorder(c, g, x, y, width, height);
            drawRightBorder(c, g, x, y, width, height);
            drawBottomBorder(c, g, x, y, width, height);
        }
    }

    public static class InternalFrameBorder extends FrameBorder {

        JInternalFrame frame;

        // The size of the bounding box for Motif frame corners.
        public final static int CORNER_SIZE = 24;

        /** Constructs an InternalFrameBorder for the InternalFrame
          * <b>aFrame</b>.
          */
        public InternalFrameBorder(JInternalFrame aFrame) {
            super(aFrame);
            frame = aFrame;
        }

        /** Sets the InternalFrameBorder's InternalFrame.
          */
        public void setFrame(JInternalFrame aFrame) {
            frame = aFrame;
        }

        /** Returns the InternalFrameBorder's InternalFrame.
          * @see #setFrame
          */
        public JInternalFrame frame() {
            return frame;
        }

        /** Returns the width of the InternalFrameBorder's resize controls,
          * appearing along the InternalFrameBorder's bottom border.  Clicking
          * and dragging within these controls lets the user change both the
          * InternalFrame's width and height, while dragging between the controls
          * constrains resizing to just the vertical dimension.  Override this
          * method if you implement your own bottom border painting and use a
          * resize control with a different size.
          */
        public int resizePartWidth() {
            if (!frame.isResizable()) {
                return 0;
            }
            return FrameBorder.BORDER_SIZE;
        }

        /** Draws the InternalFrameBorder's top border.
         */
        protected boolean drawTopBorder(Component c, Graphics g,
                                    int x, int y, int width, int height) {
            if (super.drawTopBorder(c, g, x, y, width, height) &&
                frame.isResizable()) {
                g.setColor(getFrameShadow());
                g.drawLine(CORNER_SIZE - 1, y + 1, CORNER_SIZE - 1, y + 4);
                g.drawLine(width - CORNER_SIZE - 1, y + 1,
                       width - CORNER_SIZE - 1, y + 4);

                g.setColor(getFrameHighlight());
                g.drawLine(CORNER_SIZE, y, CORNER_SIZE, y + 4);
                g.drawLine(width - CORNER_SIZE, y, width - CORNER_SIZE, y + 4);
                return true;
            }
            return false;
        }

        /** Draws the InternalFrameBorder's left border.
          */
        protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
                                     int width, int height) {
            if (super.drawLeftBorder(c, g, x, y, width, height) &&
                frame.isResizable()) {
                g.setColor(getFrameHighlight());
                int topY = y + CORNER_SIZE;
                g.drawLine(x, topY, x + 4, topY);
                int bottomY = height - CORNER_SIZE;
                g.drawLine(x + 1, bottomY, x + 5, bottomY);
                g.setColor(getFrameShadow());
                g.drawLine(x + 1, topY - 1, x + 5, topY - 1);
                g.drawLine(x + 1, bottomY - 1, x + 5, bottomY - 1);
                return true;
            }
            return false;
        }

        /** Draws the InternalFrameBorder's right border.
          */
        protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
                                      int width, int height) {
            if (super.drawRightBorder(c, g, x, y, width, height) &&
                frame.isResizable()) {
                int startX = width - getBorderInsets(c).right;
                g.setColor(getFrameHighlight());
                int topY = y + CORNER_SIZE;
                g.drawLine(startX, topY, width - 2, topY);
                int bottomY = height - CORNER_SIZE;
                g.drawLine(startX + 1, bottomY, startX + 3, bottomY);
                g.setColor(getFrameShadow());
                g.drawLine(startX + 1, topY - 1, width - 2, topY - 1);
                g.drawLine(startX + 1, bottomY - 1, startX + 3, bottomY - 1);
                return true;
            }
            return false;
        }

        /** Draws the InternalFrameBorder's bottom border.
          */
        protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
                                       int width, int height) {
            if (super.drawBottomBorder(c, g, x, y, width, height) &&
                frame.isResizable()) {
                int startY = height - getBorderInsets(c).bottom;

                g.setColor(getFrameShadow());
                g.drawLine(CORNER_SIZE - 1, startY + 1,
                       CORNER_SIZE - 1, height - 1);
                g.drawLine(width - CORNER_SIZE, startY + 1,
                       width - CORNER_SIZE, height - 1);

                g.setColor(getFrameHighlight());
                g.drawLine(CORNER_SIZE, startY, CORNER_SIZE, height - 2);
                g.drawLine(width - CORNER_SIZE + 1, startY,
                       width - CORNER_SIZE + 1, height - 2);
                return true;
            }
            return false;
        }

        // Returns true if the associated internal frame has focus.
        protected boolean isActiveFrame() {
            return frame.isSelected();
        }
    }

    public static void drawBezel(Graphics g, int x, int y, int w, int h,
                               boolean isPressed, boolean hasFocus,
                               Color shadow, Color highlight,
                               Color darkShadow, Color focus)  {

        Color oldColor = g.getColor();
        g.translate(x, y);

        if (isPressed) {
            if (hasFocus){
                g.setColor(focus);
                g.drawRect(0, 0, w-1, h-1);
            }
            g.setColor(shadow);         // inner border
            g.drawRect(1, 1, w-3, h-3);

            g.setColor(highlight);    // inner 3D border
            g.drawLine(2, h-3, w-3, h-3);
            g.drawLine(w-3, 2, w-3, h-4);

        } else {
            if (hasFocus) {
                g.setColor(focus);
                g.drawRect(0, 0, w-1, h-1);

                g.setColor(highlight);   // inner 3D border
                g.drawLine(1, 1, 1, h-3);
                g.drawLine(2, 1, w-4, 1);

                g.setColor(shadow);
                g.drawLine(2, h-3, w-3, h-3);
                g.drawLine(w-3, 1, w-3, h-4);

                g.setColor(darkShadow);        // black drop shadow  __|
                g.drawLine(1, h-2, w-2, h-2);
                g.drawLine(w-2, h-2, w-2, 1);
            } else {
                g.setColor(highlight);    // inner 3D border
                g.drawLine(1,1,1,h-3);
                g.drawLine(2,1,w-4,1);
                g.setColor(shadow);
                g.drawLine(2,h-3,w-3,h-3);
                g.drawLine(w-3,1,w-3,h-4);

                g.setColor(darkShadow);         // black drop shadow  __|
                g.drawLine(1,h-2,w-2,h-2);
                g.drawLine(w-2,h-2,w-2,0);

            }
            g.translate(-x, -y);
        }
        g.setColor(oldColor);
    }

    public static class MotifPopupMenuBorder extends AbstractBorder implements UIResource {
        protected Font   font;
        protected Color  background;
        protected Color  foreground;
        protected Color  shadowColor;
        protected Color  highlightColor;

        // Space between the border and text
        static protected final int TEXT_SPACING = 2;

        // Space for the separator under the title
        static protected final int GROOVE_HEIGHT = 2;

        /**
         * Creates a MotifPopupMenuBorder instance
         *
         */
        public MotifPopupMenuBorder(
                                    Font titleFont,
                                    Color bgColor,
                                    Color fgColor,
                                    Color shadow,
                                    Color highlight)       {
            this.font = titleFont;
            this.background = bgColor;
            this.foreground = fgColor;
            this.shadowColor = shadow;
            this.highlightColor = highlight;
        }

        /**
         * Paints the border for the specified component with the
         * specified position and size.
         * @param c the component for which this border is being painted
         * @param g the paint graphics
         * @param x the x position of the painted border
         * @param y the y position of the painted border
         * @param width the width of the painted border
         * @param height the height of the painted border
         */
        public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
            if (!(c instanceof JPopupMenu)) {
                return;
            }

            Font origFont = g.getFont();
            Color origColor = g.getColor();
            JPopupMenu popup = (JPopupMenu)c;

            String title = popup.getLabel();
            if (title == null) {
                return;
            }

            g.setFont(font);

            FontMetrics fm = SwingUtilities2.getFontMetrics(popup, g, font);
            int         fontHeight = fm.getHeight();
            int         descent = fm.getDescent();
            int         ascent = fm.getAscent();
            Point       textLoc = new Point();
            int         stringWidth = SwingUtilities2.stringWidth(popup, fm,
                                                                  title);

            textLoc.y = y + ascent + TEXT_SPACING;
            textLoc.x = x + ((width - stringWidth) / 2);

            g.setColor(background);
            g.fillRect(textLoc.x - TEXT_SPACING, textLoc.y - (fontHeight-descent),
                       stringWidth + (2 * TEXT_SPACING), fontHeight - descent);
            g.setColor(foreground);
            SwingUtilities2.drawString(popup, g, title, textLoc.x, textLoc.y);

            MotifGraphicsUtils.drawGroove(g, x, textLoc.y + TEXT_SPACING,
                                          width, GROOVE_HEIGHT,
                                          shadowColor, highlightColor);

            g.setFont(origFont);
            g.setColor(origColor);
        }

        /**
         * Reinitialize the insets parameter with this Border's current Insets.
         * @param c the component for which this border insets value applies
         * @param insets the object to be reinitialized
         */
        public Insets getBorderInsets(Component c, Insets insets) {
            if (!(c instanceof JPopupMenu)) {
                return insets;
            }
            FontMetrics fm;
            int         descent = 0;
            int         ascent = 16;

            String title = ((JPopupMenu)c).getLabel();
            if (title == null) {
                insets.left = insets.top = insets.right = insets.bottom = 0;
                return insets;
            }

            fm = c.getFontMetrics(font);

            if(fm != null) {
                descent = fm.getDescent();
                ascent = fm.getAscent();
            }

            insets.top += ascent + descent + TEXT_SPACING + GROOVE_HEIGHT;
            return insets;
        }

    }

}
