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

package com.hypixel.hytale.server.core.ui.builder;

import com.hypixel.hytale.server.core.ui.Anchor;
import com.hypixel.hytale.server.core.ui.DropdownEntryInfo;
import com.hypixel.hytale.server.core.ui.PatchStyle;
import com.hypixel.hytale.server.core.ui.LocalizableString;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.ui.ItemGridSlot;
import com.hypixel.hytale.server.core.ui.Area;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Iterator;
import org.bson.BsonArray;
import org.bson.BsonInt32;
import org.bson.BsonDouble;
import org.bson.BsonBoolean;
import com.hypixel.hytale.codec.ExtraInfo;
import com.hypixel.hytale.codec.EmptyExtraInfo;
import com.hypixel.hytale.server.core.Message;
import org.bson.BsonString;
import org.bson.BsonNull;
import com.hypixel.hytale.server.core.ui.ValueCodec;
import com.hypixel.hytale.server.core.ui.Value;
import org.bson.BsonDocument;
import org.bson.BsonValue;
import com.hypixel.hytale.protocol.packets.interface_.CustomUICommandType;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import javax.annotation.Nonnull;
import java.util.List;
import com.hypixel.hytale.protocol.packets.interface_.CustomUICommand;
import com.hypixel.hytale.codec.Codec;
import java.util.Map;

public class UICommandBuilder
{
    private static final Map<Class, Codec> CODEC_MAP;
    public static final CustomUICommand[] EMPTY_COMMAND_ARRAY;
    @Nonnull
    private final List<CustomUICommand> commands;
    
    public UICommandBuilder() {
        this.commands = new ObjectArrayList<CustomUICommand>();
    }
    
    @Nonnull
    public UICommandBuilder clear(final String selector) {
        this.commands.add(new CustomUICommand(CustomUICommandType.Clear, selector, null, null));
        return this;
    }
    
    @Nonnull
    public UICommandBuilder remove(final String selector) {
        this.commands.add(new CustomUICommand(CustomUICommandType.Remove, selector, null, null));
        return this;
    }
    
    @Nonnull
    public UICommandBuilder append(final String documentPath) {
        this.commands.add(new CustomUICommand(CustomUICommandType.Append, null, null, documentPath));
        return this;
    }
    
    @Nonnull
    public UICommandBuilder append(final String selector, final String documentPath) {
        this.commands.add(new CustomUICommand(CustomUICommandType.Append, selector, null, documentPath));
        return this;
    }
    
    @Nonnull
    public UICommandBuilder appendInline(final String selector, final String document) {
        this.commands.add(new CustomUICommand(CustomUICommandType.AppendInline, selector, null, document));
        return this;
    }
    
    @Nonnull
    public UICommandBuilder insertBefore(final String selector, final String documentPath) {
        this.commands.add(new CustomUICommand(CustomUICommandType.InsertBefore, selector, null, documentPath));
        return this;
    }
    
    @Nonnull
    public UICommandBuilder insertBeforeInline(final String selector, final String document) {
        this.commands.add(new CustomUICommand(CustomUICommandType.InsertBeforeInline, selector, null, document));
        return this;
    }
    
    @Nonnull
    @Deprecated
    private UICommandBuilder setBsonValue(final String selector, final BsonValue bsonValue) {
        final BsonDocument valueWrapper = new BsonDocument();
        valueWrapper.put("0", bsonValue);
        this.commands.add(new CustomUICommand(CustomUICommandType.Set, selector, valueWrapper.toJson(), null));
        return this;
    }
    
    @Nonnull
    public <T> UICommandBuilder set(final String selector, @Nonnull final Value<T> ref) {
        if (ref.getValue() != null) {
            throw new IllegalArgumentException("Method only accepts references without a direct value");
        }
        return this.setBsonValue(selector, ValueCodec.REFERENCE_ONLY.encode((Value<Object>)ref));
    }
    
    @Nonnull
    public UICommandBuilder setNull(final String selector) {
        return this.setBsonValue(selector, BsonNull.VALUE);
    }
    
    @Nonnull
    public UICommandBuilder set(final String selector, @Nonnull final String str) {
        return this.setBsonValue(selector, new BsonString(str));
    }
    
    @Nonnull
    public UICommandBuilder set(final String selector, @Nonnull final Message message) {
        return this.setBsonValue(selector, Message.CODEC.encode(message, EmptyExtraInfo.EMPTY));
    }
    
    @Nonnull
    public UICommandBuilder set(final String selector, final boolean b) {
        return this.setBsonValue(selector, new BsonBoolean(b));
    }
    
    @Nonnull
    public UICommandBuilder set(final String selector, final float n) {
        return this.setBsonValue(selector, new BsonDouble(n));
    }
    
    @Nonnull
    public UICommandBuilder set(final String selector, final int n) {
        return this.setBsonValue(selector, new BsonInt32(n));
    }
    
    @Nonnull
    public UICommandBuilder set(final String selector, final double n) {
        return this.setBsonValue(selector, new BsonDouble(n));
    }
    
    @Nonnull
    public UICommandBuilder setObject(final String selector, @Nonnull final Object data) {
        final Codec codec = UICommandBuilder.CODEC_MAP.get(data.getClass());
        if (codec == null) {
            throw new IllegalArgumentException(data.getClass().getName() + " is not a compatible class");
        }
        return this.setBsonValue(selector, codec.encode(data));
    }
    
    @Nonnull
    public <T> UICommandBuilder set(final String selector, @Nonnull final T[] data) {
        final Codec codec = UICommandBuilder.CODEC_MAP.get(data.getClass().getComponentType());
        if (codec == null) {
            throw new IllegalArgumentException(data.getClass().getName() + " is not a compatible class");
        }
        final BsonArray arr = new BsonArray();
        for (final T d : data) {
            arr.add(codec.encode(d));
        }
        return this.setBsonValue(selector, arr);
    }
    
    @Nonnull
    public <T> UICommandBuilder set(final String selector, @Nonnull final List<T> data) {
        Codec<T> codec = null;
        final BsonArray arr = new BsonArray();
        for (final T d : data) {
            if (codec == null) {
                codec = UICommandBuilder.CODEC_MAP.get(d.getClass());
                if (codec == null) {
                    throw new IllegalArgumentException(data.getClass().getName() + " is not a compatible class");
                }
            }
            arr.add(codec.encode(d));
        }
        return this.setBsonValue(selector, arr);
    }
    
    @Nonnull
    public CustomUICommand[] getCommands() {
        return this.commands.toArray(CustomUICommand[]::new);
    }
    
    static {
        CODEC_MAP = new Object2ObjectOpenHashMap<Class, Codec>();
        EMPTY_COMMAND_ARRAY = new CustomUICommand[0];
        UICommandBuilder.CODEC_MAP.put(Area.class, Area.CODEC);
        UICommandBuilder.CODEC_MAP.put(ItemGridSlot.class, ItemGridSlot.CODEC);
        UICommandBuilder.CODEC_MAP.put(ItemStack.class, ItemStack.CODEC);
        UICommandBuilder.CODEC_MAP.put(LocalizableString.class, LocalizableString.CODEC);
        UICommandBuilder.CODEC_MAP.put(PatchStyle.class, PatchStyle.CODEC);
        UICommandBuilder.CODEC_MAP.put(DropdownEntryInfo.class, DropdownEntryInfo.CODEC);
        UICommandBuilder.CODEC_MAP.put(Anchor.class, Anchor.CODEC);
    }
}
