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

package com.hypixel.hytale.server.npc.asset.builder.validators;

import java.lang.invoke.CallSite;
import java.lang.reflect.UndeclaredThrowableException;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.StringConcatFactory;
import java.lang.invoke.MethodType;
import java.lang.invoke.MethodHandles;
import java.util.Arrays;
import javax.annotation.Nonnull;

public class DoubleSequenceValidator extends DoubleArrayValidator
{
    private static final DoubleSequenceValidator VALIDATOR_BETWEEN_01;
    private static final DoubleSequenceValidator VALIDATOR_BETWEEN_01_WEAKLY_MONOTONIC;
    private static final DoubleSequenceValidator VALIDATOR_BETWEEN_01_MONOTONIC;
    private static final DoubleSequenceValidator VALIDATOR_WEAKLY_MONOTONIC;
    private static final DoubleSequenceValidator VALIDATOR_MONOTONIC;
    private final RelationalOperator relationLower;
    private final double lower;
    private final RelationalOperator relationUpper;
    private final double upper;
    private final RelationalOperator relationSequence;
    
    private DoubleSequenceValidator(final RelationalOperator relationLower, final double lower, final RelationalOperator relationUpper, final double upper, final RelationalOperator relationSequence) {
        this.lower = lower;
        this.upper = upper;
        this.relationLower = relationLower;
        this.relationUpper = relationUpper;
        this.relationSequence = relationSequence;
    }
    
    public static DoubleSequenceValidator between01() {
        return DoubleSequenceValidator.VALIDATOR_BETWEEN_01;
    }
    
    public static DoubleSequenceValidator between01WeaklyMonotonic() {
        return DoubleSequenceValidator.VALIDATOR_BETWEEN_01_WEAKLY_MONOTONIC;
    }
    
    public static DoubleSequenceValidator between01Monotonic() {
        return DoubleSequenceValidator.VALIDATOR_BETWEEN_01_MONOTONIC;
    }
    
    @Nonnull
    public static DoubleSequenceValidator between(final double lower, final double upper) {
        return new DoubleSequenceValidator(RelationalOperator.GreaterEqual, lower, RelationalOperator.LessEqual, upper, null);
    }
    
    @Nonnull
    public static DoubleSequenceValidator betweenWeaklyMonotonic(final double lower, final double upper) {
        return new DoubleSequenceValidator(RelationalOperator.GreaterEqual, lower, RelationalOperator.LessEqual, upper, RelationalOperator.LessEqual);
    }
    
    @Nonnull
    public static DoubleSequenceValidator betweenMonotonic(final double lower, final double upper) {
        return new DoubleSequenceValidator(RelationalOperator.GreaterEqual, lower, RelationalOperator.LessEqual, upper, RelationalOperator.Less);
    }
    
    @Nonnull
    public static DoubleSequenceValidator fromExclToIncl(final double lower, final double upper) {
        return new DoubleSequenceValidator(RelationalOperator.Greater, lower, RelationalOperator.LessEqual, upper, null);
    }
    
    @Nonnull
    public static DoubleSequenceValidator fromExclToInclWeaklyMonotonic(final double lower, final double upper) {
        return new DoubleSequenceValidator(RelationalOperator.Greater, lower, RelationalOperator.LessEqual, upper, RelationalOperator.LessEqual);
    }
    
    @Nonnull
    public static DoubleSequenceValidator fromExclToInclMonotonic(final double lower, final double upper) {
        return new DoubleSequenceValidator(RelationalOperator.Greater, lower, RelationalOperator.LessEqual, upper, RelationalOperator.Less);
    }
    
    public static DoubleSequenceValidator monotonic() {
        return DoubleSequenceValidator.VALIDATOR_MONOTONIC;
    }
    
    public static DoubleSequenceValidator weaklyMonotonic() {
        return DoubleSequenceValidator.VALIDATOR_WEAKLY_MONOTONIC;
    }
    
    @Override
    public boolean test(@Nonnull final double[] values) {
        for (int i = 0; i < values.length; ++i) {
            final double value = values[i];
            if (!DoubleValidator.compare(value, this.relationLower, this.lower) && DoubleValidator.compare(value, this.relationUpper, this.upper)) {
                return false;
            }
            if (i > 0 && this.relationSequence != null && !DoubleValidator.compare(values[i - 1], this.relationSequence, value)) {
                return false;
            }
        }
        return true;
    }
    
    @Nonnull
    @Override
    public String errorMessage(final double[] value) {
        return this.errorMessage0(value, "Array");
    }
    
    @Nonnull
    @Override
    public String errorMessage(final double[] value, final String name) {
        return this.errorMessage0(value, "\"" + name);
    }
    
    @Nonnull
    private String errorMessage0(final double[] value, final String name) {
        return name + ((this.relationLower == null) ? "" : (" values should be " + this.relationLower.asText() + " " + this.lower + " and ")) + ((this.relationUpper == null) ? "" : /* invokedynamic(!) */ProcyonInvokeDynamicHelper_22.invoke(this.relationUpper.asText(), this.upper)) + ((this.relationSequence == null) ? "" : /* invokedynamic(!) */ProcyonInvokeDynamicHelper_23.invoke(this.relationSequence.asText())) + " but is " + Arrays.toString(value);
    }
    
    static {
        VALIDATOR_BETWEEN_01 = new DoubleSequenceValidator(RelationalOperator.GreaterEqual, 0.0, RelationalOperator.LessEqual, 1.0, null);
        VALIDATOR_BETWEEN_01_WEAKLY_MONOTONIC = new DoubleSequenceValidator(RelationalOperator.GreaterEqual, 0.0, RelationalOperator.LessEqual, 1.0, RelationalOperator.LessEqual);
        VALIDATOR_BETWEEN_01_MONOTONIC = new DoubleSequenceValidator(RelationalOperator.GreaterEqual, 0.0, RelationalOperator.LessEqual, 1.0, RelationalOperator.Less);
        VALIDATOR_WEAKLY_MONOTONIC = new DoubleSequenceValidator(RelationalOperator.GreaterEqual, -1.7976931348623157E308, RelationalOperator.LessEqual, Double.MAX_VALUE, RelationalOperator.LessEqual);
        VALIDATOR_MONOTONIC = new DoubleSequenceValidator(RelationalOperator.GreaterEqual, -1.7976931348623157E308, RelationalOperator.LessEqual, Double.MAX_VALUE, RelationalOperator.Less);
    }
    
    // This helper class was generated by Procyon to approximate the behavior of an
    // 'invokedynamic' instruction that it doesn't know how to interpret.
    private static final class ProcyonInvokeDynamicHelper_22
    {
        private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
        private static MethodHandle handle;
        private static volatile int fence;
        
        private static MethodHandle handle() {
            final MethodHandle handle = ProcyonInvokeDynamicHelper_22.handle;
            if (handle != null)
                return handle;
            return ProcyonInvokeDynamicHelper_22.ensureHandle();
        }
        
        private static MethodHandle ensureHandle() {
            ProcyonInvokeDynamicHelper_22.fence = 0;
            MethodHandle handle = ProcyonInvokeDynamicHelper_22.handle;
            if (handle == null) {
                MethodHandles.Lookup lookup = ProcyonInvokeDynamicHelper_22.LOOKUP;
                try {
                    handle = ((CallSite)StringConcatFactory.makeConcatWithConstants(lookup, "makeConcatWithConstants", MethodType.methodType(String.class, String.class, double.class), " values should be \u0001 \u0001 and ")).dynamicInvoker();
                }
                catch (Throwable t) {
                    throw new UndeclaredThrowableException(t);
                }
                ProcyonInvokeDynamicHelper_22.fence = 1;
                ProcyonInvokeDynamicHelper_22.handle = handle;
                ProcyonInvokeDynamicHelper_22.fence = 0;
            }
            return handle;
        }
        
        private static String invoke(String p0, double p1) {
            try {
                return ProcyonInvokeDynamicHelper_22.handle().invokeExact(p0, p1);
            }
            catch (Throwable t) {
                throw new UndeclaredThrowableException(t);
            }
        }
    }
    
    // This helper class was generated by Procyon to approximate the behavior of an
    // 'invokedynamic' instruction that it doesn't know how to interpret.
    private static final class ProcyonInvokeDynamicHelper_23
    {
        private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
        private static MethodHandle handle;
        private static volatile int fence;
        
        private static MethodHandle handle() {
            final MethodHandle handle = ProcyonInvokeDynamicHelper_23.handle;
            if (handle != null)
                return handle;
            return ProcyonInvokeDynamicHelper_23.ensureHandle();
        }
        
        private static MethodHandle ensureHandle() {
            ProcyonInvokeDynamicHelper_23.fence = 0;
            MethodHandle handle = ProcyonInvokeDynamicHelper_23.handle;
            if (handle == null) {
                MethodHandles.Lookup lookup = ProcyonInvokeDynamicHelper_23.LOOKUP;
                try {
                    handle = ((CallSite)StringConcatFactory.makeConcatWithConstants(lookup, "makeConcatWithConstants", MethodType.methodType(String.class, String.class), " succeeding values should be \u0001 preceding values ")).dynamicInvoker();
                }
                catch (Throwable t) {
                    throw new UndeclaredThrowableException(t);
                }
                ProcyonInvokeDynamicHelper_23.fence = 1;
                ProcyonInvokeDynamicHelper_23.handle = handle;
                ProcyonInvokeDynamicHelper_23.fence = 0;
            }
            return handle;
        }
        
        private static String invoke(String p0) {
            try {
                return ProcyonInvokeDynamicHelper_23.handle().invokeExact(p0);
            }
            catch (Throwable t) {
                throw new UndeclaredThrowableException(t);
            }
        }
    }
}
