package game

import (
	"tetris/engine/graphics"
)

const (
	GRID_WIDTH  = 10
	GRID_HEIGHT = 16
)

type Grid [GRID_WIDTH * GRID_HEIGHT]Block

func (Grid) Width() int32 {
	return GRID_WIDTH
}

func (Grid) Height() int32 {
	return GRID_HEIGHT
}

func (g Grid) At(x, y byte) Block {
	return g[uint16(x)+(uint16(y)*GRID_WIDTH)]
}

func (g Grid) Tile(x, y byte) graphics.Tile {
	return g.At(x, y).Tile()
}

func (g *Grid) Set(x, y byte, c Block) {
	(*g)[uint16(x)+(uint16(y)*GRID_WIDTH)] = c
}

func (g *Grid) ClearFullRows() byte {
	completed := byte(0)
	for y := int(g.Height() - 1); y >= 0; y-- {
		if g.IsRowFull(byte(y)) {
			completed++
			g.ClearRow(byte(y))
		} else if completed > 0 {
			g.MoveRowDown(byte(y), completed)
		}
	}
	return completed
}

func (g *Grid) IsRowFull(y byte) bool {
	for x := range byte(g.Width()) {
		if g.At(x, y) == BLOCK_EMPTY {
			return false
		}
	}
	return true
}

func (g *Grid) MoveRowDown(y, num_rows byte) {
	w := uint16(g.Width())
	src := uint16(y) * w
	dst := uint16(y+num_rows) * w
	copy(g[dst:dst+w], g[src:src+w])
	clear(g[src : src+w])
}

func (g *Grid) ClearRow(y byte) {
	w := uint16(g.Width())
	n := uint16(y) * w
	clear(g[n : n+w])
}
