package main

import (
	h "git.bullercodeworks.com/brian/adventofcode/helpers"
)

type Tile struct {
	Num       int
	Data      [][]bool
	Neighbors map[h.Coordinate]*Tile
}

func NewTile(num int, lines []string) *Tile {
	t := Tile{
		Num:       num,
		Neighbors: make(map[h.Coordinate]*Tile),
	}
	for y := range lines {
		var lineData []bool
		for x := range lines[y] {
			lineData = append(lineData, lines[y][x] == '#')
		}
		t.Data = append(t.Data, lineData)
	}
	return &t
}

func (t *Tile) Rotate() {
	t.Data = RotateMap(t.Data)
}

func (t *Tile) Flip() {
	t.Data = FlipMap(t.Data)
}

func (t *Tile) IsEastNeighbor(wrk *Tile) bool {
	size := len(t.Data)
	for y := range t.Data {
		if t.Data[y][size-1] != wrk.Data[y][0] {
			return false
		}
	}
	return true
}

func (t *Tile) IsSouthNeighbor(wrk *Tile) bool {
	size := len(t.Data)
	for x := range t.Data[size-1] {
		if t.Data[size-1][x] != wrk.Data[0][x] {
			return false
		}
	}
	return true
}

func (t *Tile) IsNeighbor(wrk *Tile, canChange bool) bool {
	for _, c := range []h.Coordinate{N, E, S, W} {
		if _, ok := t.Neighbors[c]; ok {
			continue
		}
		for i := 0; i < 8; i++ {
			if c == E && t.IsEastNeighbor(wrk) {
				t.Neighbors[E] = wrk
				wrk.Neighbors[W] = t
				return true
			}
			if c == W && wrk.IsEastNeighbor(t) {
				t.Neighbors[W] = wrk
				wrk.Neighbors[E] = t
				return true
			}
			if c == S && t.IsSouthNeighbor(wrk) {
				t.Neighbors[S] = wrk
				wrk.Neighbors[N] = t
				return true
			}
			if c == N && wrk.IsSouthNeighbor(t) {
				t.Neighbors[N] = wrk
				wrk.Neighbors[S] = t
				return true
			}
			if !canChange {
				break
			}
			if i&1 == 0 {
				wrk.Flip()
			} else {
				wrk.Flip()
				wrk.Rotate()
			}
		}
	}
	return false
}
