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

import java.io.IOException;

import speiger.src.coreengine.utils.io.dataTag.DataTag;
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.streams.ExtendedDataInput;
import speiger.src.coreengine.utils.io.streams.ExtendedDataOutput;

public class StringTag implements DataTag
{
	String value;
	
	public StringTag()
	{
		this("");
	}
	
	public StringTag(String value)
	{
		this.value = value == null ? "" : value;
	}
	
	@Override
	public int getId()
	{
		return 8;
	}
	
	@Override
	public String getTypeName()
	{
		return "String";
	}
	
	@Override
	public long countBytes(long input)
	{
		return input + 4L + (value.length() * 2L);
	}
	
	@Override
	public void write(ExtendedDataOutput output, TagCompressor compressor) throws IOException
	{
		output.writeString(value);
	}
	
	@Override
	public void read(ExtendedDataInput input, TagDecompressor decompressor, int depthLimit, DataTagLimiter limiter) throws IOException
	{
		value = input.readString();
		limiter.countBytes((value.length() * 2) + 4);
	}
	
	@Override
	public StringTag copy()
	{
		return new StringTag(value);
	}
	
	public String get()
	{
		return value;
	}
	
	@Override
	public int hashCode()
	{
		return value.hashCode();
	}
	
	@Override
	public boolean equals(Object obj)
	{
		return obj instanceof StringTag && ((StringTag)obj).value.equals(value);
	}
	
	@Override
	public String toString()
	{
		return quoteAndEscape(value);
	}
	
	@Override
	public String prettyPrint(String indent, int depth)
	{	
		StringBuilder builder = quoteAndEscapeBuilder(value).insert(1, STRING_HIGHLIGHT);
		return builder.insert(builder.length() - 1, RESET_HIGHLIGHT).toString();
	}
	
	public static String quoteAndEscape(String value)
	{
		return quoteAndEscapeBuilder(value).toString();
	}
	
	public static StringBuilder quoteAndEscapeBuilder(String value)
	{
		StringBuilder builder = new StringBuilder(" ");
		char c0 = 0;
		for(int i = 0,m=value.length();i < m;++i)
		{
			char c1 = value.charAt(i);
			if(c1 == '\\')
			{
				builder.append('\\');
			}
			else if(c1 == '"' || c1 == '\'')
			{
				if(c0 == 0)
				{
					c0 = (char)(c1 == '"' ? 39 : 34);
				}
				if(c0 == c1)
				{
					builder.append('\\');
				}
			}
			builder.append(c1);
		}
		builder.setCharAt(0, c0 == 0 ? '"' : c0);
		return builder.append(c0 == 0 ? '"' : c0);
	}
}