package speiger.src.coreengine.rendering.models.loader;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.List;
import java.util.UUID;

import com.google.gson.JsonObject;

import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.AssetManager;
import speiger.src.coreengine.assets.base.IAsset;
import speiger.src.coreengine.math.color.ColorUtils;
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
import speiger.src.coreengine.utils.helpers.JsonUtil;

public class ModelLoader
{
	
	public static List<SimpleModelData> readModelData(AssetLocation location, AssetManager manager)
	{
		try(IAsset asset = manager.getAsset(location))
		{
			List<SimpleModelData> result = new ObjectArrayList<>();
			JsonObject obj = asset.json();
			JsonUtil.iterate(obj.get("models"), T -> {
				JsonObject info = T.getAsJsonObject("info");
				JsonObject format = T.getAsJsonObject("format");
				JsonObject data = T.getAsJsonObject("data");
				List<VertexEntry> entries = VertexLoader.loadVertexFormat(format);
				ByteBuffer buffer = VertexLoader.parseVertexData(data, info.get("vertecies").getAsInt(), entries, true);
				result.add(new SimpleModelData(info.get("name").getAsString(), UUID.fromString(info.get("id").getAsString()), buffer.array(), JsonUtil.parseIntArray(data.getAsJsonArray("indecies"))));
			});
			return result;
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return ObjectLists.empty();
	}
	
	public static List<SimpleModelData> readLegacyModelData(AssetLocation location, AssetManager manager)
	{
		List<SimpleModelData> resultModels = new ObjectArrayList<SimpleModelData>();
		ByteBuffer buffer = null;
		int[] indexes = null;
		String currentName = null;
		try(IAsset asset = manager.getAsset(location))
		{
			boolean flag = false;
			for(String line : IterableWrapper.wrap(asset.reader()))
			{
				if(line.startsWith("{"))
				{
					if(currentName != null && buffer != null)
					{
						resultModels.add(new SimpleModelData(currentName, null, buffer.array(), indexes));
						currentName = null;
					}
					currentName = line.substring(1, line.length() - 1);
					flag = true;
				}
				else if(flag)
				{
					flag = false;
					String[] bounds = line.split(";");
					buffer = ByteBuffer.allocate(Integer.parseInt(bounds[0]) * 28).order(ByteOrder.nativeOrder());
					indexes = new int[Integer.parseInt(bounds[1])];
				}
				else if(line.startsWith("<") && buffer != null)
				{
					String[] data = line.substring(1, line.length() - 1).split(" ");
					String[] position = data[0].split(";");
					String[] normal = data[2].split(";");
					buffer.putFloat(Float.parseFloat(position[0])).putFloat(Float.parseFloat(position[1])).putFloat(Float.parseFloat(position[2]));
					ColorUtils.write(Integer.parseInt(data[1]), true, buffer);
					buffer.putFloat(Float.parseFloat(normal[0])).putFloat(Float.parseFloat(normal[1])).putFloat(Float.parseFloat(normal[2]));
				}
				else if(line.startsWith("[") && indexes != null)
				{
					String[] data = line.substring(1, line.length() - 1).split(";");
					for(int j = 0;j<data.length;j++)
					{
						indexes[j] = Integer.parseInt(data[j]);
					}
				}
			}
			if(currentName != null && buffer != null)
			{
				resultModels.add(new SimpleModelData(currentName, null, buffer.array(), indexes));
				currentName = null;
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return resultModels;
	}
}
