/*
 * Copyright 1998-2003 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.swing.text;

import java.io.Serializable;

/**
 * A TabSet is comprised of many TabStops. It offers methods for locating the
 * closest TabStop to a given position and finding all the potential TabStops.
 * It is also immutable.
 * <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.  As of 1.4, support for long term storage
 * of all JavaBeans<sup><font size="-2">TM</font></sup>
 * has been added to the <code>java.beans</code> package.
 * Please see {@link java.beans.XMLEncoder}.
 *
 * @author  Scott Violet
 */
public class TabSet implements Serializable
{
    /** TabStops this TabSet contains. */
    private TabStop[]              tabs;
    /**
     * Since this class is immutable the hash code could be
     * calculated once. MAX_VALUE means that it was not initialized
     * yet. Hash code shouldn't has MAX_VALUE value.
     */
    private int hashCode = Integer.MAX_VALUE;

    /**
     * Creates and returns an instance of TabSet. The array of Tabs
     * passed in must be sorted in ascending order.
     */
    public TabSet(TabStop[] tabs) {
        // PENDING(sky): If this becomes a problem, make it sort.
        if(tabs != null) {
            int          tabCount = tabs.length;

            this.tabs = new TabStop[tabCount];
            System.arraycopy(tabs, 0, this.tabs, 0, tabCount);
        }
        else
            this.tabs = null;
    }

    /**
     * Returns the number of Tab instances the receiver contains.
     */
    public int getTabCount() {
        return (tabs == null) ? 0 : tabs.length;
    }

    /**
     * Returns the TabStop at index <code>index</code>. This will throw an
     * IllegalArgumentException if <code>index</code> is outside the range
     * of tabs.
     */
    public TabStop getTab(int index) {
        int          numTabs = getTabCount();

        if(index < 0 || index >= numTabs)
            throw new IllegalArgumentException(index +
                                              " is outside the range of tabs");
        return tabs[index];
    }

    /**
     * Returns the Tab instance after <code>location</code>. This will
     * return null if there are no tabs after <code>location</code>.
     */
    public TabStop getTabAfter(float location) {
        int     index = getTabIndexAfter(location);

        return (index == -1) ? null : tabs[index];
    }

    /**
     * @return the index of the TabStop <code>tab</code>, or -1 if
     * <code>tab</code> is not contained in the receiver.
     */
    public int getTabIndex(TabStop tab) {
        for(int counter = getTabCount() - 1; counter >= 0; counter--)
            // should this use .equals?
            if(getTab(counter) == tab)
                return counter;
        return -1;
    }

    /**
     * Returns the index of the Tab to be used after <code>location</code>.
     * This will return -1 if there are no tabs after <code>location</code>.
     */
    public int getTabIndexAfter(float location) {
        int     current, min, max;

        min = 0;
        max = getTabCount();
        while(min != max) {
            current = (max - min) / 2 + min;
            if(location > tabs[current].getPosition()) {
                if(min == current)
                    min = max;
                else
                    min = current;
            }
            else {
                if(current == 0 || location > tabs[current - 1].getPosition())
                    return current;
                max = current;
            }
        }
        // no tabs after the passed in location.
        return -1;
    }

    /**
     * Indicates whether this <code>TabSet</code> is equal to another one.
     * @param o the <code>TabSet</code> instance which this instance
     *  should be compared to.
     * @return <code>true</code> if <code>o</code> is the instance of
     * <code>TabSet</code>, has the same number of <code>TabStop</code>s
     * and they are all equal, <code>false</code> otherwise.
     *
     * @since 1.5
     */
    public boolean equals(Object o) {
        if (o == this) {
            return true;
        }
        if (o instanceof TabSet) {
            TabSet ts = (TabSet) o;
            int count = getTabCount();
            if (ts.getTabCount() != count) {
                return false;
            }
            for (int i=0; i < count; i++) {
                TabStop ts1 = getTab(i);
                TabStop ts2 = ts.getTab(i);
                if ((ts1 == null && ts2 != null) ||
                        (ts1 != null && !getTab(i).equals(ts.getTab(i)))) {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Returns a hashcode for this set of TabStops.
     * @return  a hashcode value for this set of TabStops.
     *
     * @since 1.5
     */
    public int hashCode() {
        if (hashCode == Integer.MAX_VALUE) {
            hashCode = 0;
            int len = getTabCount();
            for (int i = 0; i < len; i++) {
                TabStop ts = getTab(i);
                hashCode ^= ts != null ? getTab(i).hashCode() : 0;
            }
            if (hashCode == Integer.MAX_VALUE) {
                hashCode -= 1;
            }
        }
        return hashCode;
    }

    /**
     * Returns the string representation of the set of tabs.
     */
    public String toString() {
        int            tabCount = getTabCount();
        StringBuffer   buffer = new StringBuffer("[ ");

        for(int counter = 0; counter < tabCount; counter++) {
            if(counter > 0)
                buffer.append(" - ");
            buffer.append(getTab(counter).toString());
        }
        buffer.append(" ]");
        return buffer.toString();
    }
}
