package com.danitheskunk.skunkworks;

import com.danitheskunk.skunkworks.gfx.Color;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

public class Data {
	static final String[] vectorSeperators = new String[]{"x", ",", " "};
	private final LinkedHashMap<String, LinkedHashMap<String, String>> data;
	private Runnable callback;
	private String currentCategory;

	public Data(ByteBuffer data) {
		this.data = new LinkedHashMap<>();
		currentCategory = "";
		this.data.put("", new LinkedHashMap<>());
		StandardCharsets.UTF_8.decode(data).toString().lines().forEach(this::processLine);
	}

	public String get(String category, String key) {
		var val = data.get(category).get(key);
		return val == null ? "" : val;
	}

	public List<String> getCategories() {
		return new ArrayList<>(data.keySet());
	}

	public Color getColor(String category, String key) {
		var str = get(category, key);
		if(str.equals("")) {
			return Color.WHITE;
		}
		if(str.startsWith("#") && (str.length() == 7 || str.length() == 9)) {
			var r = Integer.parseInt(str.substring(1, 3), 16);
			var g = Integer.parseInt(str.substring(3, 5), 16);
			var b = Integer.parseInt(str.substring(5, 7), 16);
			var a = str.length() == 9 ? Integer.parseInt(
				str.substring(7, 9),
				16
			) : 255;

			return new Color(r, g, b, a);
		}
		for(var seperator : vectorSeperators) {
			if(str.contains(seperator)) {
				var posStr = str.split(seperator);
				return new Color(Integer.parseInt(posStr[0].strip()),
					Integer.parseInt(posStr[1].strip()),
					Integer.parseInt(posStr[2].strip())
				);
			}
		}
		return Color.WHITE;

	}

	public Vec2i getVec2i(String category, String key) {
		var str = get(category, key);
		if(str.equals("")) {
			return Vec2i.ZERO;
		}
		for(var seperator : vectorSeperators) {
			if(str.contains(seperator)) {
				var posStr = str.split(seperator);
				return new Vec2i(Integer.parseInt(posStr[0].strip()),
					Integer.parseInt(posStr[1].strip())
				);
			}
		}
		return Vec2i.ZERO;
	}

	public void onReload(Runnable callback) {
		this.callback = callback;
	}

	private void processLine(String line) {
		if(line.contains("=")) {
			var parts = line.split("=", 2);
			data.get(currentCategory).put(parts[0].strip(), parts[1].strip());
		} else if(line.startsWith("[") && line.endsWith("]")) {
			currentCategory = line.substring(1, line.length() - 1);
			if(!data.containsKey(currentCategory)) {
				data.put(currentCategory, new LinkedHashMap<>());
			}
		}
	}

	public void reload(ByteBuffer data) {
		this.data.clear();
		this.data.put("", new LinkedHashMap<>());
		StandardCharsets.UTF_8.decode(data).toString().lines().forEach(this::processLine);
		if(callback != null) {
			callback.run();
		}
	}
}
