package game

import (
	"tetris/engine/core"
	"tetris/engine/graphics"
)

type Shape struct {
	typ         ShapeType
	coordinates [3]core.Vec2i8
}

func NewShape(typ ShapeType) Shape {
	var coordinates [3]core.Vec2i8

	switch typ {
	case SHAPE_O:
		coordinates = [3]core.Vec2i8{{X: 0, Y: 1}, {X: 1, Y: 0}, {X: 1, Y: 1}}
	case SHAPE_L:
		coordinates = [3]core.Vec2i8{{X: 0, Y: -1}, {X: 0, Y: 1}, {X: 1, Y: 1}}
	case SHAPE_J:
		coordinates = [3]core.Vec2i8{{X: 0, Y: -1}, {X: 0, Y: 1}, {X: -1, Y: 1}}
	case SHAPE_T:
		coordinates = [3]core.Vec2i8{{X: -1, Y: 0}, {X: 1, Y: 0}, {X: 0, Y: 1}}
	case SHAPE_Z:
		coordinates = [3]core.Vec2i8{{X: 1, Y: 0}, {X: 0, Y: -1}, {X: -1, Y: -1}}
	case SHAPE_S:
		coordinates = [3]core.Vec2i8{{X: -1, Y: 0}, {X: 0, Y: -1}, {X: 1, Y: -1}}
	case SHAPE_I:
		coordinates = [3]core.Vec2i8{{X: 0, Y: 1}, {X: 0, Y: -1}, {X: 0, Y: -2}}
	}

	return Shape{
		typ:         typ,
		coordinates: coordinates,
	}
}

func (s Shape) Type() ShapeType {
	return s.typ
}

func (s Shape) GetBlock() Block {
	return s.typ.GetBlock()
}

func (s Shape) Tile() graphics.Tile {
	return s.GetBlock().Tile()
}

func (s Shape) Coordinates() [4]core.Vec2i8 {
	return [4]core.Vec2i8{
		{}, // first coordinate is always zero
		s.coordinates[0],
		s.coordinates[1],
		s.coordinates[2],
	}
}

func (s Shape) RotateCW() Shape {
	rotated := [3]core.Vec2i8{}

	for i, block := range s.coordinates {
		block.X, block.Y = -1*block.Y, block.X
		rotated[i] = block
	}
	return Shape{
		typ:         s.typ,
		coordinates: rotated,
	}
}

func (s Shape) RotateCCW() Shape {
	rotated := [3]core.Vec2i8{}

	for i, block := range s.coordinates {
		block.X, block.Y = block.Y, -1*block.X
		rotated[i] = block
	}
	return Shape{
		typ:         s.typ,
		coordinates: rotated,
	}
}
