import {
	setPixelsInRect,
	clearScreen,
	fillRect,
} from "./window.ts";
import { Font, font } from "./font.ts";
import { keyDown, keyPressed, keyReleased } from "./keyboard.ts";
import { addToContext, runCode } from "./runcode.ts";
import { resetRepl } from "./repl.ts";
import { COLOR } from "./colors.ts";
import { getSheet, getCodeSheet } from "./sheet.ts";
import { saveCart, loadCart } from "./cart.ts";

let spritesheet: number | null = null;

export const useSpritesheet = (sheet: number) => {
	spritesheet = sheet;
}

export const drawSprite = (x: number, y: number, spr: number) => {
	if (!spritesheet) {
		return;
	}
	const {sheet_type, value: sprites} = getSheet(spritesheet);
	if (sheet_type !== "spritesheet") {
		throw "Trying to run a non-code sheet as code."
	}
	setPixelsInRect(x, y, 8, sprites[spr]);
}

export const drawIcon = (x: number, y: number, icon: Array<number>, color: number) => {
	setPixelsInRect(x, y, 8, icon.map(n => n*color));
}

export const measureCharFont = (char: string, fnt: Font) => {
	return (fnt.chars[char]?.length ?? 0)/fnt.height;
}

export const drawCharFont = (x: number, y: number, char: string, fnt: Font, color: number) => {
	const w = measureCharFont(char, fnt);
	if (!fnt.chars[char]) {
		return 0;
	}
	setPixelsInRect(x, y, w, fnt.chars[char].map(n => n*color));
	return w;
}

export const drawTextFont = (x: number, y: number, text: string, fnt: Font, color?: number) => {
	let dx = 0;
	[...text].forEach((char) => {
		dx += 1+drawCharFont(x+dx, y, char, fnt, color ?? COLOR.WHITE);
	});
	return dx-1;
}

export const measureTextFont = (text: string, fnt: Font) => {
	let w = 0;
	[...text].forEach((char) => {
		w += measureCharFont(char, fnt)+1;
	});
	return Math.max(0, w-1);
}

export const drawText = (x: number, y: number, text: string, color?: number) => {
	return drawTextFont(x, y, text, font, color);
}

export const measureText = (text: string) => {
	return measureTextFont(text, font);
}

const faux = {
	cls: () => {
		resetRepl();
		clearScreen();
	},
	sprsht: useSpritesheet,
	spr: drawSprite,
	txt: drawText,
	rect: fillRect,
	btn: keyDown,
	btnp: keyPressed,
	btnr: keyReleased,
	code: (n: number) => {
		return runCode(getCodeSheet(n));
	},
	log: console.log,
	JSON: JSON,
	save: saveCart,
	load: loadCart,
};

for (const key in faux) {
	addToContext(key, faux[key as keyof typeof faux]);
}

export default faux;