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

package com.hypixel.hytale.builtin.buildertools.tooloperations;

import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.modules.entity.component.HeadRotation;
import com.hypixel.hytale.component.ComponentAccessor;
import com.hypixel.hytale.protocol.packets.buildertools.BuilderToolOnUseInteraction;
import com.hypixel.hytale.server.core.entity.entities.Player;
import javax.annotation.Nonnull;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.server.core.prefab.selection.mask.BlockPattern;
import com.hypixel.hytale.math.vector.Vector3i;

public class LayersOperation extends ToolOperation
{
    private final Vector3i depthDirection;
    private final int layerOneLength;
    private final int layerTwoLength;
    private final boolean enableLayerTwo;
    private final int layerThreeLength;
    private final boolean enableLayerThree;
    private final BlockPattern layerOneBlockPattern;
    private final BlockPattern layerTwoBlockPattern;
    private final BlockPattern layerThreeBlockPattern;
    private final int brushDensity;
    private final int maxDepthNecessary;
    private boolean failed;
    private final int layerTwoDepthEnd;
    private final int layerThreeDepthEnd;
    private final boolean skipLayerOne;
    private final boolean skipLayerTwo;
    private final boolean skipLayerThree;
    
    public LayersOperation(@Nonnull final Ref<EntityStore> ref, @Nonnull final Player player, @Nonnull final BuilderToolOnUseInteraction packet, @Nonnull final ComponentAccessor<EntityStore> componentAccessor) {
        super(ref, packet, componentAccessor);
        final HeadRotation headRotationComponent = componentAccessor.getComponent(ref, HeadRotation.getComponentType());
        assert headRotationComponent != null;
        final String s = this.args.tool().get("aDirection");
        switch (s) {
            case "Up": {
                this.depthDirection = Vector3i.UP;
                break;
            }
            case "Down": {
                this.depthDirection = Vector3i.DOWN;
                break;
            }
            case "North": {
                this.depthDirection = Vector3i.NORTH;
                break;
            }
            case "South": {
                this.depthDirection = Vector3i.SOUTH;
                break;
            }
            case "East": {
                this.depthDirection = Vector3i.EAST;
                break;
            }
            case "West": {
                this.depthDirection = Vector3i.WEST;
                break;
            }
            case "Camera": {
                this.depthDirection = headRotationComponent.getAxisDirection();
                break;
            }
            default: {
                this.depthDirection = Vector3i.DOWN;
                break;
            }
        }
        this.brushDensity = this.args.tool().get("jBrushDensity");
        this.layerOneLength = this.args.tool().get("bLayerOneLength");
        this.layerTwoLength = this.args.tool().get("eLayerTwoLength");
        this.layerThreeLength = this.args.tool().get("hLayerThreeLength");
        this.layerOneBlockPattern = this.args.tool().get("cLayerOneMaterial");
        this.layerTwoBlockPattern = this.args.tool().get("fLayerTwoMaterial");
        this.layerThreeBlockPattern = this.args.tool().get("iLayerThreeMaterial");
        this.enableLayerTwo = this.args.tool().get("dEnableLayerTwo");
        this.enableLayerThree = this.args.tool().get("gEnableLayerThree");
        this.skipLayerOne = this.args.tool().getOrDefault("kSkipLayerOne", false);
        this.skipLayerTwo = this.args.tool().getOrDefault("lSkipLayerTwo", false);
        this.skipLayerThree = this.args.tool().getOrDefault("mSkipLayerThree", false);
        this.maxDepthNecessary = this.layerOneLength + (this.enableLayerTwo ? this.layerTwoLength : 0) + (this.enableLayerThree ? this.layerThreeLength : 0);
        this.layerTwoDepthEnd = this.layerOneLength + this.layerTwoLength;
        this.layerThreeDepthEnd = this.layerTwoDepthEnd + this.layerThreeLength;
        if (this.enableLayerThree && !this.enableLayerTwo) {
            player.sendMessage(Message.translation("server.builderTools.layerOperation.layerTwoRequired"));
            this.failed = true;
        }
    }
    
    @Override
    boolean execute0(final int x, final int y, final int z) {
        if (this.failed) {
            return false;
        }
        if (this.random.nextInt(100) > this.brushDensity) {
            return true;
        }
        final int currentBlock = this.edit.getBlock(x, y, z);
        if (currentBlock <= 0) {
            return true;
        }
        if (this.depthDirection.x == 1) {
            for (int i = 0; i < this.maxDepthNecessary; ++i) {
                if (this.edit.getBlock(x - i - 1, y, z) <= 0 && this.attemptSetBlock(x, y, z, i)) {
                    return true;
                }
            }
        }
        else if (this.depthDirection.x == -1) {
            for (int i = 0; i < this.maxDepthNecessary; ++i) {
                if (this.edit.getBlock(x + i + 1, y, z) <= 0 && this.attemptSetBlock(x, y, z, i)) {
                    return true;
                }
            }
        }
        else if (this.depthDirection.y == 1) {
            for (int i = 0; i < this.maxDepthNecessary; ++i) {
                if (this.edit.getBlock(x, y - i - 1, z) <= 0 && this.attemptSetBlock(x, y, z, i)) {
                    return true;
                }
            }
        }
        else if (this.depthDirection.y == -1) {
            for (int i = 0; i < this.maxDepthNecessary; ++i) {
                if (this.edit.getBlock(x, y + i + 1, z) <= 0 && this.attemptSetBlock(x, y, z, i)) {
                    return true;
                }
            }
        }
        else if (this.depthDirection.z == 1) {
            for (int i = 0; i < this.maxDepthNecessary; ++i) {
                if (this.edit.getBlock(x, y, z - i - 1) <= 0 && this.attemptSetBlock(x, y, z, i)) {
                    return true;
                }
            }
        }
        else if (this.depthDirection.z == -1) {
            for (int i = 0; i < this.maxDepthNecessary; ++i) {
                if (this.edit.getBlock(x, y, z + i + 1) <= 0 && this.attemptSetBlock(x, y, z, i)) {
                    return true;
                }
            }
        }
        return true;
    }
    
    public boolean attemptSetBlock(final int x, final int y, final int z, final int depth) {
        if (depth < this.layerOneLength) {
            if (!this.skipLayerOne) {
                this.edit.setBlock(x, y, z, this.layerOneBlockPattern.nextBlock(this.random));
            }
            return true;
        }
        if (this.enableLayerTwo && depth < this.layerTwoDepthEnd) {
            if (!this.skipLayerTwo && !this.layerTwoBlockPattern.isEmpty()) {
                this.edit.setBlock(x, y, z, this.layerTwoBlockPattern.nextBlock(this.random));
            }
            return true;
        }
        if (this.enableLayerThree && depth < this.layerThreeDepthEnd) {
            if (!this.skipLayerThree && !this.layerThreeBlockPattern.isEmpty()) {
                this.edit.setBlock(x, y, z, this.layerThreeBlockPattern.nextBlock(this.random));
            }
            return true;
        }
        return false;
    }
}
