package me.minidigger.voxelgameslib.libs.net.md_5.bungee.api.chat;

import java.util.ArrayList;
import java.util.List;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import me.minidigger.voxelgameslib.libs.net.md_5.bungee.api.ChatColor;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@NoArgsConstructor
public class TranslatableComponent extends BaseComponent {
    
    private final ResourceBundle locales = ResourceBundle.getBundle("mojang-translations/en_US");
    private final Pattern format = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)");
    
    /**
     * The key into the Minecraft locale files to use for the translation. The
     * text depends on the client's locale setting. The console is always en_US
     */
    private String translate;
    /**
     * The components to substitute into the translation
     */
    private List<BaseComponent> with;
    
    /**
     * Creates a translatable component from the original to clone it.
     *
     * @param original the original for the new translatable component.
     */
    public TranslatableComponent(TranslatableComponent original) {
        super(original);
        setTranslate(original.getTranslate());
        
        if (original.getWith() != null) {
            List<BaseComponent> temp = new ArrayList<BaseComponent>();
            for (BaseComponent baseComponent : original.getWith()) {
                temp.add(baseComponent.duplicate());
            }
            setWith(temp);
        }
    }
    
    /**
     * Creates a translatable component with the passed substitutions
     *
     * @param translate the translation key
     * @param with      the {@link java.lang.String}s and {@link BaseComponent}s to use into the
     *                  translation
     * @see #translate
     * @see #setWith(java.util.List)
     */
    public TranslatableComponent(String translate, Object... with) {
        setTranslate(translate);
        List<BaseComponent> temp = new ArrayList<BaseComponent>();
        for (Object w : with) {
            if (w instanceof String) {
                temp.add(new TextComponent((String) w));
            } else if (w instanceof BaseComponent) {
                temp.add((BaseComponent) w);
            } else {
                temp.add(new TextComponent(String.valueOf(w))); // VGL: make it accept other objects too
            }
        }
        setWith(temp);
    }
    
    /**
     * Creates a duplicate of this TranslatableComponent.
     *
     * @return the duplicate of this TranslatableComponent.
     */
    @Override
    public BaseComponent duplicate() {
        return new TranslatableComponent(this);
    }
    
    /**
     * Sets the translation substitutions to be used in this component. Removes
     * any previously set substitutions
     *
     * @param components the components to substitute
     */
    public void setWith(List<BaseComponent> components) {
        for (BaseComponent component : components) {
            component.parent = this;
        }
        with = components;
    }
    
    /**
     * Adds a text substitution to the component. The text will inherit this
     * component's formatting
     *
     * @param text the text to substitute
     */
    public void addWith(String text) {
        addWith(new TextComponent(text));
    }
    
    /**
     * Adds a component substitution to the component. The text will inherit
     * this component's formatting
     *
     * @param component the component to substitute
     */
    public void addWith(BaseComponent component) {
        if (with == null) {
            with = new ArrayList<BaseComponent>();
        }
        component.parent = this;
        with.add(component);
    }
    
    @Override
    protected void toPlainText(StringBuilder builder) {
        String trans;
        try {
            trans = locales.getString(translate);
        } catch (MissingResourceException ex) {
            trans = translate;
        }
        
        Matcher matcher = format.matcher(trans);
        int position = 0;
        int i = 0;
        while (matcher.find(position)) {
            int pos = matcher.start();
            if (pos != position) {
                builder.append(trans.substring(position, pos));
            }
            position = matcher.end();
            
            String formatCode = matcher.group(2);
            switch (formatCode.charAt(0)) {
                case 's':
                case 'd':
                    String withIndex = matcher.group(1);
                    with.get(withIndex != null ? Integer.parseInt(withIndex) - 1 : i++).toPlainText(builder);
                    break;
                case '%':
                    builder.append('%');
                    break;
            }
        }
        if (trans.length() != position) {
            builder.append(trans.substring(position, trans.length()));
        }
        
        super.toPlainText(builder);
    }
    
    @Override
    protected void toLegacyText(StringBuilder builder) {
        String trans;
        try {
            trans = locales.getString(translate);
        } catch (MissingResourceException e) {
            trans = translate;
        }
        
        Matcher matcher = format.matcher(trans);
        int position = 0;
        int i = 0;
        while (matcher.find(position)) {
            int pos = matcher.start();
            if (pos != position) {
                addFormat(builder);
                builder.append(trans.substring(position, pos));
            }
            position = matcher.end();
            
            String formatCode = matcher.group(2);
            switch (formatCode.charAt(0)) {
                case 's':
                case 'd':
                    String withIndex = matcher.group(1);
                    with.get(withIndex != null ? Integer.parseInt(withIndex) - 1 : i++).toLegacyText(builder);
                    break;
                case '%':
                    addFormat(builder);
                    builder.append('%');
                    break;
            }
        }
        if (trans.length() != position) {
            addFormat(builder);
            builder.append(trans.substring(position, trans.length()));
        }
        super.toLegacyText(builder);
    }
    
    private void addFormat(StringBuilder builder) {
        builder.append(getColor());
        if (isBold()) {
            builder.append(ChatColor.BOLD);
        }
        if (isItalic()) {
            builder.append(ChatColor.ITALIC);
        }
        if (isUnderlined()) {
            builder.append(ChatColor.UNDERLINE);
        }
        if (isStrikethrough()) {
            builder.append(ChatColor.STRIKETHROUGH);
        }
        if (isObfuscated()) {
            builder.append(ChatColor.MAGIC);
        }
    }
}

@@ -85,24 +85,54 @@
 .ArrayList;%0A
+import java.util.Collections;%0A
 import java.
@@ -2410,16 +2410,134 @@
 nt) w);%0A
+            %7D else if (w instanceof BaseComponent%5B%5D) %7B%0A                Collections.addAll(temp, (BaseComponent%5B%5D) w);%0A
         

make TranslatableComponent accept event more object types.