/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  com.mojang.brigadier.ImmutableStringReader
 *  com.mojang.brigadier.Message
 *  com.mojang.brigadier.StringReader
 *  com.mojang.brigadier.arguments.ArgumentType
 *  com.mojang.brigadier.context.CommandContext
 *  com.mojang.brigadier.exceptions.CommandSyntaxException
 *  com.mojang.brigadier.exceptions.SimpleCommandExceptionType
 *  com.mojang.brigadier.suggestion.Suggestions
 *  com.mojang.brigadier.suggestion.SuggestionsBuilder
 *  net.minecraft.class_1297
 *  net.minecraft.class_1923
 *  net.minecraft.class_1937
 *  net.minecraft.class_2170
 *  net.minecraft.class_2172
 *  net.minecraft.class_2172$class_2173
 *  net.minecraft.class_2183$class_2184
 *  net.minecraft.class_2277
 *  net.minecraft.class_2278
 *  net.minecraft.class_2338
 *  net.minecraft.class_2374
 *  net.minecraft.class_241
 *  net.minecraft.class_243
 *  net.minecraft.class_2561
 *  net.minecraft.class_3532
 *  net.minecraft.class_638
 */
package meteordevelopment.meteorclient.commands.arguments;

import com.mojang.brigadier.ImmutableStringReader;
import com.mojang.brigadier.Message;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import meteordevelopment.meteorclient.MeteorClient;
import net.minecraft.class_1297;
import net.minecraft.class_1923;
import net.minecraft.class_1937;
import net.minecraft.class_2170;
import net.minecraft.class_2172;
import net.minecraft.class_2183;
import net.minecraft.class_2277;
import net.minecraft.class_2278;
import net.minecraft.class_2338;
import net.minecraft.class_2374;
import net.minecraft.class_241;
import net.minecraft.class_243;
import net.minecraft.class_2561;
import net.minecraft.class_3532;
import net.minecraft.class_638;

public class BlockPosArgumentType
implements ArgumentType<PosArgument> {
    private static final BlockPosArgumentType INSTANCE = new BlockPosArgumentType();
    private static final Collection<String> EXAMPLES = Arrays.asList("0 0 0", "~ ~ ~", "^ ^ ^", "^1 ^ ^-5", "~0.5 ~1 ~-5");
    public static final SimpleCommandExceptionType UNLOADED_EXCEPTION = new SimpleCommandExceptionType((Message)class_2561.method_43471((String)"argument.pos.unloaded"));
    public static final SimpleCommandExceptionType OUT_OF_WORLD_EXCEPTION = new SimpleCommandExceptionType((Message)class_2561.method_43471((String)"argument.pos.outofworld"));
    public static final SimpleCommandExceptionType OUT_OF_BOUNDS_EXCEPTION = new SimpleCommandExceptionType((Message)class_2561.method_43471((String)"argument.pos.outofbounds"));

    private BlockPosArgumentType() {
    }

    public static BlockPosArgumentType blockPos() {
        return INSTANCE;
    }

    public static <S> class_2338 getLoadedBlockPos(CommandContext<S> context, String name) throws CommandSyntaxException {
        class_638 clientLevel = MeteorClient.mc.field_1687;
        return BlockPosArgumentType.getLoadedBlockPos(context, clientLevel, name);
    }

    public static <S> class_2338 getLoadedBlockPos(CommandContext<S> context, class_638 level, String name) throws CommandSyntaxException {
        class_2338 blockPos = BlockPosArgumentType.getBlockPos(context, name);
        class_1923 chunkPos = new class_1923(blockPos);
        if (!level.method_2935().method_12123(chunkPos.field_9181, chunkPos.field_9180)) {
            throw UNLOADED_EXCEPTION.create();
        }
        if (!level.method_24794(blockPos)) {
            throw OUT_OF_WORLD_EXCEPTION.create();
        }
        return blockPos;
    }

    public static <S> class_2338 getBlockPos(CommandContext<S> context, String name) {
        return ((PosArgument)context.getArgument(name, PosArgument.class)).getBlockPos(context.getSource());
    }

    public static <S> class_2338 getValidBlockPos(CommandContext<S> context, String name) throws CommandSyntaxException {
        class_2338 blockPos = BlockPosArgumentType.getBlockPos(context, name);
        if (!class_1937.method_25953((class_2338)blockPos)) {
            throw OUT_OF_BOUNDS_EXCEPTION.create();
        }
        return blockPos;
    }

    public PosArgument parse(StringReader stringReader) throws CommandSyntaxException {
        return stringReader.canRead() && stringReader.peek() == '^' ? LookingPosArgument.parse(stringReader) : DefaultPosArgument.parse(stringReader);
    }

    public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder) {
        if (!(context.getSource() instanceof class_2172)) {
            return Suggestions.empty();
        }
        String string = builder.getRemaining();
        Set<class_2172.class_2173> collection = !string.isEmpty() && string.charAt(0) == '^' ? Collections.singleton(class_2172.class_2173.field_9834) : ((class_2172)context.getSource()).method_17771();
        return class_2172.method_9260((String)string, collection, (SuggestionsBuilder)builder, (Predicate)class_2170.method_9238(this::parse));
    }

    public Collection<String> getExamples() {
        return EXAMPLES;
    }

    public static interface PosArgument {
        public <S> class_243 getPosition(S var1);

        public <S> class_241 getRotation(S var1);

        default public <S> class_2338 getBlockPos(S source) {
            return class_2338.method_49638((class_2374)this.getPosition(source));
        }

        public boolean isXRelative();

        public boolean isYRelative();

        public boolean isZRelative();
    }

    public static class LookingPosArgument
    implements PosArgument {
        private final double x;
        private final double y;
        private final double z;

        public LookingPosArgument(double x, double y, double z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        @Override
        public <S> class_243 getPosition(S source) {
            class_241 vec2 = MeteorClient.mc.field_1724.method_5802();
            class_243 vec3 = class_2183.class_2184.field_9853.method_9302((class_1297)MeteorClient.mc.field_1724);
            float f = class_3532.method_15362((double)((vec2.field_1342 + 90.0f) * ((float)Math.PI / 180)));
            float g = class_3532.method_15374((double)((vec2.field_1342 + 90.0f) * ((float)Math.PI / 180)));
            float h = class_3532.method_15362((double)(-vec2.field_1343 * ((float)Math.PI / 180)));
            float i = class_3532.method_15374((double)(-vec2.field_1343 * ((float)Math.PI / 180)));
            float j = class_3532.method_15362((double)((-vec2.field_1343 + 90.0f) * ((float)Math.PI / 180)));
            float k = class_3532.method_15374((double)((-vec2.field_1343 + 90.0f) * ((float)Math.PI / 180)));
            class_243 vec32 = new class_243((double)(f * h), (double)i, (double)(g * h));
            class_243 vec33 = new class_243((double)(f * j), (double)k, (double)(g * j));
            class_243 vec34 = vec32.method_1036(vec33).method_1021(-1.0);
            double d = vec32.field_1352 * this.z + vec33.field_1352 * this.y + vec34.field_1352 * this.x;
            double e = vec32.field_1351 * this.z + vec33.field_1351 * this.y + vec34.field_1351 * this.x;
            double l = vec32.field_1350 * this.z + vec33.field_1350 * this.y + vec34.field_1350 * this.x;
            return new class_243(vec3.field_1352 + d, vec3.field_1351 + e, vec3.field_1350 + l);
        }

        @Override
        public <S> class_241 getRotation(S source) {
            return class_241.field_1340;
        }

        @Override
        public boolean isXRelative() {
            return true;
        }

        @Override
        public boolean isYRelative() {
            return true;
        }

        @Override
        public boolean isZRelative() {
            return true;
        }

        public static LookingPosArgument parse(StringReader reader) throws CommandSyntaxException {
            int cursor = reader.getCursor();
            double d = LookingPosArgument.readCoordinate(reader, cursor);
            if (!reader.canRead() || reader.peek() != ' ') {
                reader.setCursor(cursor);
                throw class_2277.field_10755.createWithContext((ImmutableStringReader)reader);
            }
            reader.skip();
            double e = LookingPosArgument.readCoordinate(reader, cursor);
            if (!reader.canRead() || reader.peek() != ' ') {
                reader.setCursor(cursor);
                throw class_2277.field_10755.createWithContext((ImmutableStringReader)reader);
            }
            reader.skip();
            double f = LookingPosArgument.readCoordinate(reader, cursor);
            return new LookingPosArgument(d, e, f);
        }

        private static double readCoordinate(StringReader reader, int startingCursorPos) throws CommandSyntaxException {
            if (!reader.canRead()) {
                throw class_2278.field_10759.createWithContext((ImmutableStringReader)reader);
            }
            if (reader.peek() != '^') {
                reader.setCursor(startingCursorPos);
                throw class_2277.field_10757.createWithContext((ImmutableStringReader)reader);
            }
            reader.skip();
            return reader.canRead() && reader.peek() != ' ' ? reader.readDouble() : 0.0;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof LookingPosArgument)) {
                return false;
            }
            LookingPosArgument lookingPosArgument = (LookingPosArgument)o;
            return this.x == lookingPosArgument.x && this.y == lookingPosArgument.y && this.z == lookingPosArgument.z;
        }

        public int hashCode() {
            return Objects.hash(this.x, this.y, this.z);
        }
    }

    public static class DefaultPosArgument
    implements PosArgument {
        private final class_2278 x;
        private final class_2278 y;
        private final class_2278 z;

        public DefaultPosArgument(class_2278 x, class_2278 y, class_2278 z) {
            this.x = x;
            this.y = y;
            this.z = z;
        }

        @Override
        public <S> class_243 getPosition(S source) {
            class_243 vec3 = MeteorClient.mc.field_1724.method_73189();
            return new class_243(this.x.method_9740(vec3.field_1352), this.y.method_9740(vec3.field_1351), this.z.method_9740(vec3.field_1350));
        }

        @Override
        public <S> class_241 getRotation(S source) {
            class_241 vec2 = MeteorClient.mc.field_1724.method_5802();
            return new class_241((float)this.x.method_9740((double)vec2.field_1343), (float)this.y.method_9740((double)vec2.field_1342));
        }

        @Override
        public boolean isXRelative() {
            return this.x.method_9741();
        }

        @Override
        public boolean isYRelative() {
            return this.y.method_9741();
        }

        @Override
        public boolean isZRelative() {
            return this.z.method_9741();
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof DefaultPosArgument)) {
                return false;
            }
            DefaultPosArgument defaultPosArgument = (DefaultPosArgument)o;
            return this.x.equals((Object)defaultPosArgument.x) && this.y.equals((Object)defaultPosArgument.y) && this.z.equals((Object)defaultPosArgument.z);
        }

        public static DefaultPosArgument parse(StringReader reader) throws CommandSyntaxException {
            int cursor = reader.getCursor();
            class_2278 worldCoordinate = class_2278.method_9739((StringReader)reader);
            if (reader.canRead() && reader.peek() == ' ') {
                reader.skip();
                class_2278 worldCoordinate2 = class_2278.method_9739((StringReader)reader);
                if (reader.canRead() && reader.peek() == ' ') {
                    reader.skip();
                    class_2278 worldCoordinate3 = class_2278.method_9739((StringReader)reader);
                    return new DefaultPosArgument(worldCoordinate, worldCoordinate2, worldCoordinate3);
                }
            }
            reader.setCursor(cursor);
            throw class_2277.field_10755.createWithContext((ImmutableStringReader)reader);
        }

        public static DefaultPosArgument parse(StringReader reader, boolean centerIntegers) throws CommandSyntaxException {
            int cursor = reader.getCursor();
            class_2278 worldCoordinate = class_2278.method_9743((StringReader)reader, (boolean)centerIntegers);
            if (reader.canRead() && reader.peek() == ' ') {
                reader.skip();
                class_2278 worldCoordinate2 = class_2278.method_9743((StringReader)reader, (boolean)false);
                if (reader.canRead() && reader.peek() == ' ') {
                    reader.skip();
                    class_2278 worldCoordinate3 = class_2278.method_9743((StringReader)reader, (boolean)centerIntegers);
                    return new DefaultPosArgument(worldCoordinate, worldCoordinate2, worldCoordinate3);
                }
            }
            reader.setCursor(cursor);
            throw class_2277.field_10755.createWithContext((ImmutableStringReader)reader);
        }

        public static DefaultPosArgument absolute(double x, double y, double z) {
            return new DefaultPosArgument(new class_2278(false, x), new class_2278(false, y), new class_2278(false, z));
        }

        public static DefaultPosArgument absolute(class_241 vec) {
            return new DefaultPosArgument(new class_2278(false, (double)vec.field_1343), new class_2278(false, (double)vec.field_1342), new class_2278(true, 0.0));
        }

        public static DefaultPosArgument current() {
            return new DefaultPosArgument(new class_2278(true, 0.0), new class_2278(true, 0.0), new class_2278(true, 0.0));
        }

        public int hashCode() {
            int i = this.x.hashCode();
            i = 31 * i + this.y.hashCode();
            return 31 * i + this.z.hashCode();
        }
    }
}

