import { clearScreen, fillRect, setPixelColor } from "./window.ts";
import { fontWidth, fontHeight } from "./font.ts";
import { drawText, drawSprite } from "./builtins.ts";
import { COLOR } from "./colors.ts";
import {getSheet, setSheet} from "./sheet.ts";
import { mouseClick, mouseHeld, mousePos } from "./mouse.ts";

const state = {
	selectedSprite: 0,
	selectedColor: 0,
	get sprites() {
		const {sheet_type, value} = getSheet(2);
		if (sheet_type !== "spritesheet") {
			throw "Trying to use a non-sprite sheet as a spritesheet."
		}
		return value;
	},
	set sprites(val) {
		setSheet(0, "spritesheet", val);
	}
}

const paletteX = 88;
const paletteY = 12;
const swatchW = 8;
const swatchH = 8;
const paletteW = 4;
const paletteH = 4;

const spriteX = 8;
const spriteY = 12;
const pixelW = 8;
const pixelH = 8;

const spriteW = 8;
const spriteH = 8;

const sheetX = 0;
const sheetY = 88;
const sheetW = 16;
const sheetH = 4;

const inRect = (x: number, y: number, rectX: number, rectY: number, rectW: number, rectH: number) => {
	return (
		x >= rectX &&
		x < rectX+rectW &&
		y >= rectY &&
		y < rectY+rectH
	)
}

const reGrid = (x: number, y: number, gridX: number, gridY: number, cellW: number, cellH: number) => {
	return {
		x: Math.floor((x-gridX)/cellW),
		y: Math.floor((y-gridY)/cellH),
	}
}

const update = () => {
	if (mouseHeld()) {
		const {x: mouseX, y: mouseY} = mousePos();
		const inPalette = inRect(mouseX, mouseY, paletteX, paletteY, paletteW*swatchW, paletteH*swatchH);
		const inSprite = inRect(mouseX, mouseY, spriteX, spriteY, spriteW*pixelW, spriteH*pixelH);
		const inSheet = inRect(mouseX, mouseY, sheetX, sheetY, sheetW*spriteW, sheetH*spriteH);
		if (inPalette) {
			const {x, y} = reGrid(mouseX, mouseY, paletteX, paletteY, swatchW, swatchH);
			state.selectedColor = paletteW*y+x;
		}
		if (inSprite) {
			const {x, y} = reGrid(mouseX, mouseY, spriteX, spriteY, pixelW, pixelH);
			const pixelNumber = spriteW*y+x;
			state.sprites[state.selectedSprite][pixelNumber] = state.selectedColor;
		}
		if (inSheet) {
			const {x, y} = reGrid(mouseX, mouseY, sheetX, sheetY, spriteW, spriteH);
			state.selectedSprite = sheetW*y+x;
		}
	}
}

const draw = () => {
	const {sprites, selectedSprite, selectedColor} = state;
	clearScreen();
	fillRect(0, 8, 128, 112, COLOR.BROWN);

	// Draw the palette
	fillRect(paletteX-1, paletteY-1, (paletteW*swatchW)+2, (paletteH*swatchH)+2, COLOR.BLACK);
	Object.keys(COLOR).forEach((name, i) => {
		const swatchX = paletteX+swatchW*(i%paletteW);
		const swatchY = paletteY+swatchH*Math.floor(i/paletteW);
		fillRect(swatchX, swatchY, swatchW, swatchH, COLOR[name as keyof typeof COLOR]);
		if (i === 0) {
			// transparent
			Array(swatchW*swatchH).fill(0).map((_z, j) => {
				const jx = j%swatchW;
				const jy = Math.floor(j/swatchW);
				setPixelColor(swatchX+jx, swatchY+jy, (jx+jy)%2 ? COLOR.BLACK : COLOR.WHITE);
			})
		}
		if (i === selectedColor) {
			fillRect(swatchX, swatchY, swatchW, 1, COLOR.WHITE);
			fillRect(swatchX, swatchY, 1, swatchH, COLOR.WHITE);
			fillRect(swatchX+swatchW-1, swatchY, 1, swatchH, COLOR.WHITE);
			fillRect(swatchX, swatchY+swatchH-1, swatchW, 1, COLOR.WHITE);
		}
	});

	// Draw the current sprite
	fillRect(spriteX-1, spriteY-1, (spriteW*pixelW)+2, (spriteH*pixelH)+2, COLOR.BLACK);
	sprites[selectedSprite].forEach((pix, i) => {
		fillRect(spriteX+pixelW*(i%spriteW), spriteY+pixelH*Math.floor(i/spriteW), pixelW, pixelH, pix);
	});

	// Draw the spritesheet
	fillRect(sheetX, sheetY-1, (sheetW*spriteW), (sheetH*spriteH)+1, COLOR.BLACK);
	sprites.forEach((_sprite, i) => {
		drawSprite(sheetX+spriteW*(i%sheetW), sheetY+spriteH*Math.floor(i/sheetW), i);
	});
}

export const spritetab = {
	update,
	draw,
}