/*
 * Copyright (c) 2011, 2014, 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.apple.laf;

import java.awt.*;
import java.util.Enumeration;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.BasicTableHeaderUI;
import javax.swing.table.*;
import com.apple.laf.ClientPropertyApplicator;
import com.apple.laf.ClientPropertyApplicator.Property;
import com.apple.laf.AquaUtils.RecyclableSingleton;

public class AquaTableHeaderUI extends BasicTableHeaderUI {
    private int originalHeaderAlignment;
    protected int sortColumn;
    protected int sortOrder;

    public static ComponentUI createUI(final JComponent c) {
        return new AquaTableHeaderUI();
    }

    public void installDefaults() {
        super.installDefaults();

        final TableCellRenderer renderer = header.getDefaultRenderer();
        if (renderer instanceof UIResource && renderer instanceof DefaultTableCellRenderer) {
            final DefaultTableCellRenderer defaultRenderer = (DefaultTableCellRenderer)renderer;
            originalHeaderAlignment = defaultRenderer.getHorizontalAlignment();
            defaultRenderer.setHorizontalAlignment(SwingConstants.LEADING);
        }
    }

    public void uninstallDefaults() {
        final TableCellRenderer renderer = header.getDefaultRenderer();
        if (renderer instanceof UIResource && renderer instanceof DefaultTableCellRenderer) {
            final DefaultTableCellRenderer defaultRenderer = (DefaultTableCellRenderer)renderer;
            defaultRenderer.setHorizontalAlignment(originalHeaderAlignment);
        }

        super.uninstallDefaults();
    }

    static final RecyclableSingleton<ClientPropertyApplicator<JTableHeader, JTableHeader>> TABLE_HEADER_APPLICATORS = new RecyclableSingleton<ClientPropertyApplicator<JTableHeader, JTableHeader>>() {
        @Override
        @SuppressWarnings("unchecked")
        protected ClientPropertyApplicator<JTableHeader, JTableHeader> getInstance() {
            return new ClientPropertyApplicator<JTableHeader, JTableHeader>(
                    new Property<JTableHeader>("JTableHeader.selectedColumn") {
                        public void applyProperty(final JTableHeader target, final Object value) {
                            tickle(target, value, target.getClientProperty("JTableHeader.sortDirection"));
                        }
                    },
                    new Property<JTableHeader>("JTableHeader.sortDirection") {
                        public void applyProperty(final JTableHeader target, final Object value) {
                            tickle(target, target.getClientProperty("JTableHeader.selectedColumn"), value);
                        }
                    }
            );
        }
    };
    static ClientPropertyApplicator<JTableHeader, JTableHeader> getTableHeaderApplicators() {
        return TABLE_HEADER_APPLICATORS.get();
    }

    static void tickle(final JTableHeader target, final Object selectedColumn, final Object direction) {
        final TableColumn tableColumn = getTableColumn(target, selectedColumn);
        if (tableColumn == null) return;

        int sortDirection = 0;
        if ("ascending".equalsIgnoreCase(direction+"")) {
            sortDirection = 1;
        } else if ("descending".equalsIgnoreCase(direction+"")) {
            sortDirection = -1;
        } else if ("decending".equalsIgnoreCase(direction+"")) {
            sortDirection = -1; // stupid misspelling that GM'ed in 10.5.0
        }

        final TableHeaderUI headerUI = target.getUI();
        if (headerUI == null || !(headerUI instanceof AquaTableHeaderUI)) return;

        final AquaTableHeaderUI aquaHeaderUI = (AquaTableHeaderUI)headerUI;
        aquaHeaderUI.sortColumn = tableColumn.getModelIndex();
        aquaHeaderUI.sortOrder = sortDirection;
        final AquaTableCellRenderer renderer = aquaHeaderUI.new AquaTableCellRenderer();
        tableColumn.setHeaderRenderer(renderer);
    }

    @SuppressWarnings("serial") // Superclass is not serializable across versions
    class AquaTableCellRenderer extends DefaultTableCellRenderer implements UIResource {
        public Component getTableCellRendererComponent(final JTable localTable, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) {
            if (localTable != null) {
                if (header != null) {
                    setForeground(header.getForeground());
                    setBackground(header.getBackground());
                    setFont(UIManager.getFont("TableHeader.font"));
                }
            }

            setText((value == null) ? "" : value.toString());

            // Modify the table "border" to draw smaller, and with the titles in the right position
            // and sort indicators, just like an NSSave/Open panel.
            final AquaTableHeaderBorder cellBorder = AquaTableHeaderBorder.getListHeaderBorder();
            cellBorder.setSortOrder(AquaTableHeaderBorder.SORT_NONE);

            if (localTable != null) {
                final boolean thisColumnSelected = localTable.getColumnModel().getColumn(column).getModelIndex() == sortColumn;

                cellBorder.setSelected(thisColumnSelected);
                if (thisColumnSelected) {
                    cellBorder.setSortOrder(sortOrder);
               }
            }

            setBorder(cellBorder);
            return this;
        }
    }

    protected static TableColumn getTableColumn(final JTableHeader target, final Object value) {
        if (value == null || !(value instanceof Integer)) return null;
        final int columnIndex = ((Integer)value).intValue();

        final TableColumnModel columnModel = target.getColumnModel();
        if (columnIndex < 0 || columnIndex >= columnModel.getColumnCount()) return null;

        return columnModel.getColumn(columnIndex);
    }

    protected static AquaTableHeaderBorder getAquaBorderFrom(final JTableHeader header, final TableColumn column) {
        final TableCellRenderer renderer = column.getHeaderRenderer();
        if (renderer == null) return null;

        final Component c = renderer.getTableCellRendererComponent(header.getTable(), column.getHeaderValue(), false, false, -1, column.getModelIndex());
        if (!(c instanceof JComponent)) return null;

        final Border border = ((JComponent)c).getBorder();
        if (!(border instanceof AquaTableHeaderBorder)) return null;

        return (AquaTableHeaderBorder)border;
    }

    protected void installListeners() {
        super.installListeners();
        getTableHeaderApplicators().attachAndApplyClientProperties(header);
    }

    protected void uninstallListeners() {
        getTableHeaderApplicators().removeFrom(header);
        super.uninstallListeners();
    }

    private int getHeaderHeightAqua() {
        int height = 0;
        boolean accomodatedDefault = false;

        final TableColumnModel columnModel = header.getColumnModel();
        for (int column = 0; column < columnModel.getColumnCount(); column++) {
            final TableColumn aColumn = columnModel.getColumn(column);
            // Configuring the header renderer to calculate its preferred size is expensive.
            // Optimise this by assuming the default renderer always has the same height.
            if (aColumn.getHeaderRenderer() != null || !accomodatedDefault) {
                final Component comp = getHeaderRendererAqua(column);
                final int rendererHeight = comp.getPreferredSize().height;
                height = Math.max(height, rendererHeight);
                // If the header value is empty (== "") in the
                // first column (and this column is set up
                // to use the default renderer) we will
                // return zero from this routine and the header
                // will disappear altogether. Avoiding the calculation
                // of the preferred size is such a performance win for
                // most applications that we will continue to
                // use this cheaper calculation, handling these
                // issues as `edge cases'.

                // Mac OS X Change - since we have a border on our renderers
                // it is possible the height of an empty header could be > 0,
                // so we chose the relatively safe number of 4 to handle this case.
                // Now if we get a size of 4 or less we assume it is empty and measure
                // a different header.
                if (rendererHeight > 4) {
                    accomodatedDefault = true;
                }
            }
        }
        return height;
    }

    private Component getHeaderRendererAqua(final int columnIndex) {
        final TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);
        TableCellRenderer renderer = aColumn.getHeaderRenderer();
        if (renderer == null) {
            renderer = header.getDefaultRenderer();
        }
        return renderer.getTableCellRendererComponent(header.getTable(), aColumn.getHeaderValue(), false, false, -1, columnIndex);
    }

    private Dimension createHeaderSizeAqua(long width) {
        // None of the callers include the intercell spacing, do it here.
        if (width > Integer.MAX_VALUE) {
            width = Integer.MAX_VALUE;
        }
        return new Dimension((int)width, getHeaderHeightAqua());
    }

    /**
     * Return the minimum size of the header. The minimum width is the sum of the minimum widths of each column (plus
     * inter-cell spacing).
     */
    public Dimension getMinimumSize(final JComponent c) {
        long width = 0;
        final Enumeration<TableColumn> enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            final TableColumn aColumn = enumeration.nextElement();
            width = width + aColumn.getMinWidth();
        }
        return createHeaderSizeAqua(width);
    }

    /**
     * Return the preferred size of the header. The preferred height is the maximum of the preferred heights of all of
     * the components provided by the header renderers. The preferred width is the sum of the preferred widths of each
     * column (plus inter-cell spacing).
     */
    public Dimension getPreferredSize(final JComponent c) {
        long width = 0;
        final Enumeration<TableColumn> enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            final TableColumn aColumn = enumeration.nextElement();
            width = width + aColumn.getPreferredWidth();
        }
        return createHeaderSizeAqua(width);
    }
}
