/*
 * WorldEdit, a Minecraft world manipulation toolkit
 * Copyright (C) sk89q <http://www.sk89q.com>
 * Copyright (C) WorldEdit team and contributors
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

package com.sk89q.worldedit.util.collection;

import com.google.common.collect.AbstractIterator;
import com.sk89q.worldedit.math.BlockVector3;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntList;
import it.unimi.dsi.fastutil.ints.IntListIterator;

import java.util.Iterator;

class VectorPositionList implements PositionList {

    private final IntList delegate = new IntArrayList();

    @Override
    public BlockVector3 get(int index) {
        int ri = index * 3;
        return BlockVector3.at(
            delegate.getInt(ri),
            delegate.getInt(ri + 1),
            delegate.getInt(ri + 2));
    }

    @Override
    public void add(BlockVector3 vector) {
        delegate.add(vector.getX());
        delegate.add(vector.getY());
        delegate.add(vector.getZ());
    }

    @Override
    public int size() {
        return delegate.size();
    }

    @Override
    public void clear() {
        delegate.clear();
    }

    @Override
    public Iterator<BlockVector3> iterator() {
        return new AbstractIterator<BlockVector3>() {

            private final IntIterator iterator = delegate.iterator();

            @Override
            protected BlockVector3 computeNext() {
                if (!iterator.hasNext()) {
                    return endOfData();
                }
                return BlockVector3.at(
                    iterator.nextInt(),
                    iterator.nextInt(),
                    iterator.nextInt());
            }
        };
    }

    @Override
    public Iterator<BlockVector3> reverseIterator() {
        return new AbstractIterator<BlockVector3>() {

            private final IntListIterator iterator = delegate.listIterator(delegate.size());

            @Override
            protected BlockVector3 computeNext() {
                if (!iterator.hasPrevious()) {
                    return endOfData();
                }
                return BlockVector3.at(
                    iterator.previousInt(),
                    iterator.previousInt(),
                    iterator.previousInt());
            }
        };
    }
}
