package quadtree

// NoVoidGetContent remplit le tableau contentHolder sans jamais afficher de vide ;
// il "répète" le terrain à l'infini
func (q Quadtree) NoVoidGetContent(topLeftX, topLeftY int, contentHolder [][]int) {

	// Cas de bases //
	if len(contentHolder) == 0 {
		return
	} else if len(contentHolder[0]) == 0 {
		return
	}

	// Toutes les cases sont mises à -1 par défaut, en attendant la récupération par NoVoidGetNodeContent //
	for i := 0; i < len(contentHolder); i++ {
		for j := 0; j < len(contentHolder[0]); j++ {
			contentHolder[i][j] = -1
		}
	}

	// Définis les valeurs de topLeftY et topLeftX des nodes qu'on souhaite récupérer pour le topLeftY et topLeftX de l'écran
	autorisesY := []int{}
	for i := topLeftY; i < len(contentHolder)+topLeftY; i++ {
		j := i
		for j < 0 {
			j += q.height
		}
		autorisesY = append(autorisesY, j%q.height)
	}

	autorisesX := []int{}
	for i := topLeftX; i < len(contentHolder[0])+topLeftX; i++ {
		j := i
		for j < 0 {
			j += q.width
		}
		autorisesX = append(autorisesX, j%q.width)
	}

	NoVoidGetNodeContent(q.root, topLeftX, topLeftY, contentHolder, autorisesY, autorisesX)
}

func NoVoidGetNodeContent(n *node, Origine_X, Origine_Y int, contentHolder [][]int, autorisesY, autorisesX []int) {

	// Cas de base //
	if n.isLeaf {
		for i := 0; i < n.height; i++ {
			for j := 0; j < n.width; j++ {
				if elemInLst(n.topLeftY+i, autorisesY) && elemInLst(n.topLeftX+j, autorisesX) {
					contentHolder[findInd(n.topLeftY+i, autorisesY)][findInd(n.topLeftX+j, autorisesX)] = n.content
				}

			}
		}
	} else {
		// Cas récursif //
		NoVoidGetNodeContent(n.topLeftNode, Origine_X, Origine_Y, contentHolder, autorisesY, autorisesX)
		NoVoidGetNodeContent(n.topRightNode, Origine_X, Origine_Y, contentHolder, autorisesY, autorisesX)
		NoVoidGetNodeContent(n.bottomLeftNode, Origine_X, Origine_Y, contentHolder, autorisesY, autorisesX)
		NoVoidGetNodeContent(n.bottomRightNode, Origine_X, Origine_Y, contentHolder, autorisesY, autorisesX)
	}
}

// Fonction utilitaire : vérifie l'existence d'un entier dans une liste d'entiers
func elemInLst(x int, lst []int) bool {
	for i := 0; i < len(lst); i++ {
		if lst[i] == x {
			return true
		}
	}
	return false
}

// Fonction utilitaire : si un entier existe dans une liste d'entiers, donne sa position dans la liste
func findInd(x int, lst []int) int {
	if elemInLst(x, lst) {
		ind := 0
		for i := 0; i < len(lst); i++ {
			if lst[i] == x {
				return ind
			}
			ind++
		}
	}
	return -1
}
