/*******************************************************************************
 *  Copyright 2017-2018 Centre for Development of Advanced Computing(C-DAC), Pune
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *   http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package cdac.medinfo.sdk.dcm30_04.utils;
import java.lang.reflect.Array;
import java.util.Vector;

/*
 * Added elementAt method implementation
 */
/**
 * This class provides an abstract mechanism of holding a collection
 * @param <T> object object of the type user specifies at the time of instantiation of this interface 
 */
public class SingleCollection<T> implements ISingleCollection<T>
{
	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 1L;

	Vector<T> objVector = null;

	/**
	 * Construct instance of SingleCollection
	 */
	public SingleCollection()
	{
		objVector = new Vector<T>();
	}

	/**
	 * An CollectionIterator for collection that allows the programmer to traverse the collection in either direction, 
	 * modify the collection during iteration. 
	 */
	public class CollectionIterator implements ICollectionIterator<T>
	{
		/**
		 * serialVersionUID
		 */
		private static final long serialVersionUID = 1L;
		int index = 0;

		/**
		 * Constructs CollectionIterator for underlying collection
		 */
		public CollectionIterator()
		{

		}

		/**
		 * This method gives the status whether collection contains more element.
		 * @return boolean - status as success or failure.
		 */
		public boolean hasNext()
		{
			if(index != objVector.size())
			{
				return true;
			}
			return false;
		}

		/**
		 * This method gives the next element from collection.
		 * @return T - generic type object.
		 */
		public T next()
		{
			T objT = objVector.get(index++);
			return objT;
		}

		/**
		 * This method removes the current element from collection.
		 */
		public void remove()
		{
			objVector.remove(index);
		}
	}

	/**
	 * This method returns an iterator over the internal collection
	 * @return iterator - returns the iterator over the internal collection
	 */
	public ICollectionIterator<T> iterator()
	{
		return new CollectionIterator();
	}

	/**
	 * This method provides a mechanism for adding an elemtn to the collection
	 * @param objT  the element to insert. 
	 * @return boolean - status indicating whether the element is added or not
	 */
	public boolean add(T objT)
	{
		objVector.add(objT);
		return true;
	}

	/**
	 * This method returns the status indicating whether the element is present in the collection or not
	 * @param objT  the element to insert. 
	 * @return boolean - returns the status indicating whether the element is present in the collection or not
	 */
	public boolean contains(T objT)
	{
		return objVector.contains(objT);
	}

	/**
	 * This method provides index based accessing over the internal collection
	 * @param index This parameter specifies the index of the element to be retrieved 
	 * @return T - object of the type user specifies at the time of instantiation of this interface
	 */
	public T get(int index)
	{
		return objVector.get(index);
	}

	/**
	 * This method returns the size of the collection
	 * @return size - returns the size of the collection
	 */
	public int size()
	{
		return objVector.size();
	}

	/**
	 * The implementation of this method checks that either collection is null or empty.
	 */
	public boolean isEmpty()
	{
		if(objVector.size() != 0)
			return false;
		return true;
	}

	/**
	 * This method returns the element at the index from the collection specified by the user
	 * @param index index specifying the position of the element in the collection
	 * @return T - object retrieved from the collection
	 */
	public T elementAt(int index)
	{
		return objVector.elementAt(index);
	}

	/**
	 * This method returns array of the objects in the collection 
	 * @return T[] - array of objects present in the collection
	 */
	@SuppressWarnings("unchecked")
	public T[] toArray()
	{
		if(objVector.size() != 0)
		{
			T obj = objVector.firstElement();
			T[] objT = (T[])Array.newInstance(obj.getClass(), objVector.size());
			return objVector.toArray(objT);
		}
		return null;
	}

	/**
	 * Removes the element at the specified index.
	 * @param iIndex - position of the element.
	 */
	public void remove(int iIndex)
	{
		objVector.remove(iIndex);
	}

	/**
	 * Removes the element specified from the collection.
	 * @param objT - element to be removed.
	 */
	public void remove(T objT)
	{
		objVector.remove(objT);
	}
	
	/**
	 * Removes all of the elements from this SingleCollection.
	 * The SingleCollection will be empty after this call returns (unless it throws an exception). 
	 */
	public void clear()
	{
		objVector.clear();
	}
}
