package common.tags;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import common.util.Util;

class TagList extends Tag {
	private List<TagObject> list;
	
	TagList() {
	}
	
	public TagList(List<TagObject> list) {
		this.list = list;
	}

	void write(DataOutput output) throws IOException {
		output.writeInt(this.list.size());
		for(int z = 0; z < this.list.size(); z++) {
			this.list.get(z).write(output);
		}
	}

	void read(DataInput input, int depth, SizeTracker tracker) throws IOException {
		tracker.read(36);
		if(depth > 256)
			throw new IOException("Objekt ist zu komplex, die Tiefe ist größer als 256");
		int len = input.readInt();
		tracker.read(4 * len);
		this.list = new ArrayList<TagObject>(len);
		for(int z = 0; z < len; z++) {
			TagObject tag = new TagObject();
			tag.read(input, depth + 1, tracker);
			this.list.add(tag);
		}
	}

	TagType getType() {
		return TagType.LIST;
	}

	public String toString() {
		StringBuilder sb = new StringBuilder("[");
		for(int z = 0; z < this.list.size(); z++) {
			if(z != 0)
				sb.append(',');
			sb.append(this.list.get(z).toString());
		}
		return sb.append(']').toString();
	}

	String toString(int indent, int depth) {
		StringBuilder sb = new StringBuilder("[");
		String prefix = Util.repeatString(' ', indent * (depth + 1));
		for(int z = 0; z < this.list.size(); z++) {
			if(z != 0)
				sb.append(',');
			sb.append('\n').append(prefix).append(this.list.get(z).toString(indent, depth + 1));
		}
		return sb.append('\n').append(Util.repeatString(' ', indent * depth)).append(']').toString();
	}

	public Tag copy() {
		TagList list = new TagList(new ArrayList<TagObject>(this.list.size()));
		for(TagObject tag : this.list) {
			list.list.add(tag.copy());
		}
		return list;
	}

	public boolean equals(Object other) {
		return super.equals(other) && this.list.equals(((TagList)other).list);
	}

	public int hashCode() {
		return super.hashCode() ^ this.list.hashCode();
	}

	public List<TagObject> getList() {
		return this.list;
	}
}
