/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.lists;

import java.util.NoSuchElementException;
import java.util.RandomAccess;
import net.ranides.assira.collection.iterators.IntListIterator;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class IntRange extends AIntList implements RandomAccess {
    
    private static final String E_IMMUTABLE = "Immutable.";
    
    private final int begin;
    
    private final int end;

    public IntRange(int begin, int end) {
        this.begin = begin;
        this.end = end;
    }

    @Override
    public int size() {
        return end - begin;
    }

    @Override
    public void add(int index, int k) {
        throw new UnsupportedOperationException(E_IMMUTABLE);
    }

    @Override
    public void addElements(int index, int[] array, int offset, int length) {
        throw new UnsupportedOperationException(E_IMMUTABLE);
    }

    @Override
    public void getElements(int from, int[] target, int offset, int length) {
        int v = begin+from;
        int n = v + length;
        while(v<n) {
            target[offset++] = v++;
        }
    }

    @Override
    public int getInt(int index) {
		if(index <0 || index>=size()) {
			throw new IndexOutOfBoundsException(index +" out of " + size());
		}
        return begin + index;
    }

    @Override
    public IntListIterator listIterator(int index) {
        return new IntRangeIterator(index);
    }

    @Override
    public int removeInt(int index) {
        throw new UnsupportedOperationException(E_IMMUTABLE);
    }

    @Override
    public int set(int index, int k) {
        throw new UnsupportedOperationException(E_IMMUTABLE);
    }

    private class IntRangeIterator implements IntListIterator {
        
        private int current;

        public IntRangeIterator(int index) {
            this.current = begin + index;
        }

        @Override
        public boolean hasNext() {
            return current<end;
        }

        @Override
        public int nextInt() {
			if(hasNext()) {
				return current++;
			}
			throw new NoSuchElementException();
        }

        @Override
        public boolean hasPrevious() {
            return current>begin;
        }

        @Override
        public int previousInt() {
			if(hasPrevious()) {
				return --current;
			}
            throw new NoSuchElementException();
        }

        @Override
        public int nextIndex() {
            return current-begin;
        }

        @Override
        public int previousIndex() {
            return current-begin-1;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException(E_IMMUTABLE);
        }

        @Override
        public void set(int e) {
            throw new UnsupportedOperationException(E_IMMUTABLE);
        }

        @Override
        public void add(int e) {
            throw new UnsupportedOperationException(E_IMMUTABLE);
        }
    }
        
}
