/*
 * Copyright (c) 1998, 2008, 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 javax.swing.plaf.metal;

import sun.swing.SwingUtilities2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.InternalFrameEvent;
import java.util.EventListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import javax.swing.plaf.basic.BasicInternalFrameTitlePane;


/**
 * Class that manages a JLF title bar
 * @author Steve Wilson
 * @author Brian Beck
 * @since 1.3
 */

public class MetalInternalFrameTitlePane  extends BasicInternalFrameTitlePane {

    protected boolean isPalette = false;
    protected Icon paletteCloseIcon;
    protected int paletteTitleHeight;

    private static final Border handyEmptyBorder = new EmptyBorder(0,0,0,0);

    /**
     * Key used to lookup Color from UIManager. If this is null,
     * <code>getWindowTitleBackground</code> is used.
     */
    private String selectedBackgroundKey;
    /**
     * Key used to lookup Color from UIManager. If this is null,
     * <code>getWindowTitleForeground</code> is used.
     */
    private String selectedForegroundKey;
    /**
     * Key used to lookup shadow color from UIManager. If this is null,
     * <code>getPrimaryControlDarkShadow</code> is used.
     */
    private String selectedShadowKey;
    /**
     * Boolean indicating the state of the <code>JInternalFrame</code>s
     * closable property at <code>updateUI</code> time.
     */
    private boolean wasClosable;

    int buttonsWidth = 0;

    MetalBumps activeBumps
        = new MetalBumps( 0, 0,
                          MetalLookAndFeel.getPrimaryControlHighlight(),
                          MetalLookAndFeel.getPrimaryControlDarkShadow(),
          (UIManager.get("InternalFrame.activeTitleGradient") != null) ? null :
                          MetalLookAndFeel.getPrimaryControl() );
    MetalBumps inactiveBumps
        = new MetalBumps( 0, 0,
                          MetalLookAndFeel.getControlHighlight(),
                          MetalLookAndFeel.getControlDarkShadow(),
        (UIManager.get("InternalFrame.inactiveTitleGradient") != null) ? null :
                          MetalLookAndFeel.getControl() );
    MetalBumps paletteBumps;

    private Color activeBumpsHighlight = MetalLookAndFeel.
                             getPrimaryControlHighlight();
    private Color activeBumpsShadow = MetalLookAndFeel.
                             getPrimaryControlDarkShadow();

    public MetalInternalFrameTitlePane(JInternalFrame f) {
        super( f );
    }

    public void addNotify() {
        super.addNotify();
        // This is done here instead of in installDefaults as I was worried
        // that the BasicInternalFrameUI might not be fully initialized, and
        // that if this resets the closable state the BasicInternalFrameUI
        // Listeners that get notified might be in an odd/uninitialized state.
        updateOptionPaneState();
    }

    protected void installDefaults() {
        super.installDefaults();
        setFont( UIManager.getFont("InternalFrame.titleFont") );
        paletteTitleHeight
            = UIManager.getInt("InternalFrame.paletteTitleHeight");
        paletteCloseIcon = UIManager.getIcon("InternalFrame.paletteCloseIcon");
        wasClosable = frame.isClosable();
        selectedForegroundKey = selectedBackgroundKey = null;
        if (MetalLookAndFeel.usingOcean()) {
            setOpaque(true);
        }
    }

    protected void uninstallDefaults() {
        super.uninstallDefaults();
        if (wasClosable != frame.isClosable()) {
            frame.setClosable(wasClosable);
        }
    }

    protected void createButtons() {
        super.createButtons();

        Boolean paintActive = frame.isSelected() ? Boolean.TRUE:Boolean.FALSE;
        iconButton.putClientProperty("paintActive", paintActive);
        iconButton.setBorder(handyEmptyBorder);

        maxButton.putClientProperty("paintActive", paintActive);
        maxButton.setBorder(handyEmptyBorder);

        closeButton.putClientProperty("paintActive", paintActive);
        closeButton.setBorder(handyEmptyBorder);

        // The palette close icon isn't opaque while the regular close icon is.
        // This makes sure palette close buttons have the right background.
        closeButton.setBackground(MetalLookAndFeel.getPrimaryControlShadow());

        if (MetalLookAndFeel.usingOcean()) {
            iconButton.setContentAreaFilled(false);
            maxButton.setContentAreaFilled(false);
            closeButton.setContentAreaFilled(false);
        }
    }

    /**
     * Override the parent's method to do nothing. Metal frames do not
     * have system menus.
     */
    protected void assembleSystemMenu() {}

    /**
     * Override the parent's method to do nothing. Metal frames do not
     * have system menus.
     */
    protected void addSystemMenuItems(JMenu systemMenu) {}

    /**
     * Override the parent's method to do nothing. Metal frames do not
     * have system menus.
     */
    protected void showSystemMenu() {}

    /**
     * Override the parent's method avoid creating a menu bar. Metal frames
     * do not have system menus.
     */
    protected void addSubComponents() {
        add(iconButton);
        add(maxButton);
        add(closeButton);
    }

    protected PropertyChangeListener createPropertyChangeListener() {
        return new MetalPropertyChangeHandler();
    }

    protected LayoutManager createLayout() {
        return new MetalTitlePaneLayout();
    }

    class MetalPropertyChangeHandler
        extends BasicInternalFrameTitlePane.PropertyChangeHandler
    {
        public void propertyChange(PropertyChangeEvent evt) {
            String prop = evt.getPropertyName();
            if( prop.equals(JInternalFrame.IS_SELECTED_PROPERTY) ) {
                Boolean b = (Boolean)evt.getNewValue();
                iconButton.putClientProperty("paintActive", b);
                closeButton.putClientProperty("paintActive", b);
                maxButton.putClientProperty("paintActive", b);
            }
            else if ("JInternalFrame.messageType".equals(prop)) {
                updateOptionPaneState();
                frame.repaint();
            }
            super.propertyChange(evt);
        }
    }

    class MetalTitlePaneLayout extends TitlePaneLayout {
        public void addLayoutComponent(String name, Component c) {}
        public void removeLayoutComponent(Component c) {}
        public Dimension preferredLayoutSize(Container c)  {
            return minimumLayoutSize(c);
        }

        public Dimension minimumLayoutSize(Container c) {
            // Compute width.
            int width = 30;
            if (frame.isClosable()) {
                width += 21;
            }
            if (frame.isMaximizable()) {
                width += 16 + (frame.isClosable() ? 10 : 4);
            }
            if (frame.isIconifiable()) {
                width += 16 + (frame.isMaximizable() ? 2 :
                    (frame.isClosable() ? 10 : 4));
            }
            FontMetrics fm = frame.getFontMetrics(getFont());
            String frameTitle = frame.getTitle();
            int title_w = frameTitle != null ? SwingUtilities2.stringWidth(
                               frame, fm, frameTitle) : 0;
            int title_length = frameTitle != null ? frameTitle.length() : 0;

            if (title_length > 2) {
                int subtitle_w = SwingUtilities2.stringWidth(frame, fm,
                                     frame.getTitle().substring(0, 2) + "...");
                width += (title_w < subtitle_w) ? title_w : subtitle_w;
            }
            else {
                width += title_w;
            }

            // Compute height.
            int height;
            if (isPalette) {
                height = paletteTitleHeight;
            } else {
                int fontHeight = fm.getHeight();
                fontHeight += 7;
                Icon icon = frame.getFrameIcon();
                int iconHeight = 0;
                if (icon != null) {
                    // SystemMenuBar forces the icon to be 16x16 or less.
                    iconHeight = Math.min(icon.getIconHeight(), 16);
                }
                iconHeight += 5;
                height = Math.max(fontHeight, iconHeight);
            }

            return new Dimension(width, height);
        }

        public void layoutContainer(Container c) {
            boolean leftToRight = MetalUtils.isLeftToRight(frame);

            int w = getWidth();
            int x = leftToRight ? w : 0;
            int y = 2;
            int spacing;

            // assumes all buttons have the same dimensions
            // these dimensions include the borders
            int buttonHeight = closeButton.getIcon().getIconHeight();
            int buttonWidth = closeButton.getIcon().getIconWidth();

            if(frame.isClosable()) {
                if (isPalette) {
                    spacing = 3;
                    x += leftToRight ? -spacing -(buttonWidth+2) : spacing;
                    closeButton.setBounds(x, y, buttonWidth+2, getHeight()-4);
                    if( !leftToRight ) x += (buttonWidth+2);
                } else {
                    spacing = 4;
                    x += leftToRight ? -spacing -buttonWidth : spacing;
                    closeButton.setBounds(x, y, buttonWidth, buttonHeight);
                    if( !leftToRight ) x += buttonWidth;
                }
            }

            if(frame.isMaximizable() && !isPalette ) {
                spacing = frame.isClosable() ? 10 : 4;
                x += leftToRight ? -spacing -buttonWidth : spacing;
                maxButton.setBounds(x, y, buttonWidth, buttonHeight);
                if( !leftToRight ) x += buttonWidth;
            }

            if(frame.isIconifiable() && !isPalette ) {
                spacing = frame.isMaximizable() ? 2
                          : (frame.isClosable() ? 10 : 4);
                x += leftToRight ? -spacing -buttonWidth : spacing;
                iconButton.setBounds(x, y, buttonWidth, buttonHeight);
                if( !leftToRight ) x += buttonWidth;
            }

            buttonsWidth = leftToRight ? w - x : x;
        }
    }

    public void paintPalette(Graphics g)  {
        boolean leftToRight = MetalUtils.isLeftToRight(frame);

        int width = getWidth();
        int height = getHeight();

        if (paletteBumps == null) {
            paletteBumps
                = new MetalBumps(0, 0,
                                 MetalLookAndFeel.getPrimaryControlHighlight(),
                                 MetalLookAndFeel.getPrimaryControlInfo(),
                                 MetalLookAndFeel.getPrimaryControlShadow() );
        }

        Color background = MetalLookAndFeel.getPrimaryControlShadow();
        Color darkShadow = MetalLookAndFeel.getPrimaryControlDarkShadow();

        g.setColor(background);
        g.fillRect(0, 0, width, height);

        g.setColor( darkShadow );
        g.drawLine ( 0, height - 1, width, height -1);

        int xOffset = leftToRight ? 4 : buttonsWidth + 4;
        int bumpLength = width - buttonsWidth -2*4;
        int bumpHeight = getHeight()  - 4;
        paletteBumps.setBumpArea( bumpLength, bumpHeight );
        paletteBumps.paintIcon( this, g, xOffset, 2);
    }

    public void paintComponent(Graphics g)  {
        if(isPalette) {
            paintPalette(g);
            return;
        }

        boolean leftToRight = MetalUtils.isLeftToRight(frame);
        boolean isSelected = frame.isSelected();

        int width = getWidth();
        int height = getHeight();

        Color background = null;
        Color foreground = null;
        Color shadow = null;

        MetalBumps bumps;
        String gradientKey;

        if (isSelected) {
            if (!MetalLookAndFeel.usingOcean()) {
                closeButton.setContentAreaFilled(true);
                maxButton.setContentAreaFilled(true);
                iconButton.setContentAreaFilled(true);
            }
            if (selectedBackgroundKey != null) {
                background = UIManager.getColor(selectedBackgroundKey);
            }
            if (background == null) {
                background = MetalLookAndFeel.getWindowTitleBackground();
            }
            if (selectedForegroundKey != null) {
                foreground = UIManager.getColor(selectedForegroundKey);
            }
            if (selectedShadowKey != null) {
                shadow = UIManager.getColor(selectedShadowKey);
            }
            if (shadow == null) {
                shadow = MetalLookAndFeel.getPrimaryControlDarkShadow();
            }
            if (foreground == null) {
                foreground = MetalLookAndFeel.getWindowTitleForeground();
            }
            activeBumps.setBumpColors(activeBumpsHighlight, activeBumpsShadow,
                        UIManager.get("InternalFrame.activeTitleGradient") !=
                                      null ? null : background);
            bumps = activeBumps;
            gradientKey = "InternalFrame.activeTitleGradient";
        } else {
            if (!MetalLookAndFeel.usingOcean()) {
                closeButton.setContentAreaFilled(false);
                maxButton.setContentAreaFilled(false);
                iconButton.setContentAreaFilled(false);
            }
            background = MetalLookAndFeel.getWindowTitleInactiveBackground();
            foreground = MetalLookAndFeel.getWindowTitleInactiveForeground();
            shadow = MetalLookAndFeel.getControlDarkShadow();
            bumps = inactiveBumps;
            gradientKey = "InternalFrame.inactiveTitleGradient";
        }

        if (!MetalUtils.drawGradient(this, g, gradientKey, 0, 0, width,
                                     height, true)) {
            g.setColor(background);
            g.fillRect(0, 0, width, height);
        }

        g.setColor( shadow );
        g.drawLine ( 0, height - 1, width, height -1);
        g.drawLine ( 0, 0, 0 ,0);
        g.drawLine ( width - 1, 0 , width -1, 0);


        int titleLength;
        int xOffset = leftToRight ? 5 : width - 5;
        String frameTitle = frame.getTitle();

        Icon icon = frame.getFrameIcon();
        if ( icon != null ) {
            if( !leftToRight )
                xOffset -= icon.getIconWidth();
            int iconY = ((height / 2) - (icon.getIconHeight() /2));
            icon.paintIcon(frame, g, xOffset, iconY);
            xOffset += leftToRight ? icon.getIconWidth() + 5 : -5;
        }

        if(frameTitle != null) {
            Font f = getFont();
            g.setFont(f);
            FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g, f);
            int fHeight = fm.getHeight();

            g.setColor(foreground);

            int yOffset = ( (height - fm.getHeight() ) / 2 ) + fm.getAscent();

            Rectangle rect = new Rectangle(0, 0, 0, 0);
            if (frame.isIconifiable()) { rect = iconButton.getBounds(); }
            else if (frame.isMaximizable()) { rect = maxButton.getBounds(); }
            else if (frame.isClosable()) { rect = closeButton.getBounds(); }
            int titleW;

            if( leftToRight ) {
              if (rect.x == 0) {
                rect.x = frame.getWidth()-frame.getInsets().right-2;
              }
              titleW = rect.x - xOffset - 4;
              frameTitle = getTitle(frameTitle, fm, titleW);
            } else {
              titleW = xOffset - rect.x - rect.width - 4;
              frameTitle = getTitle(frameTitle, fm, titleW);
              xOffset -= SwingUtilities2.stringWidth(frame, fm, frameTitle);
            }

            titleLength = SwingUtilities2.stringWidth(frame, fm, frameTitle);
            SwingUtilities2.drawString(frame, g, frameTitle, xOffset, yOffset);
            xOffset += leftToRight ? titleLength + 5  : -5;
        }

        int bumpXOffset;
        int bumpLength;
        if( leftToRight ) {
            bumpLength = width - buttonsWidth - xOffset - 5;
            bumpXOffset = xOffset;
        } else {
            bumpLength = xOffset - buttonsWidth - 5;
            bumpXOffset = buttonsWidth + 5;
        }
        int bumpYOffset = 3;
        int bumpHeight = getHeight() - (2 * bumpYOffset);
        bumps.setBumpArea( bumpLength, bumpHeight );
        bumps.paintIcon(this, g, bumpXOffset, bumpYOffset);
    }

    public void setPalette(boolean b) {
        isPalette = b;

        if (isPalette) {
            closeButton.setIcon(paletteCloseIcon);
         if( frame.isMaximizable() )
                remove(maxButton);
            if( frame.isIconifiable() )
                remove(iconButton);
        } else {
            closeButton.setIcon(closeIcon);
            if( frame.isMaximizable() )
                add(maxButton);
            if( frame.isIconifiable() )
                add(iconButton);
        }
        revalidate();
        repaint();
    }

    /**
     * Updates any state dependant upon the JInternalFrame being shown in
     * a <code>JOptionPane</code>.
     */
    private void updateOptionPaneState() {
        int type = -2;
        boolean closable = wasClosable;
        Object obj = frame.getClientProperty("JInternalFrame.messageType");

        if (obj == null) {
            // Don't change the closable state unless in an JOptionPane.
            return;
        }
        if (obj instanceof Integer) {
            type = ((Integer) obj).intValue();
        }
        switch (type) {
        case JOptionPane.ERROR_MESSAGE:
            selectedBackgroundKey =
                              "OptionPane.errorDialog.titlePane.background";
            selectedForegroundKey =
                              "OptionPane.errorDialog.titlePane.foreground";
            selectedShadowKey = "OptionPane.errorDialog.titlePane.shadow";
            closable = false;
            break;
        case JOptionPane.QUESTION_MESSAGE:
            selectedBackgroundKey =
                            "OptionPane.questionDialog.titlePane.background";
            selectedForegroundKey =
                    "OptionPane.questionDialog.titlePane.foreground";
            selectedShadowKey =
                          "OptionPane.questionDialog.titlePane.shadow";
            closable = false;
            break;
        case JOptionPane.WARNING_MESSAGE:
            selectedBackgroundKey =
                              "OptionPane.warningDialog.titlePane.background";
            selectedForegroundKey =
                              "OptionPane.warningDialog.titlePane.foreground";
            selectedShadowKey = "OptionPane.warningDialog.titlePane.shadow";
            closable = false;
            break;
        case JOptionPane.INFORMATION_MESSAGE:
        case JOptionPane.PLAIN_MESSAGE:
            selectedBackgroundKey = selectedForegroundKey = selectedShadowKey =
                                    null;
            closable = false;
            break;
        default:
            selectedBackgroundKey = selectedForegroundKey = selectedShadowKey =
                                    null;
            break;
        }
        if (closable != frame.isClosable()) {
            frame.setClosable(closable);
        }
    }
}
