/*******************************************************************************
 * Copyright (c) 2011 Jesper Moller, and others
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Jesper Moller - initial API and implementation
 *     Jesper Steen Moller  - bug 340933 - Migrate to new XPath2 API
 *******************************************************************************/

package org.eclipse.wst.xml.xpath2.api;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.ListIterator;

import org.eclipse.wst.xml.xpath2.api.typesystem.ItemType;
import org.eclipse.wst.xml.xpath2.processor.internal.types.SimpleAtomicItemTypeImpl;
import org.eclipse.wst.xml.xpath2.processor.internal.types.builtin.BuiltinTypeLibrary;
import org.eclipse.wst.xml.xpath2.processor.internal.types.builtin.SingleItemSequence;

/**
 * @since 2.0
 */
public class ResultBuffer {

	private ArrayList<Item> values = new ArrayList<Item>();
	
	public ResultSequence getSequence() {
		if (values.size() == 0) return EMPTY;
		if (values.size() == 1) return wrap(values.get(0));
		
		return new ArrayResultSequence(values.toArray(new Item[values.size()]));
	}
	
	public void clear() {
		values.clear();
	}
	
	public ResultBuffer add(Item at) {
		values.add(at);
		return this;
	}

	public ResultBuffer append(Item at) {
		values.add(at);
		return this;
	}

	public ResultBuffer concat(ResultSequence rs) {
		values.addAll(collectionWrapper(rs));
		return this;
	}

	public static final class SingleResultSequence implements ResultSequence {
		
		public SingleResultSequence(Item at) {
			value = at;
		}
		
		private final Item value;
	
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#getLength()
		 */
		public int size() {
			return 1;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#getItem(int)
		 */
		public Item item(int index) {
			if (index != 0) throw new IndexOutOfBoundsException("Length is one, you looked up number "+ index);
			return value;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#first()
		 */
		public Item first() {
			return item(0);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#getItem(int)
		 */
		public Object value(int index) {
			if (index != 0) throw new IndexOutOfBoundsException("Length is one, you looked up number "+ index);
			return value.getNativeValue();
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#empty()
		 */
		public boolean empty() {
			return false;
		}
	
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#first()
		 */
		public Object firstValue() {
			return value.getNativeValue();
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#iterator()
		 */
		public Iterator iterator() {
			return new Iterator() {
				boolean seenIt = false;
				
				public final void remove() {
					throw new UnsupportedOperationException("ResultSequences are immutable");
				}
				
				public final Object next() {
					if (! seenIt) {
						seenIt = true;
						return value;
					}
					throw new IllegalStateException("This iterator is at its end");
				}
				
				public final boolean hasNext() {
					return !seenIt;
				}
			};
		}

		public ItemType itemType(int index) {
			return item(index).getItemType();
		}
		
		public ItemType sequenceType() {
			return value.getItemType();
		}
	}

	public static final class ArrayResultSequence implements ResultSequence {
		
		private final Item[] results;
	
		public ArrayResultSequence(Item results[]) {
			this.results = results;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#getLength()
		 */
		public int size() {
			return results.length;
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#getItem(int)
		 */
		public Item item(int index) {
			if (index < 0 && index >= results.length) throw new IndexOutOfBoundsException("Index " + index + " is out of alllowed bounds (less that " + results.length);
			return results[index];
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#empty()
		 */
		public boolean empty() {
			return false;
		}
	
		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#first()
		 */
		public Object firstValue() {
			return item(0).getNativeValue();
		}

		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#first()
		 */
		public Item first() {
			return item(0);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.wst.xml.xpath2.api.ResultSequence#iterator()
		 */
		public Iterator iterator() {
			return new Iterator() {
				int nextIndex = 0;
				
				public final void remove() {
					throw new UnsupportedOperationException("ResultSequences are immutable");
				}
				
				public final Object next() {
					if (nextIndex < results.length) {
						return results[nextIndex++];
					}
					throw new IllegalStateException("This iterator is at its end");
				}
				
				public final boolean hasNext() {
					return nextIndex < results.length;
				}
			};
		}

		public ItemType itemType(int index) {
			if (index < 0 && index >= results.length) throw new IndexOutOfBoundsException("Index " + index + " is out of alllowed bounds (less that " + results.length);
			return results[index].getItemType();
		}

		public ItemType sequenceType() {
			return new SimpleAtomicItemTypeImpl(BuiltinTypeLibrary.XS_ANYTYPE, ItemType.OCCURRENCE_ONE_OR_MANY);
		}

		public Object value(int index) {
			return item(index).getNativeValue();
		}
	}

	public int size() {
		return values.size();
	}

	public ListIterator iterator() {
		return values.listIterator();
	}

	public void prepend(ResultSequence rs) {
		values.addAll(0, collectionWrapper(rs));
	}

	private Collection<Item> collectionWrapper(final ResultSequence rs) {
		// This is a dummy collections, solely exists for faster inserts into our array
		return new Collection<Item>() {

			public boolean add(Item arg0) {
				return false;
			}

			public boolean addAll(Collection arg0) {
				return false;
			}

			public void clear() {
			}

			public boolean contains(Object arg0) {
				return false;
			}

			public boolean containsAll(Collection arg0) {
				return false;
			}

			public boolean isEmpty() {
				return rs.empty();
			}

			public Iterator/*<Item>*/ iterator() {
				return rs.iterator();
			}

			public boolean remove(Object arg0) {
				return false;
			}

			public boolean removeAll(Collection arg0) {
				return false;
			}

			public boolean retainAll(Collection arg0) {
				return false;
			}

			public int size() {
				return rs.size();
			}

			public Object[] toArray() {
				return toArray(new Item[size()]);
			}

			public Object[] toArray(Object[] arg0) {
				if (arg0.length < size())
					arg0 = new Item[size()];
				for (int i = 0; i< size(); ++i) {
					arg0[i] = rs.item(i);
				}
				return arg0;
			}
		};
	}
	
	public final static ResultSequence EMPTY = new ResultSequence() {

		public int size() {
			return 0;
		}

		public Item item(int index) {
			throw new IndexOutOfBoundsException("Sequence is empty!");
		}

		public boolean empty() {
			return true;
		}
		
		public ItemType itemType(int index) {
			throw new IndexOutOfBoundsException("Sequence is empty!");
		}
		
		public ItemType sequenceType() {
			return new SimpleAtomicItemTypeImpl(BuiltinTypeLibrary.XS_ANYTYPE, ItemType.OCCURRENCE_ONE_OR_MANY);
		}
		
		public Object value(int index) {
			throw new IndexOutOfBoundsException("Sequence is empty!");
		}
		
		public Object firstValue() {
			throw new IndexOutOfBoundsException("Sequence is empty!");
		}

		public Item first() {
			throw new IndexOutOfBoundsException("Sequence is empty!");
		}
		
		public Iterator iterator() {
			return new Iterator() {
				
				public void remove() {
					throw new UnsupportedOperationException("ResultSequences are immutable");
				}
				
				public Object next() {
					throw new IllegalStateException("This ResultSequence is empty");
				}
				
				public boolean hasNext() {
					return false;
				}
			};
		}
	};

	public Collection<Item> getCollection() {
		return this.values;
	}

	public ResultBuffer concat(Collection/*<Item>*/ others) {
		this.values.addAll(others);
		return this;
	}

	public static ResultSequence wrap(Item item) {
		if (item instanceof SingleItemSequence)
			return (SingleItemSequence)item;
		
		return new SingleResultSequence(item); 
	}

	public Item item(int index) {
		return values.get(index);
	}

	public void addAt(int pos, Item element) {
		values.add(pos, element);
	}
}
