/*
 * 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 DListImpl {

	private int size = 0;

	private DNode header;

	private DNode tailer;

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

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

	public DNode insertFirst(DNode parDNode) {
		if(parDNode == null) throw new IllegalArgumentException("Null argument was found.");
		if((parDNode.getNext() != null)||(parDNode.getPrevious() != null)) throw new IllegalArgumentException("A invalid node was found.");
		parDNode.setPrevious(this.header);
		parDNode.setNext(this.header.getNext());
		this.header.getNext().setPrevious(parDNode);
		this.header.setNext(parDNode);
		this.size++;
		return parDNode;
	}

	public DNode insertFirst(Object parObject) {
		DNode toInsert = new DNodeImpl(parObject,null,this.header);
		toInsert.setNext(this.header.getNext());
		this.header.getNext().setPrevious(toInsert);
		this.header.setNext(toInsert);
		this.size++;
		return toInsert;
	}

	public DNode insertLast(Object parObject) {
		DNode toInsert = new DNodeImpl(parObject,this.tailer,null);
		toInsert.setPrevious(this.tailer.getPrevious());
		this.tailer.getPrevious().setNext(toInsert);
		this.tailer.setPrevious(toInsert);
		this.size++;
		return toInsert;
	}

	public DNode insertAfter(DNode parDNode, Object parObject) {
		if(parDNode == null) throw new IllegalArgumentException("Null argument was found.");
		DNode toInsert = new DNodeImpl(parObject,null,parDNode);
		toInsert.setNext(parDNode.getNext());
		parDNode.getNext().setPrevious(toInsert);
		parDNode.setNext(toInsert);
		this.size++;
		return toInsert;
	}

	public DNode insertBefore(DNode parDNode, Object parObject) {
		if(parDNode == null) throw new IllegalArgumentException("Null argument was found.");
		DNode toInsert = new DNodeImpl(parObject,parDNode,null);
		toInsert.setPrevious(parDNode.getPrevious());
		parDNode.getPrevious().setNext(toInsert);
		parDNode.setPrevious(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.");
		DNode 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.");
		DNode toRemove = this.tailer.getPrevious();
		this.tailer.setPrevious(toRemove.getPrevious());
		this.size--;
		toRemove.setNext(null);
		toRemove.setPrevious(null);
		
		return toRemove.getContent();
	}

	public Object removeNode(DNode parDNode) throws BoundaryException {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node to remove.");
		if(parDNode == null) throw new IllegalArgumentException("Null argument was found.");
		DNode previous = parDNode.getPrevious();
		DNode next = parDNode.getNext();
		if(previous!=null){
			previous.setNext(next);
		}
		if(next!=null){
			next.setPrevious(previous);
		}
		parDNode.setNext(null);
		parDNode.setPrevious(null);
		this.size--;
		return parDNode.getContent();
	}

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

	public boolean isLast(DNode parDNode) throws BoundaryException {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node.");
		return(this.tailer.getPrevious()==parDNode);
	}

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

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

	public DNode getLast() throws BoundaryException {
		if(this.isEmpty()) throw new BoundaryException("The list is empty. It doesn't have node.");
		return this.tailer.getPrevious();
	}
	public DListImpl() {
		this.size = 0;
		this.header = new DNodeImpl(null,null,null);
		this.tailer = new DNodeImpl(null,null,this.header);
		this.header.setNext(this.tailer);
	}
}