// 
// Decompiled by Procyon v0.6.0
// 

package com.hypixel.hytale.builtin.hytalegenerator.newsystem.views;

import com.hypixel.hytale.builtin.hytalegenerator.datastructures.voxelspace.VoxelConsumer;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import com.hypixel.hytale.builtin.hytalegenerator.newsystem.bufferbundle.buffers.NVoxelBuffer;
import com.hypixel.hytale.builtin.hytalegenerator.newsystem.GridUtils;
import javax.annotation.Nonnull;
import com.hypixel.hytale.math.vector.Vector3i;
import com.hypixel.hytale.builtin.hytalegenerator.bounds.Bounds3i;
import com.hypixel.hytale.builtin.hytalegenerator.newsystem.bufferbundle.NBufferBundle;
import com.hypixel.hytale.builtin.hytalegenerator.datastructures.voxelspace.VoxelSpace;

public class NVoxelBufferView<T> implements VoxelSpace<T>
{
    private final Class<T> voxelType;
    private final NBufferBundle.Access.View bufferAccess;
    private final Bounds3i bounds_voxelGrid;
    private final Vector3i size_voxelGrid;
    
    public NVoxelBufferView(@Nonnull final NBufferBundle.Access.View bufferAccess, @Nonnull final Class<T> voxelType) {
        this.bufferAccess = bufferAccess;
        this.voxelType = voxelType;
        GridUtils.toVoxelGrid_fromBufferGrid(this.bounds_voxelGrid = bufferAccess.getBounds_bufferGrid());
        this.size_voxelGrid = this.bounds_voxelGrid.getSize();
    }
    
    public void copyFrom(@Nonnull final NVoxelBufferView<T> source) {
        assert source.bounds_voxelGrid.contains(this.bounds_voxelGrid);
        final Bounds3i thisBounds_bufferGrid = this.bufferAccess.getBounds_bufferGrid();
        final Vector3i pos_bufferGrid = new Vector3i();
        pos_bufferGrid.setX(thisBounds_bufferGrid.min.x);
        while (pos_bufferGrid.x < thisBounds_bufferGrid.max.x) {
            pos_bufferGrid.setY(thisBounds_bufferGrid.min.y);
            while (pos_bufferGrid.y < thisBounds_bufferGrid.max.y) {
                pos_bufferGrid.setZ(thisBounds_bufferGrid.min.z);
                while (pos_bufferGrid.z < thisBounds_bufferGrid.max.z) {
                    final NVoxelBuffer<T> sourceBuffer = source.getBuffer_fromBufferGrid(pos_bufferGrid);
                    final NVoxelBuffer<T> destinationBuffer = this.getBuffer_fromBufferGrid(pos_bufferGrid);
                    destinationBuffer.reference(sourceBuffer);
                    pos_bufferGrid.setZ(pos_bufferGrid.z + 1);
                }
                pos_bufferGrid.setY(pos_bufferGrid.y + 1);
            }
            pos_bufferGrid.setX(pos_bufferGrid.x + 1);
        }
    }
    
    @Override
    public boolean set(final T content, final int x, final int y, final int z) {
        return this.set(content, new Vector3i(x, y, z));
    }
    
    @Override
    public boolean set(final T content, @Nonnull final Vector3i position_voxelGrid) {
        assert this.bounds_voxelGrid.contains(position_voxelGrid);
        final NVoxelBuffer<T> buffer = this.getBuffer_fromVoxelGrid(position_voxelGrid);
        final Vector3i positionInBuffer_voxelGrid = position_voxelGrid.clone();
        GridUtils.toVoxelGridInsideBuffer_fromWorldGrid(positionInBuffer_voxelGrid);
        buffer.setVoxelContent(positionInBuffer_voxelGrid, content);
        return true;
    }
    
    @Override
    public void set(final T content) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public void setOrigin(final int x, final int y, final int z) {
        throw new UnsupportedOperationException();
    }
    
    @Nullable
    @Override
    public T getContent(final int x, final int y, final int z) {
        return this.getContent(new Vector3i(x, y, z));
    }
    
    @Nullable
    @Override
    public T getContent(@Nonnull final Vector3i position_voxelGrid) {
        assert this.bounds_voxelGrid.contains(position_voxelGrid);
        final NVoxelBuffer<T> buffer = this.getBuffer_fromVoxelGrid(position_voxelGrid);
        final Vector3i positionInBuffer_voxelGrid = position_voxelGrid.clone();
        GridUtils.toVoxelGridInsideBuffer_fromWorldGrid(positionInBuffer_voxelGrid);
        return buffer.getVoxelContent(positionInBuffer_voxelGrid);
    }
    
    @Override
    public boolean replace(final T replacement, final int x, final int y, final int z, @Nonnull final Predicate<T> mask) {
        return false;
    }
    
    @Override
    public void pasteFrom(@Nonnull final VoxelSpace<T> source) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public int getOriginX() {
        return 0;
    }
    
    @Override
    public int getOriginY() {
        return 0;
    }
    
    @Override
    public int getOriginZ() {
        return 0;
    }
    
    @Override
    public String getName() {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public boolean isInsideSpace(final int x, final int y, final int z) {
        return this.isInsideSpace(new Vector3i(x, y, z));
    }
    
    @Override
    public boolean isInsideSpace(@Nonnull final Vector3i position) {
        return this.bounds_voxelGrid.contains(position);
    }
    
    @Override
    public void forEach(final VoxelConsumer<? super T> action) {
        throw new UnsupportedOperationException();
    }
    
    @Override
    public int minX() {
        return this.bounds_voxelGrid.min.x;
    }
    
    @Override
    public int maxX() {
        return this.bounds_voxelGrid.max.x;
    }
    
    @Override
    public int minY() {
        return this.bounds_voxelGrid.min.y;
    }
    
    @Override
    public int maxY() {
        return this.bounds_voxelGrid.max.y;
    }
    
    @Override
    public int minZ() {
        return this.bounds_voxelGrid.min.z;
    }
    
    @Override
    public int maxZ() {
        return this.bounds_voxelGrid.max.z;
    }
    
    @Override
    public int sizeX() {
        return this.size_voxelGrid.x;
    }
    
    @Override
    public int sizeY() {
        return this.size_voxelGrid.y;
    }
    
    @Override
    public int sizeZ() {
        return this.size_voxelGrid.z;
    }
    
    @Nonnull
    private NVoxelBuffer<T> getBuffer_fromVoxelGrid(@Nonnull final Vector3i position_voxelGrid) {
        final Vector3i localBufferPosition_bufferGrid = position_voxelGrid.clone();
        GridUtils.toBufferGrid_fromVoxelGrid(localBufferPosition_bufferGrid);
        return this.getBuffer_fromBufferGrid(localBufferPosition_bufferGrid);
    }
    
    @Nonnull
    private NVoxelBuffer<T> getBuffer_fromBufferGrid(@Nonnull final Vector3i position_bufferGrid) {
        return (NVoxelBuffer)this.bufferAccess.getBuffer(position_bufferGrid).buffer();
    }
}
