package floor

import (
	"github.com/hajimehoshi/ebiten/v2"
	"gitlab.univ-nantes.fr/jezequel-l/quadtree/configuration"
)

/// EXTENSION 12 : zoom / dézoom ///

// zoom gère le zoom et le dézoom de l'écran, en fonction de la position de la caméra
// et du terrain
func (f *Floor) zoom(topLeftX, topLeftY, camXPos, camYPos int) (updatedX, updatedY int, canMove bool) {

	canMove = true

	// Dézoom //
	if ebiten.IsKeyPressed(ebiten.KeyR) {

		tab := make([]int, len(f.content[0]))
		nb_dezoomY := 0
		nb_dezoomX := 0

		if len(f.content) < f.QuadtreeContent.GetHeight() || len(f.content[0]) < f.QuadtreeContent.GetWidth() && len(f.content) < 50 && len(f.content[0]) < 50 {

			// Note : extensions partiellement incompatibles
			if configuration.Global.Extension11 {

				// Dézoom haut //
				if len(f.content) < f.QuadtreeContent.GetHeight() {
					f.content = append(f.content, tab)
					nb_dezoomY++
					canMove = false

					configuration.Global.ScreenCenterTileY++
					topLeftY--
				}

				// Dézoom bas //
				if len(f.content) < f.QuadtreeContent.GetHeight() {
					f.content = append(f.content, tab)
					nb_dezoomY++
					canMove = false
				}

				// Dézoom gauche //
				if len(f.content[0]) < f.QuadtreeContent.GetWidth() {
					for i := 0; i < len(f.content); i++ {
						f.content[i] = append(f.content[i], 0)
					}
					nb_dezoomX++
					canMove = false

					configuration.Global.ScreenCenterTileX++
					topLeftX--
				}

				// Dézoom droite //
				if len(f.content[0]) < f.QuadtreeContent.GetWidth() {
					for i := 0; i < len(f.content); i++ {
						f.content[i] = append(f.content[i], 0)
					}
					nb_dezoomX++
					canMove = false
				}

			} else {
				// Dézoom haut //
				if topLeftY > 0 {
					f.content = append(f.content, tab)
					nb_dezoomY++
					canMove = false

					configuration.Global.ScreenCenterTileY++
					topLeftY--
				}

				// Dézoom bas //
				if topLeftY+len(f.content) < f.QuadtreeContent.GetHeight() {
					f.content = append(f.content, tab)
					nb_dezoomY++
					canMove = false
				}

				// Dézoom gauche //
				if topLeftX > 0 {
					for i := 0; i < len(f.content); i++ {
						f.content[i] = append(f.content[i], 0)
					}
					nb_dezoomX++
					canMove = false

					configuration.Global.ScreenCenterTileX++
					topLeftX--
				}

				// Dézoom droite //
				if topLeftX+len(f.content[0]) < f.QuadtreeContent.GetWidth() {
					for i := 0; i < len(f.content); i++ {
						f.content[i] = append(f.content[i], 0)
					}
					nb_dezoomX++
					canMove = false
				}
			}

			configuration.Global.ScreenWidth += configuration.Global.TileSize * nb_dezoomX
			configuration.Global.ScreenHeight += configuration.Global.TileSize * nb_dezoomY
			configuration.Global.NumTileY += nb_dezoomY
			configuration.Global.NumTileX += nb_dezoomX
			f.QuadtreeContent.GetContent(topLeftX, topLeftY, f.content)
		}

		// Zoom //
	} else if ebiten.IsKeyPressed(ebiten.KeyE) {

		nb_zoomX := 0
		nb_zoomY := 0

		// Zoom bas //
		if len(f.content) > 3 && camYPos < topLeftY+len(f.content)-2 {
			f.content = reduction(f.content, 0, len(f.content)-1, 0, len(f.content[0]))
			nb_zoomY++
			canMove = false
		}

		// Zoom haut //
		if len(f.content) > 3 && camYPos > topLeftY+1 {
			f.content = reduction(f.content, 1, len(f.content), 0, len(f.content[0]))
			nb_zoomY++
			canMove = false

			topLeftY++
			configuration.Global.ScreenCenterTileY--
		}

		// Zoom droite //
		if len(f.content[0]) > 3 && camXPos < topLeftX+len(f.content[0])-2 {
			f.content = reduction(f.content, 0, len(f.content), 0, len(f.content[0])-1)
			nb_zoomX++
			canMove = false
		}

		// Zoom gauche //
		if len(f.content[0]) > 3 && camXPos > topLeftX+1 {
			f.content = reduction(f.content, 0, len(f.content), 1, len(f.content[0]))
			nb_zoomX++
			canMove = false

			topLeftX++
			configuration.Global.ScreenCenterTileX--
		}

		configuration.Global.ScreenWidth -= configuration.Global.TileSize * nb_zoomX
		configuration.Global.ScreenHeight -= configuration.Global.TileSize * nb_zoomY
		configuration.Global.NumTileY -= nb_zoomY
		configuration.Global.NumTileX -= nb_zoomX
		f.QuadtreeContent.GetContent(topLeftX, topLeftY, f.content)
	}
	return topLeftX, topLeftY, canMove
}

// Fonction intermédiaire servant à couper des lignes ou colonnes d'un tableau
func reduction(tab [][]int, startY, endY, startX, endX int) (reducedContent [][]int) {
	for i := startY; i < endY; i++ {
		reducedContent = append(reducedContent, []int{})
		for j := startX; j < endX; j++ {
			reducedContent[i-startY] = append(reducedContent[i-startY], tab[i][j])
		}
	}
	return reducedContent
}
