package speiger.src.coreengine.utils.io.dataTag;

import java.io.IOException;
import java.util.function.Consumer;

import speiger.src.coreengine.utils.io.dataTag.array.ByteArrayTag;
import speiger.src.coreengine.utils.io.dataTag.array.DoubleArrayTag;
import speiger.src.coreengine.utils.io.dataTag.array.FloatArrayTag;
import speiger.src.coreengine.utils.io.dataTag.array.IntArrayTag;
import speiger.src.coreengine.utils.io.dataTag.array.LongArrayTag;
import speiger.src.coreengine.utils.io.dataTag.array.MediumArrayTag;
import speiger.src.coreengine.utils.io.dataTag.array.ShortArrayTag;
import speiger.src.coreengine.utils.io.dataTag.array.StringArrayTag;
import speiger.src.coreengine.utils.io.dataTag.compression.DataTagLimiter;
import speiger.src.coreengine.utils.io.dataTag.compression.TagCompressor;
import speiger.src.coreengine.utils.io.dataTag.compression.TagDecompressor;
import speiger.src.coreengine.utils.io.dataTag.simple.ByteTag;
import speiger.src.coreengine.utils.io.dataTag.simple.DoubleTag;
import speiger.src.coreengine.utils.io.dataTag.simple.FloatTag;
import speiger.src.coreengine.utils.io.dataTag.simple.IntTag;
import speiger.src.coreengine.utils.io.dataTag.simple.LongTag;
import speiger.src.coreengine.utils.io.dataTag.simple.MediumTag;
import speiger.src.coreengine.utils.io.dataTag.simple.ShortTag;
import speiger.src.coreengine.utils.io.dataTag.simple.StringTag;
import speiger.src.coreengine.utils.io.dataTag.special.ListTag;
import speiger.src.coreengine.utils.io.dataTag.special.MapTag;
import speiger.src.coreengine.utils.io.streams.ExtendedDataInput;
import speiger.src.coreengine.utils.io.streams.ExtendedDataOutput;

public interface DataTag
{
	String KEY_HIGHLIGHT = "§<color=5636095>";
	String STRING_HIGHLIGHT = "§<color=5635925>";
	String NUMBER_HIGHLIGHT = "§<color=16755200>";
	String TYPE_HIGHLIGHT = "§<color=16733525>";
	String RESET_HIGHLIGHT = "§<color>";
	
	public int getId();
	public String getTypeName();
	
	public long countBytes(long input);
	public default void addKeys(Consumer<String> keys){};
	
	public void write(ExtendedDataOutput output, TagCompressor compressor) throws IOException;
	public void read(ExtendedDataInput input, TagDecompressor decompressor, int depthLimit, DataTagLimiter limiter) throws IOException;
	
	public DataTag copy();
	
	@SuppressWarnings("unchecked")
	public default <T> T cast(){return (T)this;}
	@SuppressWarnings("unchecked")
	public default <T> T cast(Class<T> clz){return (T)this;}
	
	public default String prettyPrint(){return prettyPrint(" ", 0);}
	public String prettyPrint(String indent, int depth);
	
	
	public static DataTag create(byte id)
	{
		switch(id)
		{
			case 1: return new ByteTag();
			case 2: return new ShortTag();
			case 3: return new MediumTag();
			case 4: return new IntTag();
			case 5: return new LongTag();
			case 6: return new FloatTag();
			case 7: return new DoubleTag();
			case 8: return new StringTag();
			case 9: return new ByteArrayTag();
			case 10: return new ShortArrayTag();
			case 11: return new MediumArrayTag();
			case 12: return new IntArrayTag();
			case 13: return new LongArrayTag();
			case 14: return new FloatArrayTag();
			case 15: return new DoubleArrayTag();
			case 16: return new StringArrayTag();
			case 17: return new MapTag();
			case 18: return new ListTag();
		}
		return null;
	}
	
	static String repeate(String s, int amount)
	{
		StringBuilder builder = new StringBuilder();
		for(int i = 0;i<amount;i++)
		{
			builder.append(s);
		}
		return builder.toString();
	}
}
