package com.evilco.mc.nbt.tag;

import com.evilco.mc.nbt.error.UnexpectedTagTypeException;
import com.evilco.mc.nbt.stream.NbtInputStream;
import com.evilco.mc.nbt.stream.NbtOutputStream;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nonnull;

public class TagList extends AbstractTag implements IAnonymousTagContainer {
   protected List<ITag> tagList;

   public TagList(@Nonnull String name) {
      super(name);
      this.tagList = new ArrayList();
   }

   public TagList(@Nonnull String name, @Nonnull List<ITag> tagList) {
      super(name);
      Preconditions.checkNotNull(tagList, "tagList");
      this.tagList = tagList;
   }

   public TagList(@Nonnull NbtInputStream inputStream, boolean anonymous) throws IOException {
      super(inputStream, anonymous);
      this.tagList = new ArrayList();
      byte type = inputStream.readByte();
      TagType tagType = TagType.valueOf(type);
      int size = inputStream.readInt();
      if (tagType != TagType.END) {
         for(int i = 0; i < size; ++i) {
            this.addTag(inputStream.readTag(tagType, true));
         }

      }
   }

   public void addTag(@Nonnull ITag tag) {
      this.tagList.add(tag);
   }

   public List<ITag> getTags() {
      return (new ImmutableList.Builder()).addAll((Iterable)this.tagList).build();
   }

   public <T extends ITag> List<T> getTags(Class<T> tagClass) throws UnexpectedTagTypeException {
      ImmutableList.Builder<T> builder = new ImmutableList.Builder();
      Iterator var3 = this.tagList.iterator();

      while(var3.hasNext()) {
         ITag tag = (ITag)var3.next();
         if (!tagClass.isInstance(tag)) {
            throw new UnexpectedTagTypeException("The list entry should be of type " + tagClass.getSimpleName() + ", but is of type " + tag.getClass().getSimpleName());
         }

         builder.add((Object)tag);
      }

      return builder.build();
   }

   public byte getTagID() {
      return TagType.LIST.typeID;
   }

   public void removeTag(@Nonnull ITag tag) {
      this.tagList.remove(tag);
   }

   public void setTag(int i, @Nonnull ITag tag) {
      this.tagList.set(i, tag);
   }

   public void write(NbtOutputStream outputStream, boolean anonymous) throws IOException {
      super.write(outputStream, anonymous);
      outputStream.writeByte(this.tagList.size() > 0 ? ((ITag)this.tagList.get(0)).getTagID() : TagType.END.typeID);
      outputStream.writeInt(this.tagList.size());
      Iterator var3 = this.tagList.iterator();

      while(var3.hasNext()) {
         ITag tag = (ITag)var3.next();
         tag.write(outputStream, true);
      }

   }
}
