//---------------------------------
// SortableObject.Java
// Written By: Russell Schwager
//             russells@jhu.edu
// January 29, 1997
//---------------------------------

// Insert Copyright comments

import java.util.Vector;

public class SortableObject
{
	// Creates an initial vector of size
	// (The default constructor creates a vector of size 10)
	// Vectors dynamically allocates memory when needed
	Vector  collection = new Vector(1);
	boolean isSorted;

	public SortableObject(Object object[])
	{ // Constructor - Move all the elements from the array of
	  // objects into the vector.

		for (int i = 0; i < object.length; i++)
			collection.addElement(object[i]);

		isSorted = false;

	}

	// Constructors to handle the primitives
	public SortableObject(int array[])
	{ // Constructor - Move all the elements from the array of
	  // ints into the vector, converting the ints to Integers.

		for (int i = 0; i < array.length; i++)
			collection.addElement(new Integer(array[i]));

		isSorted = false;

	}

	public SortableObject(char array[])
	{ // Constructor - Move all the elements from the array of
	  // chars into the vector, converting the chars to Characters.

		for (int i = 0; i < array.length; i++)
			collection.addElement(new Character(array[i]));

		isSorted = false;

	}

	public SortableObject(float array[])
	{ // Constructor - Move all the elements from the array of
	  // floats into the vector, converting the floats to Floats.

		for (int i = 0; i < array.length; i++)
			collection.addElement(new Float(array[i]));

		isSorted = false;

	}

	public SortableObject(double array[])
	{ // Constructor - Move all the elements from the array of
	  // doubles into the vector, converting the doubles to Doubles.

		for (int i = 0; i < array.length; i++)
			collection.addElement(new Double(array[i]));

		isSorted = false;

	}

	public SortableObject(long array[])
	{ // Constructor - Move all the elements from the array of
	  // longs into the vector, converting the longs to Longs.

		for (int i = 0; i < array.length; i++)
			collection.addElement(new Long(array[i]));

		isSorted = false;

	}

	public void setStatus(boolean status)
	{
		isSorted = status;
	}

	public boolean getStatus()
	{
		return isSorted;
	}

	public String toString(int index)
	{ // Returns a string representing part of the object.  

		return this.at(index).toString();
	}
	
	public String toString()
	{ // Returns a string representing the object.  This method is
	  // defined in the object class.

		String returnString = new String(this.toString(0));
		
		for (int i = 1; i < this.size(); i++)
			returnString = returnString.concat(" " + 
									this.toString(i));

		return returnString;
	}
	
	public int size()
	{
		return collection.size();
	}

	public int numDigits()
	{ // used only for radix-sort

		return ((String)(this.at(1))).length();
	}
	
	public Object compare(int index1, int index2)
	{ // Call the doCompare function that properly handles
	  // the objects in the collection.

		Object objectAtIndex1 = this.at(index1);
		Object objectAtIndex2 = this.at(index2);

		if ((objectAtIndex1 instanceof Number && 
			objectAtIndex2 instanceof Number))
			return doNumberCompare(index1, index2);
		else if ((objectAtIndex1 instanceof String && 
				objectAtIndex2 instanceof String))
				return doStringCompare(index1, index2);
			else if ((objectAtIndex1 instanceof Character && 
					objectAtIndex2 instanceof Character))
					return doCharacterCompare(index1, index2);

		return this.at(index1);
	}

	private Object doNumberCompare(int index1, int index2)
	{ // Returns the max of the two numbers.  This function handles
	  // all types of Number Objects by converting the number to a
	  // Double and then doing the comparison.

		if (((Number)this.at(index1)).doubleValue() >= 
			((Number)this.at(index2)).doubleValue())
			return this.at(index1);

		return this.at(index2);
	}

	private Object doStringCompare(int index1, int index2)
	{ // Returns the string that is lexically greater

		String string1 = (String)this.at(index1);
		String string2 = (String)this.at(index2);

		if (string1.compareTo(string2) > 0)
			return string1;

		return string2;
	
	}

	private Object doStringCompare(int index1, int index2, int digit)
	{ // Returns the string that is lexically greater at the digit
	  // provided

		String string1 = (String)this.at(index1);
		String string2 = (String)this.at(index2);
		char char1 = string1.charAt(digit);
		char char2 = string2.charAt(digit);

		if (char1 >= char2)
			return string1;

		return string2;
	
	}

	private Object doCharacterCompare(int index1, int index2)
	{ // Returns the character that is greater

		Character char1 = (Character)this.at(index1);
		Character char2 = (Character)this.at(index2);

		if (char1.charValue() >= char2.charValue())
			return char1;

		return char2;
	
	}

	public Object at(int index)
	{
		return collection.elementAt(index);
	}

	public void setElementAt(Object value, int index)
	{

		collection.setElementAt(value, index);
	}
	
	public void swap(int index1, int index2)
	{ // Swap two elements in the collection 

		Object tempObject;

		tempObject = this.at(index1);
		collection.setElementAt(this.at(index2), index1);
		collection.setElementAt(tempObject, index2);

	}
}
