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

package com.hypixel.hytale.builtin.hytalegenerator.patterns;

import com.hypixel.hytale.codec.codecs.EnumCodec;
import com.hypixel.hytale.codec.Codec;
import java.util.Iterator;
import com.hypixel.hytale.math.vector.Vector3i;
import java.util.Collection;
import java.util.ArrayList;
import com.hypixel.hytale.builtin.hytalegenerator.bounds.SpaceSize;
import java.util.List;
import javax.annotation.Nonnull;

public class WallPattern extends Pattern
{
    @Nonnull
    private final Pattern wallPattern;
    @Nonnull
    private final Pattern originPattern;
    @Nonnull
    private final List<WallDirection> directions;
    private final boolean matchAll;
    private final SpaceSize readSpaceSize;
    
    public WallPattern(@Nonnull final Pattern wallPattern, @Nonnull final Pattern originPattern, @Nonnull final List<WallDirection> wallDirections, final boolean matchAll) {
        this.wallPattern = wallPattern;
        this.originPattern = originPattern;
        this.directions = new ArrayList<WallDirection>(wallDirections);
        this.matchAll = matchAll;
        final SpaceSize originSpace = originPattern.readSpace();
        final SpaceSize wallSpace = wallPattern.readSpace();
        SpaceSize totalSpace = originSpace;
        for (final WallDirection d : this.directions) {
            final SpaceSize directionedWallSpace = switch (d.ordinal()) {
                default -> throw new MatchException(null, null);
                case 2 -> wallSpace.clone().moveBy(new Vector3i(1, 0, 0));
                case 3 -> wallSpace.clone().moveBy(new Vector3i(-1, 0, 0));
                case 0 -> wallSpace.clone().moveBy(new Vector3i(0, 0, -1));
                case 1 -> wallSpace.clone().moveBy(new Vector3i(0, 0, 1));
            };
            totalSpace = SpaceSize.merge(totalSpace, directionedWallSpace);
        }
        this.readSpaceSize = totalSpace;
    }
    
    @Override
    public boolean matches(@Nonnull final Context context) {
        for (final WallDirection direction : this.directions) {
            final boolean matches = this.matches(context, direction);
            if (this.matchAll && !matches) {
                return false;
            }
            if (matches) {
                return true;
            }
        }
        return false;
    }
    
    private boolean matches(@Nonnull final Context context, @Nonnull final WallDirection direction) {
        final Vector3i wallPosition = context.position.clone();
        switch (direction.ordinal()) {
            case 2: {
                final Vector3i vector3i = wallPosition;
                ++vector3i.x;
                break;
            }
            case 3: {
                final Vector3i vector3i2 = wallPosition;
                --vector3i2.x;
                break;
            }
            case 0: {
                final Vector3i vector3i3 = wallPosition;
                --vector3i3.z;
                break;
            }
            case 1: {
                final Vector3i vector3i4 = wallPosition;
                ++vector3i4.z;
                break;
            }
        }
        final Context wallContext = new Context(context);
        wallContext.position = wallPosition;
        return this.originPattern.matches(context) && this.wallPattern.matches(wallContext);
    }
    
    @Nonnull
    @Override
    public SpaceSize readSpace() {
        return this.readSpaceSize.clone();
    }
    
    public enum WallDirection
    {
        N, 
        S, 
        E, 
        W;
        
        public static final Codec<WallDirection> CODEC;
        
        static {
            CODEC = new EnumCodec<WallDirection>(WallDirection.class, EnumCodec.EnumStyle.LEGACY);
        }
    }
}
