package gui

// resourcesGui.go provides functions to retrieve icons/emojis from the imageFiles package as fyne canvas images
// It also provides the Choose Emoji page

import "fyne.io/fyne/v2"
import "fyne.io/fyne/v2/container"
import "fyne.io/fyne/v2/widget"
import "fyne.io/fyne/v2/theme"
import "fyne.io/fyne/v2/canvas"
import "fyne.io/fyne/v2/layout"

import "seekia/internal/imageFiles"
import "seekia/internal/helpers"
import "seekia/internal/imagery"

import "bytes"
import "image"
import "errors"


func getIdentityTypeIcon(identityType string, iconSizeShift int)(*canvas.Image, error){

	iconSize := getCustomFyneSize(iconSizeShift)

	if (identityType == "Mate"){
		mateIcon, err := getFyneImageIcon("Mate")
		if (err != nil) { return nil, err }
		mateIcon.SetMinSize(iconSize)
		return mateIcon, nil
	}
	if (identityType == "Host"){
		hostIcon, err := getFyneImageIcon("Host")
		if (err != nil) { return nil, err }
		hostIcon.SetMinSize(iconSize)
		return hostIcon, nil
	}
	if (identityType == "Moderator"){
		moderatorIcon, err := getFyneImageIcon("Moderate")
		if (err != nil) { return nil, err }
		moderatorIcon.SetMinSize(iconSize)
		return moderatorIcon, nil
	}

	return nil, errors.New("getIdentityTypeIcon called with invalid identityType: " + identityType)
}

func getFyneImageIcon(iconName string)(*canvas.Image, error){

	iconFileBytes, err := imageFiles.GetIconFileBytesFromName(iconName)
	if (err != nil) { return nil, err }

	iconImageObject, err := getFyneImageFromFileBytes(iconFileBytes, "SVG")
	if (err != nil) { return nil, err }

	return iconImageObject, nil
}


//Outputs:
//	-image.Image
//	-error (will return err if file cannot be read)
func getEmojiImageObject(emojiIdentifier int)(image.Image, error){

	emojiFileBytes, err := imageFiles.GetEmojiFileBytesFromIdentifier(emojiIdentifier)
	if (err != nil) { return nil, err }

	golangImageObject, err := imagery.ConvertSVGImageFileBytesToGolangImage(emojiFileBytes)
	if (err != nil) { return nil, err }

	return golangImageObject, nil
}



func getFyneImageFromFileBytes(imageFileBytes []byte, fileType string)(*canvas.Image, error){

	if (fileType != "SVG" && fileType != "PNG"){
		return nil, errors.New("getFyneImageFromFileBytes called with invalid fileType: " + fileType)
	}

	randomString, err := helpers.GetNewRandomHexString(16)
	if (err != nil) { return nil, err }

	fileReader := bytes.NewReader(imageFileBytes)

	getFileExtention := func()string{
		if (fileType == "SVG"){
			return ".svg"
		}
		// fileType == PNG
		return ".png"
	}

	fileExtention := getFileExtention()

	randomFileName := randomString + fileExtention
	iconImageObject := canvas.NewImageFromReader(fileReader, randomFileName)
	iconImageObject.FillMode = canvas.ImageFillContain

	return iconImageObject, nil
}

func getColorSquareAsFyneImage(colorCode string)(*canvas.Image, error){

	colorSquareGoImage, err := imagery.GetColorSquare(colorCode)
	if (err != nil) { return nil, err }

	fyneImageObject := canvas.NewImageFromImage(colorSquareGoImage)
	fyneImageObject.FillMode = canvas.ImageFillContain

	return fyneImageObject, nil
}


func setChooseEmojiPage(window fyne.Window, pageTitle string, currentCategory string, emojiIndex int, previousPage func(), nextPage func(int)){

	setLoadingScreen(window, pageTitle, "Loading Emojis...")

	title := getPageTitleCentered(pageTitle)

	backButton := getBackButtonCentered(previousPage)

	emojiCategoriesList := imageFiles.GetEmojiCategoriesList()

	handleCategorySelectFunction := func(newCategory string){
		if (currentCategory == newCategory){
			return
		}

		setChooseEmojiPage(window, pageTitle, newCategory, 0, previousPage, nextPage)
	}

	categorySelector := widget.NewSelect(emojiCategoriesList, handleCategorySelectFunction)
	categorySelector.Selected = currentCategory

	categoryLabel := widget.NewLabel("Category:")

	categorySelectorRow := container.NewHBox(layout.NewSpacer(), categoryLabel, categorySelector, layout.NewSpacer())

	emojisInCategoryList, err := imageFiles.GetEmojisInCategoryList(currentCategory)
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	finalPageIndex := len(emojisInCategoryList) - 10	

	// This returns an index that represents the beginning of a page, if emoji index is out of bounds
	getPageIndex := func()int{

		if (emojiIndex <= 0){
			return 0
		}
		if (emojiIndex >= finalPageIndex){
			return finalPageIndex
		}
		return emojiIndex
	}

	pageIndex := getPageIndex()

	getFirstPageButton := func()fyne.Widget{
		if (emojiIndex <= 0){
			emptyButton := widget.NewButton(" ", nil)
			return emptyButton
		}
		firstPageButton := widget.NewButtonWithIcon("", theme.MediaFastRewindIcon(), func(){
				setChooseEmojiPage(window, pageTitle, currentCategory, 0, previousPage, nextPage)
			})
		return firstPageButton
	}

	firstPageButton := getFirstPageButton()

	getPreviousPageButton := func()fyne.Widget{
		if (emojiIndex <= 0){
			emptyButton := widget.NewButton(" ", nil)
			return emptyButton
		}
		backButton := widget.NewButtonWithIcon("", theme.NavigateBackIcon(), func(){
				setChooseEmojiPage(window, pageTitle, currentCategory, emojiIndex-10, previousPage, nextPage)
			})
		return backButton
	}

	previousPageButton := getPreviousPageButton()
	
	getNextPageButton := func()fyne.Widget{

		if (emojiIndex >= finalPageIndex){
			emptyButton := widget.NewButton(" ", nil)
			return emptyButton
		}

		nextButton := widget.NewButtonWithIcon("", theme.NavigateNextIcon(), func(){
			setChooseEmojiPage(window, pageTitle, currentCategory, emojiIndex+10, previousPage, nextPage)
		})

		return nextButton
	}

	nextPageButton := getNextPageButton()

	getFinalPageButton := func()fyne.Widget{

		if (emojiIndex >= finalPageIndex){
			emptyButton := widget.NewButton(" ", nil)
			return emptyButton
		}

		finalPageButton := widget.NewButtonWithIcon("", theme.MediaFastForwardIcon(), func(){
			setChooseEmojiPage(window, pageTitle, currentCategory, finalPageIndex, previousPage, nextPage)
		})

		return finalPageButton
	}

	finalPageButton := getFinalPageButton()

	numberOfPages := len(emojisInCategoryList)/10
	numberOfPagesString := helpers.ConvertIntToString(numberOfPages)

	currentPage := (pageIndex/10) +1
	currentPageString := helpers.ConvertIntToString(currentPage)

	pageLabel := getBoldLabel("Page " + currentPageString + "/" + numberOfPagesString)

	navigationRow := container.NewHBox(layout.NewSpacer(), firstPageButton, previousPageButton, pageLabel, nextPageButton, finalPageButton, layout.NewSpacer())

	getEmojisGrid := func()(*fyne.Container, error){	

		emojisGrid := container.NewGridWithColumns(5)

		finalIndex := len(emojisInCategoryList) - 1

		counter := 0

		for i := pageIndex; i <= finalIndex; i++{
	
			currentEmojiIdentifier := emojisInCategoryList[i]

			emojiImage, err := getEmojiImageObject(currentEmojiIdentifier)
			if (err != nil){ return nil, err }

			emojiFyneImage := canvas.NewImageFromImage(emojiImage)
			emojiFyneImage.FillMode = canvas.ImageFillContain

			chooseButton := widget.NewButtonWithIcon("Select", theme.ConfirmIcon(), func(){
					nextPage(currentEmojiIdentifier)
				})

			emojiCell := getContainerBoxed(container.NewBorder(nil, chooseButton, nil, nil, emojiFyneImage))

			emojisGrid.Add(emojiCell)

			counter += 1

			if (counter >= 10){
				break
			}
		}

		return emojisGrid, nil
	}

	emojisGrid, err := getEmojisGrid()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	header := container.NewVBox(title, backButton, widget.NewSeparator(), categorySelectorRow, widget.NewSeparator(), navigationRow)
	
	page := container.NewBorder(header, nil, nil, nil, emojisGrid)

	setPageContent(page, window)
}


