package cnrg.itx.ds;

import java.util.*;

/**
 * This class represents a list of locations.
 */
public class LocationList {

	private Element m_head;
	private Element m_tail;
	private Element m_current;
	
	/**
	 * Default constructor
	 */
	public LocationList(){
		m_head = null;
		m_tail = null;
		m_current = null;
	}
	
	/**
	 * Copy constructor
	 * @param newLocationList an input location list object
	 */
	public LocationList(LocationList newLocationList){
		if (newLocationList != null) {
			if (newLocationList.count() > 0) {
				add(newLocationList.first());
				Location tmploc = newLocationList.next();
				while ( tmploc != null ) {
					add(tmploc);
					tmploc = newLocationList.next();
				}
			}
		}
	}
	
	/**
	 * Remove all the elements from the location list object
	 */
	public synchronized void removeAll() {
		m_head = null;
		m_tail = null;
		m_current = null;
	}
	
	/**
	 * Get the number of elements.  Zero implies empty list.
	 * @return number of elements
	 */
	public synchronized int count(){
		int count = 0;
		Element m_tmp = m_head;

		if (m_tmp == null)
			return count;

		count++;
		while (m_tmp != m_tail) {
			count++;
			m_tmp = m_tmp.getNext();
		}
		return count;
	}

	/**
	 * Reset to the first element position
	 */
	public synchronized void reset(){
		m_current = m_head;
	}

	/**
	 * Get the first element (also Reset to the first element position)
	 * @return the first location object in the list
	 */
	public synchronized Location first(){
		reset();
		if (m_current != null)
			return (Location)m_current.getObject();

		return null;
	}

	/**
	 * Get the next element.  Returms NULL if call Next on the last element. <br>
	 * NOTE: To traverse the list from the beginning, call first(), then calling next() to traverse to the end of the list
	 * @return the next location object in the list
	 */
	public synchronized Location next(){
		if (m_current != null && m_current != m_tail) {
			m_current = m_current.getNext();
			return (Location)m_current.getObject();
		}

		return null;
	}

	/**
	 * Add a new element to the end of the list
	 * @param newLocation the new location object to be added to the list
	 */
	public synchronized void add(Location newLocation){
		Element newElement = new Element();
		
		newElement.setObject(newLocation);
		
		if (m_head != null){
			m_tail.setNext(newElement);
			m_tail = m_tail.getNext();
		}
		else {
			m_head = newElement;
			m_tail = newElement;
		}
	}

	/**
	 * Add the given location list to the end of the list
	 * @param newLocationList the new location list to be added to the list
	 */
	public synchronized void add(LocationList newLocationList){
		if (newLocationList != null) {
			Location loc = newLocationList.first();
			while (loc != null) {
				add(loc);
				loc = newLocationList.next();
			}
		}
	}
	
	/**
	 * Get the element at a particular position (zero-based index)
	 * @param index the index of the element to be retrieved
	 * @return the element at the given position.  NULL if the given position is out of range.
	 */
	public synchronized Location getAt(int index) {
		if (index < 0) return null;
		
		int count = 0;
		Element m_tmp = m_head;
		
		while (m_tmp != null) {
			if (count == index)
				break;
			m_tmp = m_tmp.getNext();
			count++;
		}
		
		if (m_tmp != null)
			return (Location)m_tmp.getObject();
		else
			return null;
	}
	
	/**
	 * Delete the existing element from a given position (zero-based index)
	 * @param index the index of the location object to be deleted
	 *
	public synchronized void delete(int index){
	}*/
}
