/*
 * @(#)StringSet.java    2.3  7 December 2003
 *
 * Copyright 2004
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.quick;

import java.util.*;

/**
 * <P><CODE>StringSet</CODE> encapsulates a structure that maintains a set
 * of <CODE>String</CODE>s both in the original order of entry and in
 * sorted order.</P>
 *
 * @author  Richard Rasala
 * @version 2.3
 * @since   2.3
 */
public final class StringSet {
    
    /** The string sorted set. */
    private QuickTreeSet stringSet  = new QuickTreeSet();
    
    /** The vector of strings in order. */
    private QuickVector  stringList = new QuickVector();
    
    
    /** The default constructor. */
    public StringSet() { }
    
    
    /**
     * <P>The constructor with an array of strings.</P>
     *
     * @param strings the array of strings
     */
    public StringSet(String[] strings) {
        addStrings(strings);
    }
    
    
    /**
     * <P>Adds the given <CODE>String</CODE> to the <CODE>StringSet</CODE>.</P>
     *
     * <P>The string must be non-<CODE>null</CODE> and must not already be in
     * the set; otherwise does nothing.</P>
     *
     * @param string the string to enter into the set
     */
    public void addString(String string) {
        if(string == null)
            return;
        
        if (contains(string))
            return;
        
        stringSet.add(string);
        stringList.add(string);
    }
    
    
    /**
     * <P>Adds an array of strings to the set.</P>
     *
     * @param strings the array of strings
     */
    public void addStrings(String[] strings) {
        if (strings == null)
            return;
        
        int length = strings.length;
        
        for (int i = 0; i < length; i++)
            addString(strings[i]);
    }
    
    
    /**
     * <P>Clears the set and adds an array of strings to the set.</P>
     *
     * <P>If strings is <CODE>null</CODE>, then only clears.</P>
     *
     * @param strings the array of strings
     */
    public void setStrings(String[] strings) {
        clear();
        addStrings(strings);
    }
    
    
    /**
     * <P>Removes and returns the string corresponding to the given
     * index in order of entry in the set provided that the index
     * is in bounds; otherwise returns <CODE>null</CODE>.</P>
     *
     * @param  index the index of the string
     * @return the string at the given index or null
     */
    public String remove(int index) {
        if ((index < 0) || (index >= size()))
            return null;
        
        String string = getString(index);
        
        stringSet.remove(string);
        stringList.remove(index);
        
        return string;
    }
    
    
    /**
     * <P>Removes and returns the given <CODE>String</CODE> string
     * provided that the string is in the set; otherwise returns
     * <CODE>null</CODE>.</P>
     *
     * @param  string to remove
     * @return the string or null
     */
    public String remove(String string) {
        if (! contains(string))
            return null;
        
        stringSet.remove(string);
        stringList.remove(string);
        
        return string;
    }
    
    
    /**
     * <P>Clear the set of all strings.</P>
     */
    public void clear() {
        stringSet.clear();
        stringList.clear();
    }
    
    
    /**
     * Returns the number of strings in this set.
     *
     * @return the number of strings
     */
    public int size() {
        return stringList.size();
    }
    
    
    /**
     * <P>Returns the <CODE>String</CODE> string at the given index
     * in order of entry into the set; or <CODE>null</CODE> if the
     * index is out of bounds.</P>
     *
     * @param  the index of the string
     * @return the associated string or null
     */
    public String getString(int index) {
        if ((index < 0) || (index >= size()))
            return null;
        
        return (String) stringList.get(index);
    }
    
    
    /**
     * <P>Returns as an array the <CODE>String</CODE>s in this set
     * in order of entry into the set.</P>
     *
     * @return the array of strings in this set
     */
    public String[] getStrings() {
        return (String[]) stringList.toArray(new String[0]);
    }
    
    
    /**
     * <P>Returns as an array the <CODE>String</CODE>s in this set
     * in sorted order.</P>
     *
     * @return the sorted array of strings in this set
     */
    public String[] getSortedStrings() {
        return (String[]) stringSet.toArray(new String[0]);
    }
    
    
    /**
     * Returns <CODE>true</CODE> if this set contains the <CODE>String</CODE>.
     *
     * @param  string the string to test
     * @return whether or not the string is in the set
     */
    public boolean contains(String string) {
        if (string == null)
            return false;
        
        return stringSet.contains(string);
    }
    
}
