package com.jscape.util.collections;

import com.jscape.util.ArrayTools;

/**
 * @author Alex Usun
 */
public class CircularLongBuffer {

    private final long[] data;
    private int position;
    private boolean overflow;

    public CircularLongBuffer(int size) {
        this.data = new long[size];
    }

    public void put(long value) {
        this.data[this.position++] = value;
        adjustPosition();
    }

    public LongIterator iterator() {
        return new Iterator(this.data, this.position, this.overflow);
    }

    public int size() {
        return this.data.length;
    }

    public int filled() {
        return this.overflow ? this.data.length : this.position;
    }

    public boolean isEmpty() {
        return filled() == 0;
    }

    public void reset() {
        this.position = 0;
        this.overflow = false;
    }

    @Override
    public String toString() {
        return "CircularLongBuffer {"
                + "data=" + ArrayTools.toString(this.data)
                + ", position=" + this.position
                + ", overflow=" + this.overflow
                + '}';
    }

    private void adjustPosition() {
        if (this.position >= this.data.length) {
            this.position = 0;
            this.overflow = true;
        }
    }

    public static class Iterator
            extends LongArrayIterator {

        private final boolean overflow;
        private int read;

        public Iterator(long[] data, int position, boolean overflow) {
            super(data, overflow ? position : 0, overflow ? data.length : position);
            this.overflow = overflow;
        }

        @Override
        public boolean hasNext() {
            return this.read < this.length;
        }

        @Override
        public long next() {
            long ret = super.next();
            ++this.read;
            adjustPosition();

            return ret;
        }

        @Override
        public void reset() {
            super.reset();
            this.read = 0;
        }

        @Override
        public String toString() {
            return "Iterator {"
                    + "overflow=" + this.overflow
                    + ", read=" + this.read
                    + '}';
        }

        private void adjustPosition() {
            if (this.position >= this.data.length && this.overflow) {
                this.position = 0;
            }
        }

    }


}
