/*
 * Created on 01/08/2003
 *
 * To change the template for this generated file go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
package sce.list;

/**
 * @author TOSHIBA
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class SListImpl {

	private SNode header;

	private int size = 0;

	public int getSize() {
		return this.size;
	}

	public boolean isEmpty() {
		return( this.size == 0 );
	}

	public SNode insertFirst(Object parObject) {
		SNode toInsert = new SNodeImpl(parObject,this.header.getNext());
		this.header.setNext(toInsert);
		this.size++;
		return toInsert;
	}

	public SNode insertLast(Object parObject) {
		SNode navigator;
		SNode toInsert;
		navigator = this.header.getNext();
		if(navigator==null){
			toInsert = this.insertFirst(parObject);
		}else{
			toInsert = new SNodeImpl(parObject,null);
			while(navigator.getNext()!=null){
				navigator = navigator.getNext();
			}
			navigator.setNext(toInsert);
			this.size++;
		}
		return toInsert;
	}

	public SNode insertAfter(SNode parSNode, Object parObject) {
		SNode toInsert = new SNodeImpl(parObject,null);
		toInsert.setNext(parSNode.getNext());
		parSNode.setNext(toInsert);
		this.size++;	
		return toInsert;
	}

    public SNode insertN(Object parObject,int positionToInsert) {
    	int position = 0;
    	SNode toInsert;
    	SNode navigator=this.header;
    	if(positionToInsert <= 1){
    		toInsert = this.insertFirst(parObject);
    	}else if(positionToInsert > this.size){
			toInsert = this.insertLast(parObject);
    	}else{
			toInsert = new SNodeImpl(parObject,null);
			for(int i=0;i<positionToInsert-1;i++){
				navigator = navigator.getNext();
			}
			toInsert.setNext(navigator.getNext());
			navigator.setNext(toInsert);
			this.size++;
    	}
		return(toInsert);
	}
    
	public Object removeFirst() throws BoundaryException {
        if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node to remove.");
		SNode node = this.header.getNext();
		this.header.setNext(node.getNext());
		node.setNext(null);
		this.size--;
		return node.getContent();
	}

	public Object removeLast() throws BoundaryException {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node to remove.");
		SNode navigator;
		SNode previous = this.header;
		navigator = this.header.getNext();
		while(navigator.getNext()!=null){
			previous = navigator;
			navigator = navigator.getNext();
		}
		previous.setNext(null);
    	this.size--;
		return navigator.getContent();
	}

	public Object removeAfter(SNode parSNode) throws BoundaryException {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node to remove.");
		
		SNode toRemove = parSNode.getNext();
		Object toReturn = null;
		if(toRemove!=null){
			parSNode.setNext(toRemove.getNext());
			this.size--;
			toRemove.setNext(null);
			toReturn = toRemove.getContent();
		}
		return toReturn;
	}

	public Object removeN(int positionToRemove)  throws BoundaryException  {
		int position = 0;
		Object removed;
		SNode toRemove;
		SNode navigator=this.header;
		if(positionToRemove <= 1){
			removed = this.removeFirst();
		}else if(positionToRemove >= this.size){
			removed = this.removeLast();
		}else{
			for(int i=0;i<positionToRemove-1;i++){
				navigator = navigator.getNext();
			}
			toRemove = navigator.getNext();
			navigator.setNext(toRemove.getNext());
			toRemove.setNext(null);
			removed = toRemove.getContent();	
			this.size--;
		}
		return(removed);
	}

	public boolean isFirst(SNode parSNode) throws BoundaryException   {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node.");
		return(this.header.getNext()==parSNode);
	}

	public SNode getFirst() throws BoundaryException   {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node.");
		return (this.header.getNext());
	}

	public SNode getAfter(SNode parSNode) throws BoundaryException   {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node.");
		return parSNode.getNext();
	}

	public SListImpl() {
		this.header = new SNodeImpl(null,null);
		this.size = 0;
	}

}