/*
 * Copyright (c) 2003, 2011, 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;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;

/*
 * Private storage mechanism for Action key-value pairs.
 * In most cases this will be an array of alternating
 * key-value pairs.  As it grows larger it is scaled
 * up to a Hashtable.
 * <p>
 * This does no synchronization, if you need thread safety synchronize on
 * another object before calling this.
 *
 * @author Georges Saab
 * @author Scott Violet
 */
class ArrayTable implements Cloneable {
    // Our field for storage
    private Object table = null;
    private static final int ARRAY_BOUNDARY = 8;


    /**
     * Writes the passed in ArrayTable to the passed in ObjectOutputStream.
     * The data is saved as an integer indicating how many key/value
     * pairs are being archived, followed by the the key/value pairs. If
     * <code>table</code> is null, 0 will be written to <code>s</code>.
     * <p>
     * This is a convenience method that ActionMap/InputMap and
     * AbstractAction use to avoid having the same code in each class.
     */
    static void writeArrayTable(ObjectOutputStream s, ArrayTable table) throws IOException {
        Object keys[];

        if (table == null || (keys = table.getKeys(null)) == null) {
            s.writeInt(0);
        }
        else {
            // Determine how many keys have Serializable values, when
            // done all non-null values in keys identify the Serializable
            // values.
            int validCount = 0;

            for (int counter = 0; counter < keys.length; counter++) {
                Object key = keys[counter];

                /* include in Serialization when both keys and values are Serializable */
                if (    (key instanceof Serializable
                         && table.get(key) instanceof Serializable)
                             ||
                         /* include these only so that we get the appropriate exception below */
                        (key instanceof ClientPropertyKey
                         && ((ClientPropertyKey)key).getReportValueNotSerializable())) {

                    validCount++;
                } else {
                    keys[counter] = null;
                }
            }
            // Write ou the Serializable key/value pairs.
            s.writeInt(validCount);
            if (validCount > 0) {
                for (Object key : keys) {
                    if (key != null) {
                        s.writeObject(key);
                        s.writeObject(table.get(key));
                        if (--validCount == 0) {
                            break;
                        }
                    }
                }
            }
        }
    }


    /*
     * Put the key-value pair into storage
     */
    public void put(Object key, Object value){
        if (table==null) {
            table = new Object[] {key, value};
        } else {
            int size = size();
            if (size < ARRAY_BOUNDARY) {              // We are an array
                if (containsKey(key)) {
                    Object[] tmp = (Object[])table;
                    for (int i = 0; i<tmp.length-1; i+=2) {
                        if (tmp[i].equals(key)) {
                            tmp[i+1]=value;
                            break;
                        }
                    }
                } else {
                    Object[] array = (Object[])table;
                    int i = array.length;
                    Object[] tmp = new Object[i+2];
                    System.arraycopy(array, 0, tmp, 0, i);

                    tmp[i] = key;
                    tmp[i+1] = value;
                    table = tmp;
                }
            } else {                 // We are a hashtable
                if ((size==ARRAY_BOUNDARY) && isArray()) {
                    grow();
                }
                ((Hashtable<Object,Object>)table).put(key, value);
            }
        }
    }

    /*
     * Gets the value for key
     */
    public Object get(Object key) {
        Object value = null;
        if (table !=null) {
            if (isArray()) {
                Object[] array = (Object[])table;
                for (int i = 0; i<array.length-1; i+=2) {
                    if (array[i].equals(key)) {
                        value = array[i+1];
                        break;
                    }
                }
            } else {
                value = ((Hashtable)table).get(key);
            }
        }
        return value;
    }

    /*
     * Returns the number of pairs in storage
     */
    public int size() {
        int size;
        if (table==null)
            return 0;
        if (isArray()) {
            size = ((Object[])table).length/2;
        } else {
            size = ((Hashtable)table).size();
        }
        return size;
    }

    /*
     * Returns true if we have a value for the key
     */
    public boolean containsKey(Object key) {
        boolean contains = false;
        if (table !=null) {
            if (isArray()) {
                Object[] array = (Object[])table;
                for (int i = 0; i<array.length-1; i+=2) {
                    if (array[i].equals(key)) {
                        contains = true;
                        break;
                    }
                }
            } else {
                contains = ((Hashtable)table).containsKey(key);
            }
        }
        return contains;
    }

    /*
     * Removes the key and its value
     * Returns the value for the pair removed
     */
    public Object remove(Object key){
        Object value = null;
        if (key==null) {
            return null;
        }
        if (table !=null) {
            if (isArray()){
                // Is key on the list?
                int index = -1;
                Object[] array = (Object[])table;
                for (int i = array.length-2; i>=0; i-=2) {
                    if (array[i].equals(key)) {
                        index = i;
                        value = array[i+1];
                        break;
                    }
                }

                // If so,  remove it
                if (index != -1) {
                    Object[] tmp = new Object[array.length-2];
                    // Copy the list up to index
                    System.arraycopy(array, 0, tmp, 0, index);
                    // Copy from two past the index, up to
                    // the end of tmp (which is two elements
                    // shorter than the old list)
                    if (index < tmp.length)
                        System.arraycopy(array, index+2, tmp, index,
                                         tmp.length - index);
                    // set the listener array to the new array or null
                    table = (tmp.length == 0) ? null : tmp;
                }
            } else {
                value = ((Hashtable)table).remove(key);
            }
            if (size()==ARRAY_BOUNDARY - 1 && !isArray()) {
                shrink();
            }
        }
        return value;
    }

    /**
     * Removes all the mappings.
     */
    public void clear() {
        table = null;
    }

    /*
     * Returns a clone of the <code>ArrayTable</code>.
     */
    public Object clone() {
        ArrayTable newArrayTable = new ArrayTable();
        if (isArray()) {
            Object[] array = (Object[])table;
            for (int i = 0 ;i < array.length-1 ; i+=2) {
                newArrayTable.put(array[i], array[i+1]);
            }
        } else {
            Hashtable<?,?> tmp = (Hashtable)table;
            Enumeration<?> keys = tmp.keys();
            while (keys.hasMoreElements()) {
                Object o = keys.nextElement();
                newArrayTable.put(o,tmp.get(o));
            }
        }
        return newArrayTable;
    }

    /**
     * Returns the keys of the table, or <code>null</code> if there
     * are currently no bindings.
     * @param keys  array of keys
     * @return an array of bindings
     */
    public Object[] getKeys(Object[] keys) {
        if (table == null) {
            return null;
        }
        if (isArray()) {
            Object[] array = (Object[])table;
            if (keys == null) {
                keys = new Object[array.length / 2];
            }
            for (int i = 0, index = 0 ;i < array.length-1 ; i+=2,
                     index++) {
                keys[index] = array[i];
            }
        } else {
            Hashtable<?,?> tmp = (Hashtable)table;
            Enumeration<?> enum_ = tmp.keys();
            int counter = tmp.size();
            if (keys == null) {
                keys = new Object[counter];
            }
            while (counter > 0) {
                keys[--counter] = enum_.nextElement();
            }
        }
        return keys;
    }

    /*
     * Returns true if the current storage mechanism is
     * an array of alternating key-value pairs.
     */
    private boolean isArray(){
        return (table instanceof Object[]);
    }

    /*
     * Grows the storage from an array to a hashtable.
     */
    private void grow() {
        Object[] array = (Object[])table;
        Hashtable<Object, Object> tmp = new Hashtable<Object, Object>(array.length/2);
        for (int i = 0; i<array.length; i+=2) {
            tmp.put(array[i], array[i+1]);
        }
        table = tmp;
    }

    /*
     * Shrinks the storage from a hashtable to an array.
     */
    private void shrink() {
        Hashtable<?,?> tmp = (Hashtable)table;
        Object[] array = new Object[tmp.size()*2];
        Enumeration<?> keys = tmp.keys();
        int j = 0;

        while (keys.hasMoreElements()) {
            Object o = keys.nextElement();
            array[j] = o;
            array[j+1] = tmp.get(o);
            j+=2;
        }
        table = array;
    }
}
