package net.minecraft.client;

import net.minecraft.util.Unit;
import net.minecraft.network.chat.FormattedText;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Style;
import java.util.Optional;

public class StringDecomposer {
    private static final Optional<Object> STOP_ITERATION;
    
    private static boolean feedChar(final Style nb, final Output a, final int integer, final char character) {
        if (Character.isSurrogate(character)) {
            return a.onChar(integer, nb, 65533);
        }
        return a.onChar(integer, nb, character);
    }
    
    public static boolean iterate(final String string, final Style nb, final Output a) {
        for (int integer4 = string.length(), integer5 = 0; integer5 < integer4; ++integer5) {
            final char character6 = string.charAt(integer5);
            if (Character.isHighSurrogate(character6)) {
                if (integer5 + 1 >= integer4) {
                    if (!a.onChar(integer5, nb, 65533)) {
                        return false;
                    }
                    break;
                }
                else {
                    final char character7 = string.charAt(integer5 + 1);
                    if (Character.isLowSurrogate(character7)) {
                        if (!a.onChar(integer5, nb, Character.toCodePoint(character6, character7))) {
                            return false;
                        }
                        ++integer5;
                    }
                    else if (!a.onChar(integer5, nb, 65533)) {
                        return false;
                    }
                }
            }
            else if (!feedChar(nb, a, integer5, character6)) {
                return false;
            }
        }
        return true;
    }
    
    public static boolean iterateBackwards(final String string, final Style nb, final Output a) {
        final int integer4 = string.length();
        for (int integer5 = integer4 - 1; integer5 >= 0; --integer5) {
            final char character6 = string.charAt(integer5);
            if (Character.isLowSurrogate(character6)) {
                if (integer5 - 1 < 0) {
                    if (!a.onChar(0, nb, 65533)) {
                        return false;
                    }
                    break;
                }
                else {
                    final char character7 = string.charAt(integer5 - 1);
                    if (Character.isHighSurrogate(character7)) {
                        --integer5;
                        if (!a.onChar(integer5, nb, Character.toCodePoint(character7, character6))) {
                            return false;
                        }
                    }
                    else if (!a.onChar(integer5, nb, 65533)) {
                        return false;
                    }
                }
            }
            else if (!feedChar(nb, a, integer5, character6)) {
                return false;
            }
        }
        return true;
    }
    
    public static boolean iterateFormatted(final String string, final Style nb, final Output a) {
        return iterateFormatted(string, 0, nb, a);
    }
    
    public static boolean iterateFormatted(final String string, final int integer, final Style nb, final Output a) {
        return iterateFormatted(string, integer, nb, nb, a);
    }
    
    public static boolean iterateFormatted(final String string, final int integer, final Style nb3, final Style nb4, final Output a) {
        final int integer2 = string.length();
        Style nb5 = nb3;
        for (int integer3 = integer; integer3 < integer2; ++integer3) {
            final char character9 = string.charAt(integer3);
            if (character9 == '§') {
                if (integer3 + 1 >= integer2) {
                    break;
                }
                final char character10 = string.charAt(integer3 + 1);
                final ChatFormatting i11 = ChatFormatting.getByCode(character10);
                if (i11 != null) {
                    nb5 = ((i11 == ChatFormatting.RESET) ? nb4 : nb5.applyLegacyFormat(i11));
                }
                ++integer3;
            }
            else if (Character.isHighSurrogate(character9)) {
                if (integer3 + 1 >= integer2) {
                    if (!a.onChar(integer3, nb5, 65533)) {
                        return false;
                    }
                    break;
                }
                else {
                    final char character10 = string.charAt(integer3 + 1);
                    if (Character.isLowSurrogate(character10)) {
                        if (!a.onChar(integer3, nb5, Character.toCodePoint(character9, character10))) {
                            return false;
                        }
                        ++integer3;
                    }
                    else if (!a.onChar(integer3, nb5, 65533)) {
                        return false;
                    }
                }
            }
            else if (!feedChar(nb5, a, integer3, character9)) {
                return false;
            }
        }
        return true;
    }
    
    public static boolean iterateFormatted(final FormattedText mu, final Style nb, final Output a) {
        return !mu.visit((nb, string) -> iterateFormatted(string, 0, nb, a) ? Optional.empty() : StringDecomposer.STOP_ITERATION, nb).isPresent();
    }
    
    public static String filterBrokenSurrogates(final String string) {
        final StringBuilder stringBuilder2 = new StringBuilder();
        iterate(string, Style.EMPTY, (integer2, nb, integer4) -> {
            stringBuilder2.appendCodePoint(integer4);
            return true;
        });
        return stringBuilder2.toString();
    }
    
    static {
        STOP_ITERATION = Optional.<Unit>of(Unit.INSTANCE);
    }
    
    @FunctionalInterface
    public interface Output {
        boolean onChar(final int integer1, final Style nb, final int integer3);
    }
}
