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

package com.hypixel.hytale.server.npc.util.expression.compile;

import java.util.Collection;
import java.util.Collections;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.function.Supplier;

public enum Token implements Supplier<String>
{
    INVALID((String)null, 0), 
    END((String)null, 0), 
    STRING((String)null, 0, EnumSet.of(TokenFlags.OPERAND, TokenFlags.LITERAL)), 
    NUMBER((String)null, 0, EnumSet.of(TokenFlags.OPERAND, TokenFlags.LITERAL)), 
    IDENTIFIER((String)null, 0, EnumSet.of(TokenFlags.OPERAND)), 
    OPEN_BRACKET("(", 20, EnumSet.of(TokenFlags.OPENING_BRACKET), (Token)null, (Token)null), 
    CLOSE_BRACKET(")", 20, EnumSet.of(TokenFlags.CLOSING_BRACKET), Token.OPEN_BRACKET, (Token)null), 
    OPEN_SQUARE_BRACKET("[", 19, EnumSet.of(TokenFlags.OPENING_BRACKET, TokenFlags.OPENING_TUPLE), (Token)null, (Token)null), 
    CLOSE_SQUARE_BRACKET("]", 19, EnumSet.of(TokenFlags.CLOSING_BRACKET), Token.OPEN_SQUARE_BRACKET, (Token)null), 
    COMMA(",", 20, EnumSet.of(TokenFlags.LIST)), 
    FUNCTION_CALL((String)null, 19), 
    UNARY_MINUS((String)null, 16, EnumSet.of(TokenFlags.OPERATOR, TokenFlags.RIGHT_TO_LEFT, TokenFlags.UNARY)), 
    UNARY_PLUS((String)null, 16, EnumSet.of(TokenFlags.OPERATOR, TokenFlags.RIGHT_TO_LEFT, TokenFlags.UNARY)), 
    LOGICAL_NOT("!", 16, EnumSet.of(TokenFlags.OPERATOR, TokenFlags.RIGHT_TO_LEFT, TokenFlags.UNARY)), 
    BITWISE_NOT("~", 16, EnumSet.of(TokenFlags.OPERATOR, TokenFlags.RIGHT_TO_LEFT, TokenFlags.UNARY)), 
    EXPONENTIATION("**", 15, EnumSet.of(TokenFlags.OPERATOR, TokenFlags.RIGHT_TO_LEFT)), 
    REMAINDER("%", 14, EnumSet.of(TokenFlags.OPERATOR)), 
    DIVIDE("/", 14, EnumSet.of(TokenFlags.OPERATOR)), 
    MULTIPLY("*", 14, EnumSet.of(TokenFlags.OPERATOR)), 
    MINUS("-", 13, EnumSet.of(TokenFlags.OPERATOR), (Token)null, Token.UNARY_MINUS), 
    PLUS("+", 13, EnumSet.of(TokenFlags.OPERATOR), (Token)null, Token.UNARY_PLUS), 
    GREATER_EQUAL(">=", 11, EnumSet.of(TokenFlags.OPERATOR)), 
    GREATER(">", 11, EnumSet.of(TokenFlags.OPERATOR)), 
    LESS_EQUAL("<=", 11, EnumSet.of(TokenFlags.OPERATOR)), 
    LESS("<", 11, EnumSet.of(TokenFlags.OPERATOR)), 
    NOT_EQUAL("!=", 10, EnumSet.of(TokenFlags.OPERATOR)), 
    EQUAL("==", 10, EnumSet.of(TokenFlags.OPERATOR)), 
    BITWISE_AND("&", 9, EnumSet.of(TokenFlags.OPERATOR)), 
    BITWISE_XOR("^", 8, EnumSet.of(TokenFlags.OPERATOR)), 
    BITWISE_OR("|", 7, EnumSet.of(TokenFlags.OPERATOR)), 
    LOGICAL_AND("&&", 6, EnumSet.of(TokenFlags.OPERATOR)), 
    LOGICAL_OR("||", 5, EnumSet.of(TokenFlags.OPERATOR));
    
    private final String text;
    private final int precedence;
    private final EnumSet<TokenFlags> flags;
    @Nullable
    private final Token matchingBracket;
    @Nullable
    private final Token unaryVariant;
    
    private Token(final String text, final int precedence) {
        this.text = text;
        this.precedence = precedence;
        this.flags = EnumSet.noneOf(TokenFlags.class);
        this.matchingBracket = null;
        this.unaryVariant = null;
    }
    
    private Token(final String text, final int precedence, final EnumSet<TokenFlags> flags) {
        this.text = text;
        this.precedence = precedence;
        this.flags = flags;
        this.matchingBracket = null;
        this.unaryVariant = null;
    }
    
    private Token(final String text, final int precedence, final EnumSet<TokenFlags> flags, final Token matchingBracket, final Token unaryVariant) {
        this.text = text;
        this.precedence = precedence;
        this.flags = flags;
        this.matchingBracket = matchingBracket;
        this.unaryVariant = unaryVariant;
    }
    
    @Override
    public String get() {
        return this.text;
    }
    
    public int getPrecedence() {
        return this.precedence;
    }
    
    public EnumSet<TokenFlags> getFlags() {
        return this.flags;
    }
    
    public boolean containsAnyFlag(@Nonnull final EnumSet<TokenFlags> testFlags) {
        return !Collections.disjoint(this.flags, testFlags);
    }
    
    public boolean isEndToken() {
        return this == Token.END;
    }
    
    public boolean isOperand() {
        return this.flags.contains(TokenFlags.OPERAND);
    }
    
    public boolean isLiteral() {
        return this.flags.contains(TokenFlags.LITERAL);
    }
    
    public boolean isOperator() {
        return this.flags.contains(TokenFlags.OPERATOR);
    }
    
    public boolean isRightToLeft() {
        return this.flags.contains(TokenFlags.RIGHT_TO_LEFT);
    }
    
    public boolean canBeUnary() {
        return this.unaryVariant != null;
    }
    
    @Nullable
    public Token getUnaryVariant() {
        return this.unaryVariant;
    }
    
    public boolean isUnary() {
        return this.flags.contains(TokenFlags.UNARY);
    }
    
    public boolean isOpenBracket() {
        return this.flags.contains(TokenFlags.OPENING_BRACKET);
    }
    
    public boolean isOpenTuple() {
        return this.flags.contains(TokenFlags.OPENING_TUPLE);
    }
    
    public boolean isCloseBracket() {
        return this.flags.contains(TokenFlags.CLOSING_BRACKET);
    }
    
    @Nullable
    public Token getMatchingBracket() {
        return this.matchingBracket;
    }
    
    public boolean isList() {
        return this.flags.contains(TokenFlags.LIST);
    }
}
