/*
 * Copyright (c) 2011, 2012, 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 javax.swing.SwingConstants;

class AquaTabbedPaneTabState {
    static final int FIXED_SCROLL_TAB_LENGTH = 27;

    protected final Rectangle leftScrollTabRect = new Rectangle();
    protected final Rectangle rightScrollTabRect = new Rectangle();

    protected int numberOfVisibleTabs = 0;
    protected int visibleTabList[] = new int[10];
    protected int lastLeftmostTab;
    protected int lastReturnAt;

    private boolean needsScrollers;
    private boolean hasMoreLeftTabs;
    private boolean hasMoreRightTabs;

    private final AquaTabbedPaneUI pane;

    protected AquaTabbedPaneTabState(final AquaTabbedPaneUI pane) {
        this.pane = pane;
    }

    protected int getIndex(final int i) {
        if (i >= visibleTabList.length) return Integer.MIN_VALUE;
        return visibleTabList[i];
    }

    protected void init(final int tabCount) {
        if (tabCount < 1) needsScrollers = false;
        if (tabCount == visibleTabList.length) return;
        final int[] tempVisibleTabs = new int[tabCount];
        System.arraycopy(visibleTabList, 0, tempVisibleTabs, 0, Math.min(visibleTabList.length, tabCount));
        visibleTabList = tempVisibleTabs;
    }

    int getTotal() {
        return numberOfVisibleTabs;
    }

    boolean needsScrollTabs() {
        return needsScrollers;
    }

    void setNeedsScrollers(final boolean needsScrollers) {
        this.needsScrollers = needsScrollers;
    }

    boolean needsLeftScrollTab() {
        return hasMoreLeftTabs;
    }

    boolean needsRightScrollTab() {
        return hasMoreRightTabs;
    }

    Rectangle getLeftScrollTabRect() {
        return leftScrollTabRect;
    }

    Rectangle getRightScrollTabRect() {
        return rightScrollTabRect;
    }

    boolean isBefore(final int i) {
        if (numberOfVisibleTabs == 0) return true;
        if (i < visibleTabList[0]) return true;
        return false;
    }

    boolean isAfter(final int i) {
        if (i > visibleTabList[numberOfVisibleTabs - 1]) return true;
        return false;
    }

    private void addToEnd(final int idToAdd, final int length) {
        visibleTabList[length] = idToAdd;
    }

    private void addToBeginning(final int idToAdd, final int length) {
        System.arraycopy(visibleTabList, 0, visibleTabList, 1, length);
        visibleTabList[0] = idToAdd;
    }


    void relayoutForScrolling(final Rectangle[] rects, final int startX, final int startY, final int returnAt, final int selectedIndex, final boolean verticalTabRuns, final int tabCount, final boolean isLeftToRight) {
        if (!needsScrollers) {
            hasMoreLeftTabs = false;
            hasMoreRightTabs = false;
            return;
        }

        // we don't fit, so we need to figure the space based on the size of the popup
        // tab, then add the tabs, centering the selected tab as much as possible.

        // Tabs on TOP or BOTTOM or LEFT or RIGHT
        // if top or bottom, width is hardocoded
        // if left or right height should be hardcoded.
        if (verticalTabRuns) {
            rightScrollTabRect.height = FIXED_SCROLL_TAB_LENGTH;
            leftScrollTabRect.height = FIXED_SCROLL_TAB_LENGTH;
        } else {
            rightScrollTabRect.width = FIXED_SCROLL_TAB_LENGTH;
            leftScrollTabRect.width = FIXED_SCROLL_TAB_LENGTH;
        }

        // we have all the tab rects, we just need to adjust the x coordinates
        // and populate the visible list

        // sja fix what do we do if remaining width is <0??

        // we could try to center it based on width of tabs, but for now
        // we try to center based on number of tabs on each side, putting the extra
        // on the left (since the first right is the selected tab).
        // if we have 0 selected we will just go right, and if we have

        // the logic here is start with the selected tab, and then fit
        // in as many tabs as possible on each side until we don't fit any more.
        // but if all we did was change selection then we need to try to keep the same
        // tabs on screen so we don't get a jarring tab moving out from under the mouse
        // effect.

        final boolean sizeChanged = returnAt != lastReturnAt;
        // so if we stay the same, make right the first tab and say left done = true
        if (pane.popupSelectionChanged || sizeChanged) {
            pane.popupSelectionChanged = false;
            lastLeftmostTab = -1;
        }

        int right = selectedIndex;
        int left = selectedIndex - 1;

        // if we had a good last leftmost tab then we set left to unused and
        // start at that tab.
        if (lastLeftmostTab >= 0) {
            right = lastLeftmostTab;
            left = -1;
        } else if (selectedIndex < 0) {
            // this is if there is none selected see radar 3138137
            right = 0;
            left = -1;
        }

        int remainingSpace = returnAt - pane.tabAreaInsets.right - pane.tabAreaInsets.left - FIXED_SCROLL_TAB_LENGTH * 2;
        int visibleCount = 0;

        final Rectangle firstRect = rects[right];
        if ((verticalTabRuns ? firstRect.height : firstRect.width) > remainingSpace) {
            // always show at least the selected one!
            addToEnd(right, visibleCount);
            if (verticalTabRuns) {
                firstRect.height = remainingSpace; // force it to fit!
            } else {
                firstRect.width = remainingSpace; // force it to fit!
            }
            visibleCount++;
        } else {
            boolean rightDone = false;
            boolean leftDone = false;

            // at least one if not more will fit
            while ((visibleCount < tabCount) && !(rightDone && leftDone)) {
                if (!rightDone && right >= 0 && right < tabCount) {
                    final Rectangle rightRect = rects[right];
                    if ((verticalTabRuns ? rightRect.height : rightRect.width) > remainingSpace) {
                        rightDone = true;
                    } else {
                        addToEnd(right, visibleCount);
                        visibleCount++;
                        remainingSpace -= (verticalTabRuns ? rightRect.height : rightRect.width);
                        right++;
                        continue; // this gives a bias to "paging forward", and "inching backward"
                    }
                } else {
                    rightDone = true;
                }

                if (!leftDone && left >= 0 && left < tabCount) {
                    final Rectangle leftRect = rects[left];
                    if ((verticalTabRuns ? leftRect.height : leftRect.width) > remainingSpace) {
                        leftDone = true;
                    } else {
                        addToBeginning(left, visibleCount);
                        visibleCount++;
                        remainingSpace -= (verticalTabRuns ? leftRect.height : leftRect.width);
                        left--;
                    }
                } else {
                    leftDone = true;
                }
            }
        }

        if (visibleCount > visibleTabList.length) visibleCount = visibleTabList.length;

        hasMoreLeftTabs = visibleTabList[0] > 0;
        hasMoreRightTabs = visibleTabList[visibleCount - 1] < visibleTabList.length - 1;

        numberOfVisibleTabs = visibleCount;
        // add the scroll tab at the end;
        lastLeftmostTab = getIndex(0);
        lastReturnAt = returnAt;

        final int firstTabIndex = getIndex(0);
        final int lastTabIndex = getIndex(visibleCount - 1);

        // move all "invisible" tabs beyond the edge of known space...
        for (int i = 0; i < tabCount; i++) {
            if (i < firstTabIndex || i > lastTabIndex) {
                final Rectangle rect = rects[i];
                rect.x = Short.MAX_VALUE;
                rect.y = Short.MAX_VALUE;
            }
        }
    }

    protected void alignRectsRunFor(final Rectangle[] rects, final Dimension tabPaneSize, final int tabPlacement, final boolean isRightToLeft) {
        final boolean isVertical = tabPlacement == SwingConstants.LEFT || tabPlacement == SwingConstants.RIGHT;

        if (isVertical) {
            if (needsScrollers) {
                stretchScrollingVerticalRun(rects, tabPaneSize);
            } else {
                centerVerticalRun(rects, tabPaneSize);
            }
        } else {
            if (needsScrollers) {
                stretchScrollingHorizontalRun(rects, tabPaneSize, isRightToLeft);
            } else {
                centerHorizontalRun(rects, tabPaneSize, isRightToLeft);
            }
        }
    }

    private void centerHorizontalRun(final Rectangle[] rects, final Dimension size, final boolean isRightToLeft) {
        int totalLength = 0;
        for (final Rectangle element : rects) {
            totalLength += element.width;
        }

        int x = size.width / 2 - totalLength / 2;

        if (isRightToLeft) {
            for (final Rectangle rect : rects) {
                rect.x = x;
                x += rect.width;
            }
        } else {
            for (int i = rects.length - 1; i >= 0; i--) {
                final Rectangle rect = rects[i];
                rect.x = x;
                x += rect.width;
            }
        }
    }

    private void centerVerticalRun(final Rectangle[] rects, final Dimension size) {
        int totalLength = 0;
        for (final Rectangle element : rects) {
            totalLength += element.height;
        }

        int y = size.height / 2 - totalLength / 2;

        if (true) {
            for (final Rectangle rect : rects) {
                rect.y = y;
                y += rect.height;
            }
        } else {
            for (int i = rects.length - 1; i >= 0; i--) {
                final Rectangle rect = rects[i];
                rect.y = y;
                y += rect.height;
            }
        }
    }

    private void stretchScrollingHorizontalRun(final Rectangle[] rects, final Dimension size, final boolean isRightToLeft) {
        final int totalTabs = getTotal();
        final int firstTabIndex = getIndex(0);
        final int lastTabIndex = getIndex(totalTabs - 1);

        int totalRunLength = 0;
        for (int i = firstTabIndex; i <= lastTabIndex; i++) {
            totalRunLength += rects[i].width;
        }

        int slack = size.width - totalRunLength - pane.tabAreaInsets.left - pane.tabAreaInsets.right;
        if (needsLeftScrollTab()) {
            slack -= FIXED_SCROLL_TAB_LENGTH;
        }
        if (needsRightScrollTab()) {
            slack -= FIXED_SCROLL_TAB_LENGTH;
        }

        final int minSlack = (int)((float)(slack) / (float)(totalTabs));
        int extraSlack = slack - (minSlack * totalTabs);
        int runningLength = 0;
        final int xOffset = pane.tabAreaInsets.left + (needsLeftScrollTab() ? FIXED_SCROLL_TAB_LENGTH : 0);

        if (isRightToLeft) {
            for (int i = firstTabIndex; i <= lastTabIndex; i++) {
                final Rectangle rect = rects[i];
                int slackToAdd = minSlack;
                if (extraSlack > 0) {
                    slackToAdd++;
                    extraSlack--;
                }
                rect.x = runningLength + xOffset;
                rect.width += slackToAdd;
                runningLength += rect.width;
            }
        } else {
            for (int i = lastTabIndex; i >= firstTabIndex; i--) {
                final Rectangle rect = rects[i];
                int slackToAdd = minSlack;
                if (extraSlack > 0) {
                    slackToAdd++;
                    extraSlack--;
                }
                rect.x = runningLength + xOffset;
                rect.width += slackToAdd;
                runningLength += rect.width;
            }
        }

        if (isRightToLeft) {
            leftScrollTabRect.x = pane.tabAreaInsets.left;
            leftScrollTabRect.y = rects[firstTabIndex].y;
            leftScrollTabRect.height = rects[firstTabIndex].height;

            rightScrollTabRect.x = size.width - pane.tabAreaInsets.right - rightScrollTabRect.width;
            rightScrollTabRect.y = rects[lastTabIndex].y;
            rightScrollTabRect.height = rects[lastTabIndex].height;
        } else {
            rightScrollTabRect.x = pane.tabAreaInsets.left;
            rightScrollTabRect.y = rects[firstTabIndex].y;
            rightScrollTabRect.height = rects[firstTabIndex].height;

            leftScrollTabRect.x = size.width - pane.tabAreaInsets.right - rightScrollTabRect.width;
            leftScrollTabRect.y = rects[lastTabIndex].y;
            leftScrollTabRect.height = rects[lastTabIndex].height;

            if (needsLeftScrollTab()) {
                for (int i = lastTabIndex; i >= firstTabIndex; i--) {
                    final Rectangle rect = rects[i];
                    rect.x -= FIXED_SCROLL_TAB_LENGTH;
                }
            }

            if (needsRightScrollTab()) {
                for (int i = lastTabIndex; i >= firstTabIndex; i--) {
                    final Rectangle rect = rects[i];
                    rect.x += FIXED_SCROLL_TAB_LENGTH;
                }
            }
        }
    }

    private void stretchScrollingVerticalRun(final Rectangle[] rects, final Dimension size) {
        final int totalTabs = getTotal();
        final int firstTabIndex = getIndex(0);
        final int lastTabIndex = getIndex(totalTabs - 1);

        int totalRunLength = 0;
        for (int i = firstTabIndex; i <= lastTabIndex; i++) {
            totalRunLength += rects[i].height;
        }

        int slack = size.height - totalRunLength - pane.tabAreaInsets.top - pane.tabAreaInsets.bottom;
        if (needsLeftScrollTab()) {
            slack -= FIXED_SCROLL_TAB_LENGTH;
        }
        if (needsRightScrollTab()) {
            slack -= FIXED_SCROLL_TAB_LENGTH;
        }

        final int minSlack = (int)((float)(slack) / (float)(totalTabs));
        int extraSlack = slack - (minSlack * totalTabs);
        int runningLength = 0;
        final int yOffset = pane.tabAreaInsets.top + (needsLeftScrollTab() ? FIXED_SCROLL_TAB_LENGTH : 0);

        for (int i = firstTabIndex; i <= lastTabIndex; i++) {
            final Rectangle rect = rects[i];
            int slackToAdd = minSlack;
            if (extraSlack > 0) {
                slackToAdd++;
                extraSlack--;
            }
            rect.y = runningLength + yOffset;
            rect.height += slackToAdd;
            runningLength += rect.height;
        }

        leftScrollTabRect.x = rects[firstTabIndex].x;
        leftScrollTabRect.y = pane.tabAreaInsets.top;
        leftScrollTabRect.width = rects[firstTabIndex].width;

        rightScrollTabRect.x = rects[lastTabIndex].x;
        rightScrollTabRect.y = size.height - pane.tabAreaInsets.bottom - rightScrollTabRect.height;
        rightScrollTabRect.width = rects[lastTabIndex].width;
    }
}
