/*******************************************************************************
 *  Copyright 2017 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.hl7282.utils;
import java.util.List;
import java.util.Vector;

import cdac.medinfo.sdk.hl7282.commoninterface.ICollectionIterator;
import cdac.medinfo.sdk.hl7282.commoninterface.ISingleCollection;

/**
 * This class provides an abstract mechanism of holding a collection.
 * @param <T> Spcifies type of which singleCollection is formed.
 */
public class SingleCollection <T> implements ISingleCollection<T>
{
	/**
	 * 
	 */
	Vector<T> objVector;

	/**
	 * This constructor creats vector of type T.
	 */
	public SingleCollection()
	{
		objVector = new Vector<T>();
	}

	/**
	 * This constructor creats collection of size iSize.
	 * @param iSize Size of the collection.
	 */
	public SingleCollection(int iSize)
	{
		objVector = new Vector<T>(iSize);
	}

	class CollectionIterator implements ICollectionIterator<T>
	{
		int iIndex = 0;

		/**
		 * Check whether the collection contains more elements.
		 * @return boolean - true if the iteration has more elements.
		 */
		public boolean hasNext()
		{
			if(iIndex != objVector.size())
			{
				return true;
			}
			return false;
		}

		/**
		 * Returns the next element in the iteration
		 * @return T - object specified at the time of instantiation of the implementor class.
		 */
		public T next()
		{
			T objT = objVector.get(iIndex++);
			return objT;
		}

		/**
		 * Removes from the underlying collection the last element returned by the iterator.
		 */	  
		public void remove()
		{
			objVector.remove(iIndex);
		}
	}

	/**
	 * Returns an iterator over the internal collection.
	 * @return ICollectionIterator&lt;T&gt; - 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 object specified at the time of instantiation of the implementor class.
	 * @return boolean - status indicating whether the element is added or not.
	 */
	public boolean add(T objT)
	{
		objVector.add(objT);
		return true;
	}

	/**
	 * Adds any collection into this collection.
	 * @param collection object of any class collection .
	 * @return boolean - true if collection is successfully added .
	 */
	public boolean addAll(List<T> collection)
	{
		objVector.addAll(collection);
		return true;
	}

	/**
	 * Tests if the specified element is peresent in the collection.
	 * @param objT object of the type user specifies at the time of instantiation of this interface.
	 * @return boolean - true if elemnent is present in the collection.
	 */
	public boolean contains(T objT)
	{
		return objVector.contains(objT);
	}

	/**
	 * Returns element at specified index.
	 * @param iIndex the integer indicating the position of the element to be retrieved from the collection.
	 * @return object - object of the type user specifies at the time of instantiation of this interface.
	 */
	public T elementAt(int iIndex)
	{
		return objVector.elementAt(iIndex);
	}


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

	/**
	 * Removes the element at the specified index.
	 * @param objectToRemove position of the element.
	 */
	public void remove(Object objectToRemove)
	{
		if(objVector.contains(objectToRemove))
			objVector.remove(objectToRemove);
	}

	/**
	 * Returns number of elements in the collection.
	 * @return int - number of elements in the collection.
	 */
	public int size()
	{
		return objVector.size();
	}

	/**
	 * Returns true if this collection contains all of the elements in the specified collection otherwise false.
	 * @param objSingleCollection whose elements will be tested for containment in this SingleCollection.
	 * @return true if this SingleCollection contains all of the elements in the specified Collection otherwise false.
	 */
	public boolean containsAll(ISingleCollection<T> objSingleCollection) 
	{
		if(null != objSingleCollection)
		{	
			for (T t : objSingleCollection)
			{
				if(this.contains(t))
					continue;
				else
					return false;
			}
			return true;
		}
		else
		{
			return false;
		}
	}
}
