package com.danitheskunk.skunkworks.gfx;

import com.danitheskunk.skunkworks.Recti;
import com.danitheskunk.skunkworks.Vec2i;
import com.danitheskunk.skunkworks.gfx.font.IFont;
import com.danitheskunk.skunkworks.gfx.vt.Terminal;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;

abstract public class BaseRenderContext implements IRenderContext {
	protected final Vec2i size;

	protected BaseRenderContext(Vec2i size) {
		this.size = size;
	}

	public void drawString(Vec2i pos, String string, IFont font) {
		drawString(pos, string, font, Color.WHITE);
	}

	public void drawString(Vec2i pos, String string, IFont font, Color color) {
		int x = pos.getX();
		int y = pos.getY();
		IntBuffer buf;
		try {
			buf = ByteBuffer.wrap(string.getBytes("UTF-32")).asIntBuffer();
		} catch(UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
		for(int i = 0; i < string.length(); ++i) {
			int ch = buf.get(i);
			var tex = font.getTexture(ch);
			var off = font.getOffset(ch);
			drawTextureRectangle(
				new Recti(Vec2i.add(new Vec2i(x, y), off), tex.getSize()),
				tex,
				color,
				true
			);
			x += font.getXAdvance(ch);
		}
	}

	public void drawTerminal(Terminal terminal) {
		var off = Vec2i.div(Vec2i.sub(size, terminal.getPixelSize()), 2);
		drawTerminal(terminal, off);
	}

	public void drawTerminal(Terminal terminal, Vec2i pos) {
		var termSize = terminal.getSize();
		var charSize = terminal.getFullCharSize();
		var halfCharSize = terminal.getHalfCharSize();
		var halfFont = terminal.getHalfFont();
		var fullFont = terminal.getFullFont();

		for(int y = 0; y < termSize.getY(); ++y) {
			for(int x = 0; x < termSize.getX(); ++x) {
				var charPos = new Vec2i(x, y);
				var bgColor = terminal.getBackgroundColor(charPos);
				var fgColor = terminal.getForegroundColor(charPos);
				var pixelPos = Vec2i.add(pos, Vec2i.mul(charPos, charSize));
				var isHalfWidth = terminal.isHalfWidth(charPos);

				drawTexture(pixelPos, fullFont.getTexture(0xdb), bgColor);
				if(isHalfWidth && halfFont != null) {
					drawTexture(pixelPos,
						halfFont.getTexture(terminal.getLeftHalfChar(charPos)),
						fgColor
					);
					drawTexture(new Vec2i(pixelPos.getX() + halfCharSize.getX(),
							pixelPos.getY()
						),
						halfFont.getTexture(terminal.getRightHalfChar(charPos)),
						fgColor
					);
				} else {
					drawTexture(pixelPos,
						fullFont.getTexture(terminal.getChar(charPos)),
						fgColor
					);
				}
			}
		}
	}
}
