
package gui

// buildProfileGui_Mental.go implements pages to build the Mental portion of a mate profile

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

import "seekia/internal/allowedText"
import "seekia/internal/helpers"
import "seekia/internal/profiles/myLocalProfiles"
import "seekia/internal/worldLanguages"

import "strings"
import "errors"


func setBuildMateProfileCategoryPage_Mental(window fyne.Window, previousPage func()){

	currentPage := func(){setBuildMateProfileCategoryPage_Mental(window, previousPage)}

	title := getPageTitleCentered(translate("Build Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	languageButton := widget.NewButton(translate("Language"), func(){
			setBuildMateProfilePage_Language(window, currentPage)
		})

	beliefsButton := widget.NewButton(translate("Beliefs"), func(){
			setBuildMateProfilePage_Beliefs(window, currentPage)
		})

	genderIdentityButton := widget.NewButton(translate("Gender Identity"), func(){
			setBuildMateProfilePage_GenderIdentity(window, currentPage)
		})

	petsButton := widget.NewButton(translate("Pets"), func(){
			setBuildMateProfilePage_Pets(window, currentPage)
		})

	buttonsGrid := container.NewGridWithColumns(1, languageButton, beliefsButton, genderIdentityButton, petsButton)

	buttonsGridCentered := getContainerCentered(buttonsGrid)

	buttonsGridPadded := container.NewPadded(buttonsGridCentered)

	page := container.NewVBox(title, backButton, widget.NewSeparator(), buttonsGridPadded)

	setPageContent(page, window)
}


func setBuildMateProfilePage_Language(window fyne.Window, previousPage func()){

	currentPage := func(){setBuildMateProfilePage_Language(window, previousPage)}

	title := getPageTitleCentered(translate("Build Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	subtitle := getPageSubtitleCentered("Language")

	description1 := getLabelCentered("Select the languages you understand.")
	description2 := getLabelCentered("Rate your ability to understand each language.")
	description3 := getLabelCentered("1 = Low fluency, 5 = High fluency")

	myLanguagesAttributeExists, myLanguagesAttribute, err := myLocalProfiles.GetProfileData("Mate", "Language")
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return	
	}

	addLanguageButton := getWidgetCentered(widget.NewButtonWithIcon("Add Language", theme.ContentAddIcon(), func(){
			setBuildMateProfilePage_ChooseLanguage(window, currentPage, currentPage)
		}))

	if (myLanguagesAttributeExists == false){
			
		noLanguagesExistLabel := getBoldLabelCentered("No Languages Exist.")

		page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), description1, description2, description3, widget.NewSeparator(), noLanguagesExistLabel, addLanguageButton)
		setPageContent(page, window)
		return
	}

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

		worldLanguageObjectsMap, err := worldLanguages.GetWorldLanguageObjectsMap()
		if (err != nil) { return nil, err }

		languageNameLabel := getItalicLabelCentered(translate("Language Name"))	

		fluencyLabel := getItalicLabelCentered(translate("Fluency"))

		emptyLabel := widget.NewLabel("")

		languageDescriptionsColumn := container.NewVBox(languageNameLabel, widget.NewSeparator())
		languageRatingsColumn := container.NewVBox(fluencyLabel, widget.NewSeparator())
		manageLanguageButtonsColumn := container.NewVBox(emptyLabel, widget.NewSeparator())	

		myLanguageItemsList := strings.Split(myLanguagesAttribute, "+&")

		for _, languageItem := range myLanguageItemsList{

			languageName, languageRating, delimiterFound := strings.Cut(languageItem, "$")
			if (delimiterFound == false){
				return nil, errors.New("MyLocalProfiles contains invalid language item: missing $: " + languageItem)
			}

			languageRatingInt, err := helpers.ConvertStringToInt(languageRating)
			if (err != nil){
				return nil, errors.New("MyLocalProfiles contains invalid language item: Language rating not an int: " + languageRating)	
			}

			if (languageRatingInt < 1 || languageRatingInt > 5){
				return nil, errors.New("MyLocalProfiles contains invalid language item: Language rating is invalid: " + languageRating)
			}

			getLanguageDescription := func()string{

				languageObject, exists := worldLanguageObjectsMap[languageName]
				if (exists == false){
					// Language name must be custom
					return languageName
				}

				languageNamesList := languageObject.NamesList

				languageDescription := helpers.TranslateAndJoinStringListItems(languageNamesList, "/")

				return languageDescription
			}

			languageDescription := getLanguageDescription()

			languageDescriptionLabel := getBoldLabelCentered(languageDescription)

			languageRatingLabel := getBoldLabelCentered(languageRating + "/5")

			manageLanguageButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
					setBuildMateProfilePage_ManageLanguage(window, languageName, currentPage, currentPage)
				})

			languageDescriptionsColumn.Add(languageDescriptionLabel)
			languageRatingsColumn.Add(languageRatingLabel)
			manageLanguageButtonsColumn.Add(manageLanguageButton)

			languageDescriptionsColumn.Add(widget.NewSeparator())
			languageRatingsColumn.Add(widget.NewSeparator())
			manageLanguageButtonsColumn.Add(widget.NewSeparator())
		}

		languagesGrid := container.NewHBox(layout.NewSpacer(), languageDescriptionsColumn, languageRatingsColumn, manageLanguageButtonsColumn,  layout.NewSpacer())

		return languagesGrid, nil
	}

	languagesGrid, err := getLanguagesGrid()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), description1, description2, description3, widget.NewSeparator(), addLanguageButton, widget.NewSeparator(), languagesGrid)

	setPageContent(page, window)
}


func setBuildMateProfilePage_ChooseLanguage(window fyne.Window, previousPage func(), onCompletePage func()){

	currentPage := func(){setBuildMateProfilePage_ChooseLanguage(window, previousPage, onCompletePage)}

	title := getPageTitleCentered(translate("Build Mate Profile - Mental"))	

	backButton := getBackButtonCentered(previousPage)

	subtitle := getPageSubtitleCentered("Choose Language")

	description1 := getLabelCentered("Choose a language.")
	description2 := getLabelCentered("If your language is not listed, select Language Is Missing.")

	worldLanguageObjectsList, err := worldLanguages.GetWorldLanguageObjectsList()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	// This list stores the translated language names
	worldLanguageDescriptionsList := make([]string, 0, len(worldLanguageObjectsList))

	// This map will store the language names
	// If a language has multiple names, the first name is used
	//Map Structure: Language Description -> Language primary name
	worldLanguageNamesMap := make(map[string]string)

	for _, languageObject := range worldLanguageObjectsList{

		languageNamesList := languageObject.NamesList

		languagePrimaryName := languageNamesList[0]

		languageDescription := helpers.TranslateAndJoinStringListItems(languageNamesList, "/")
		
		worldLanguageDescriptionsList = append(worldLanguageDescriptionsList, languageDescription)

		worldLanguageNamesMap[languageDescription] = languagePrimaryName
	}

	helpers.SortStringListToUnicodeOrder(worldLanguageDescriptionsList)

	onSelectedFunction := func(itemIndex int){

		languageDescription := worldLanguageDescriptionsList[itemIndex]

		languagePrimaryName, exists := worldLanguageNamesMap[languageDescription]
		if (exists == false){
			setErrorEncounteredPage(window, errors.New("worldLanguageNamesMap missing languageDescription"), currentPage)
			return
		}

		setBuildMateProfilePage_AddLanguage(window, languagePrimaryName, currentPage, onCompletePage)
	}

	languagesWidgetList, err := getFyneWidgetListFromStringList(worldLanguageDescriptionsList, onSelectedFunction)
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	languageIsMissingButton := getWidgetCentered(widget.NewButton("Language Is Missing", func(){
			setBuildMateProfilePage_EnterCustomLanguage(window, currentPage, onCompletePage)
		}))

	header := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), description1, description2, widget.NewSeparator())

	page := container.NewBorder(header, languageIsMissingButton, nil, nil, languagesWidgetList)

	setPageContent(page, window)
}

func setBuildMateProfilePage_EnterCustomLanguage(window fyne.Window, previousPage func(), onCompletePage func()){

	currentPage := func(){setBuildMateProfilePage_EnterCustomLanguage(window, previousPage, onCompletePage)}

	title := getPageTitleCentered(translate("Buid Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	subtitle := getPageSubtitleCentered("Add Custom Language")

	description := widget.NewLabel("Enter your custom language.")

	languageEntry := widget.NewEntry()
	languageEntry.SetPlaceHolder(translate("Enter language..."))

	languageEntryWithDescription := getContainerCentered(container.NewGridWithColumns(1, description, languageEntry))

	submitButton := getWidgetCentered(widget.NewButtonWithIcon("Submit", theme.ConfirmIcon(), func(){

			newLanguage := languageEntry.Text

			if (newLanguage == ""){
				dialogTitle := translate("Language Is Empty.")
				dialogMessage := getLabelCentered(translate("You must provide a language."))
				dialogContent := container.NewVBox(dialogMessage)
				dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
				return
			}

			if (len(newLanguage) > 30){
				dialogTitle := translate("Language Is Too Long.")
				dialogMessage := getLabelCentered(translate("Language cannot be longer than 30 bytes."))
				dialogContent := container.NewVBox(dialogMessage)
				dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
				return
			}

			isAllowed := allowedText.VerifyStringIsAllowed(newLanguage)
			if (isAllowed == false){
				dialogTitle := translate("Invalid Language")
				dialogMessageA := getLabelCentered(translate("Your language contains an invalid character."))
				dialogMessageB := getLabelCentered(translate("It must be encoded in UTF-8."))
				dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
				dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
				return
			}

			containsTabsOrNewlines := helpers.CheckIfStringContainsTabsOrNewlines(newLanguage)
			if (containsTabsOrNewlines == true){
				dialogTitle := translate("Invalid Language")
				dialogMessageA := getLabelCentered(translate("Your language contains a tab or a newline character."))
				dialogMessageB := getLabelCentered(translate("Remove the character and resubmit."))
				dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
				dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
				return
			}

			containsDelimiter := strings.Contains(newLanguage, "+&")
			if (containsDelimiter == true){
				dialogTitle := translate("Cannot Add Language.")
				dialogMessageA := getLabelCentered(translate("Language contains invalid substring: " + `"+&"`))
				dialogMessageB := getLabelCentered(translate("Remove this substring and resubmit."))
				dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
				dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
				return
			}

			containsDelimiter = strings.Contains(newLanguage, "$")
			if (containsDelimiter == true){
				dialogTitle := translate("Cannot Add Language.")
				dialogMessageA := getLabelCentered(translate("Language contains invalid substring: " + `"$"`))
				dialogMessageB := getLabelCentered(translate("Remove this substring and resubmit."))
				dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
				dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
				return
			}

			setBuildMateProfilePage_AddLanguage(window, newLanguage, currentPage, onCompletePage)
		}))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), languageEntryWithDescription, submitButton)

	setPageContent(page, window)
}


func setBuildMateProfilePage_AddLanguage(window fyne.Window, languagePrimaryName string, previousPage func(), onCompletePage func()){

	currentPage := func(){setBuildMateProfilePage_AddLanguage(window, languagePrimaryName, previousPage, onCompletePage)}

	title := getPageTitleCentered(translate("Build Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	subtitle := getPageSubtitleCentered("Add Language")

	languageNameLabel := getLabelCentered("Language Name:")

	getLanguageNameText := func()(string, error){

		worldLanguageObjectsMap, err := worldLanguages.GetWorldLanguageObjectsMap()
		if (err != nil) { return "", err }

		languageObject, exists := worldLanguageObjectsMap[languagePrimaryName]
		if (exists == false){
			// Language name must be custom
			return languagePrimaryName, nil
		}

		languageNamesList := languageObject.NamesList

		languageNamesListFormatted := helpers.TranslateAndJoinStringListItems(languageNamesList, "/")

		return languageNamesListFormatted, nil
	}

	languageNameText, err := getLanguageNameText()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	languageNameTextLabel := getBoldLabelCentered(languageNameText)

	description1 := getLabelCentered("Choose how well you understand this language.")
	description2 := getLabelCentered("1 = Least Fluency, 5 = Highest Fluency")

	optionsList := []string{"1", "2", "3", "4", "5"}
	fluencySelector := widget.NewSelect(optionsList, nil)

	fluencySelector.PlaceHolder = translate("Select one...")

	fluencySelectorCentered := getWidgetCentered(fluencySelector)

	submitFunction := func(){

		myLanguageAttributeExists, existingMyLanguageAttribute, err := myLocalProfiles.GetProfileData("Mate", "Language")
		if (err != nil){
			setErrorEncounteredPage(window, err, currentPage)
			return
		}

		if (myLanguageAttributeExists == true){
			existingMyLanguageAttributeList := strings.Split(existingMyLanguageAttribute, "+&")

			if (len(existingMyLanguageAttributeList) >= 100){
				dialogTitle := translate("Language Limit Reached.")
				dialogMessage := getLabelCentered(translate("You cannot add more than 100 languages."))
				dialogContent := container.NewVBox(dialogMessage)
				dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
				return
			}
		}

		newLanguageRating := fluencySelector.Selected

		if (newLanguageRating == ""){
			dialogTitle := translate("Missing Language Fluency Rating.")
			dialogMessage := getLabelCentered(translate("You must choose a language fluency rating."))
			dialogContent := container.NewVBox(dialogMessage)
			dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
			return
		}

		newLanguageItem := languagePrimaryName + "$" + newLanguageRating

		getNewLanguageAttribute := func()(string, error){

			if (myLanguageAttributeExists == false){
				return newLanguageItem, nil
			}

			// We check to see if language already exists
			// If so, we replace existing language

			existingMyLanguageAttributeList := strings.Split(existingMyLanguageAttribute, "+&")

			newMyLanguageAttributeList := make([]string, 0)			

			for _, languageItem := range existingMyLanguageAttributeList{

				itemLanguageName, _, delimiterFound := strings.Cut(languageItem, "$")
				if (delimiterFound == false){
					return "", errors.New("MyLocalProfiles contains invalid myLanguage attribute: " + languageItem)
				}

				if (languagePrimaryName == itemLanguageName){
					// Language already exists, we will skip this language item
					continue
				}
				newMyLanguageAttributeList = append(newMyLanguageAttributeList, languageItem)
			}

			newMyLanguageAttributeList = append(newMyLanguageAttributeList, newLanguageItem)

			newMyLanguageAttribute := strings.Join(newMyLanguageAttributeList, "+&")

			return newMyLanguageAttribute, nil
		}

		newLanguageAttribute, err := getNewLanguageAttribute()
		if (err != nil){
			setErrorEncounteredPage(window, err, currentPage)
			return
		}

		err = myLocalProfiles.SetProfileData("Mate", "Language", newLanguageAttribute)
		if (err != nil){
			setErrorEncounteredPage(window, err, currentPage)
			return
		}

		onCompletePage()
	}

	submitButton := getWidgetCentered(widget.NewButtonWithIcon(translate("Submit"), theme.ConfirmIcon(), submitFunction))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), languageNameLabel, languageNameTextLabel, widget.NewSeparator(), description1, description2, widget.NewSeparator(), fluencySelectorCentered, submitButton)

	setPageContent(page, window)
}


func setBuildMateProfilePage_ManageLanguage(window fyne.Window, languagePrimaryName string, previousPage func(), afterDeletePage func()){

	currentPage := func(){setBuildMateProfilePage_ManageLanguage(window, languagePrimaryName, previousPage, afterDeletePage)}

	title := getPageTitleCentered(translate("Build Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	subtitle := getPageSubtitleCentered("Manage Language")

	languageNameLabel := getLabelCentered(translate("Language Name:"))

	getLanguageNameText := func()(string, error){

		worldLanguageObjectsMap, err := worldLanguages.GetWorldLanguageObjectsMap()
		if (err != nil) { return "", err }

		languageObject, exists := worldLanguageObjectsMap[languagePrimaryName]
		if (exists == false){
			// Language name must be custom
			return languagePrimaryName, nil
		}

		languageNamesList := languageObject.NamesList

		languageNamesListFormatted := helpers.TranslateAndJoinStringListItems(languageNamesList, "/")

		return languageNamesListFormatted, nil
	}

	languageNameText, err := getLanguageNameText()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	languageNameTextLabel := getBoldLabelCentered(languageNameText)

	myLanguageAttributeExists, myLanguageAttribute, err := myLocalProfiles.GetProfileData("Mate", "Language")
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}
	if (myLanguageAttributeExists == false){
		setErrorEncounteredPage(window, errors.New("setBuildMateProfilePage_ManageLanguage called when language attribute is empty."), previousPage)
		return
	}

	myLanguageAttributeList := strings.Split(myLanguageAttribute, "+&")

	getMyLanguageCurrentRating := func()(string, error){

		for _, languageItem := range myLanguageAttributeList{

			itemLanguageName, languageRating, delimiterFound := strings.Cut(languageItem, "$")
			if (delimiterFound == false){
				return "", errors.New("MyLocalProfiles contains invalid Location attribute: Missing $: " + languageItem)
			}
			if (itemLanguageName == languagePrimaryName){
				return languageRating, nil
			}
		}

		return "", errors.New("setBuildMateProfilePage_ManageLanguage called when my language rating not found.")
	}

	myCurrentLanguageRating, err := getMyLanguageCurrentRating()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	handleSelectFunction := func(newLanguageRating string){

		if (newLanguageRating == myCurrentLanguageRating){
			return
		}

		newLanguageItem := languagePrimaryName + "$" + newLanguageRating

		newMyLanguageAttributeList := make([]string, 0)

		languageFound := false

		for _, languageItem := range myLanguageAttributeList{

			itemLanguageName, languageRating, delimiterFound := strings.Cut(languageItem, "$")
			if (delimiterFound == false){
				setErrorEncounteredPage(window, errors.New("MyLocalProfiles contains invalid Location attribute: Missing $: " + languageItem), currentPage)
				return
			}
			if (itemLanguageName == languagePrimaryName){

				if (languageFound == true){
					setErrorEncounteredPage(window, errors.New("My mate Language attribute contains duplicate language item."), currentPage)
					return
				}

				if (languageRating == newLanguageRating){
					// We already checked for this earlier. This should not happen
					setErrorEncounteredPage(window, errors.New("languageRating is the same after already checking."), currentPage)
					return
				}
				// We will add the language with the revised rating
				languageFound = true
				newMyLanguageAttributeList = append(newMyLanguageAttributeList, newLanguageItem)
				continue
			}
			newMyLanguageAttributeList = append(newMyLanguageAttributeList, languageItem)
		}

		if (languageFound == false){
			setErrorEncounteredPage(window, errors.New("My language not found after being found already."), currentPage)
			return
		}

		newMyLanguageAttribute := strings.Join(newMyLanguageAttributeList, "+&")

		err = myLocalProfiles.SetProfileData("Mate", "Language", newMyLanguageAttribute)
		if (err != nil){
			setErrorEncounteredPage(window, err, currentPage)
			return
		}

		currentPage()
	}

	selectorOptionsList := []string{"1", "2", "3", "4", "5"}
	fluencySelector := widget.NewSelect(selectorOptionsList, handleSelectFunction)

	fluencySelector.Selected = myCurrentLanguageRating

	fluencyLabel := getLabelCentered("Fluency:")

	fluencySelectorCentered := getWidgetCentered(fluencySelector)

	deleteButton := getWidgetCentered(widget.NewButtonWithIcon("Delete", theme.DeleteIcon(), func(){

			newMyLanguageAttributeList := make([]string, 0)

			for _, languageItem := range myLanguageAttributeList{

				itemLanguageName, _, delimiterFound := strings.Cut(languageItem, "$")
				if (delimiterFound == false){
					setErrorEncounteredPage(window, errors.New("MyLocalProfiles contains invalid Location attribute: Missing $: " + languageItem), currentPage)
					return
				}
				if (itemLanguageName == languagePrimaryName){
					continue
				}
				newMyLanguageAttributeList = append(newMyLanguageAttributeList, languageItem)
			}

			if (len(newMyLanguageAttributeList) != (len(myLanguageAttributeList)-1)){
				setErrorEncounteredPage(window, errors.New("Failed to delete language item."), currentPage)
				return
			}

			if (len(newMyLanguageAttributeList) == 0){

				err = myLocalProfiles.DeleteProfileData("Mate", "Language")
				if (err != nil){
					setErrorEncounteredPage(window, err, currentPage)
					return
				}

				afterDeletePage()
				return
			}

			newMyLanguageAttribute := strings.Join(newMyLanguageAttributeList, "+&")

			err = myLocalProfiles.SetProfileData("Mate", "Language", newMyLanguageAttribute)
			if (err != nil){
				setErrorEncounteredPage(window, err, currentPage)
				return
			}

			afterDeletePage()
		}))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), languageNameLabel, languageNameTextLabel, widget.NewSeparator(), fluencyLabel, fluencySelectorCentered, widget.NewSeparator(), deleteButton)

	setPageContent(page, window)
}



func setBuildMateProfilePage_Beliefs(window fyne.Window, previousPage func()){

	currentPage := func(){setBuildMateProfilePage_Beliefs(window, previousPage)}

	pageTitle := getPageTitleCentered(translate("Build Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	pageSubtitle := getPageSubtitleCentered(translate("Beliefs"))

	description1 := getLabelCentered(translate("Enter your beliefs."))
	description2 := getLabelCentered(translate("Beliefs may include your worldview, religion, and philosophies."))

	currentBeliefsExist, currentBeliefs, err := myLocalProfiles.GetProfileData("Mate", "Beliefs")
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

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

		myBeliefsLabel := widget.NewLabel("My Beliefs:")

		if (currentBeliefsExist == false){

			noResponseLabel := getBoldItalicLabel("No Response")
			currentBeliefsRow := container.NewHBox(layout.NewSpacer(), myBeliefsLabel, noResponseLabel, layout.NewSpacer())

			return currentBeliefsRow, nil
		}

		isAllowed := allowedText.VerifyStringIsAllowed(currentBeliefs)
		if (isAllowed == false){
			return nil, errors.New("Current mate beliefs is not allowed: " + currentBeliefs)
		}

		if( len(currentBeliefs) > 1000){
			return nil, errors.New("Current mate beliefs is too long: " + currentBeliefs)
		}
	
		currentBeliefsTrimmed, _, err := helpers.TrimAndFlattenString(currentBeliefs, 15)
		if (err != nil) { return nil, err }

		currentBeliefsLabel := getBoldLabel(currentBeliefsTrimmed)

		viewMyBeliefsButton := widget.NewButtonWithIcon("", theme.VisibilityIcon(), func(){
				setViewTextPage(window, "Viewing Beliefs", currentBeliefs, false, currentPage)
			})

		currentBeliefsRow := container.NewHBox(layout.NewSpacer(), myBeliefsLabel, currentBeliefsLabel, viewMyBeliefsButton, layout.NewSpacer())

		return currentBeliefsRow, nil
	}

	currentBeliefsRow, err := getMyCurrentBeliefsRow()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	editButton := widget.NewButtonWithIcon("Edit", theme.DocumentCreateIcon(), func(){
			setBuildMateProfilePage_EditBeliefs(window, currentPage, currentPage)
		})

	noResponseButton := widget.NewButtonWithIcon(translate("No Response"), theme.CancelIcon(), func(){

			if (currentBeliefsExist == false){
				return
			}

			setBuildMateProfilePage_DeleteBeliefs(window, currentPage, currentPage)
		})

	buttonsGrid := getContainerCentered(container.NewGridWithColumns(1, editButton, noResponseButton))
	
	page := container.NewVBox(pageTitle, backButton, widget.NewSeparator(), pageSubtitle, widget.NewSeparator(), description1, description2, widget.NewSeparator(), currentBeliefsRow, widget.NewSeparator(), buttonsGrid)

	setPageContent(page, window)
}


func setBuildMateProfilePage_DeleteBeliefs(window fyne.Window, previousPage func(), nextPage func()){

	title := getPageTitleCentered("Delete Beliefs")

	backButton := getBackButtonCentered(previousPage)

	description1 := getBoldLabelCentered("Delete Beliefs?")
	description2 := getLabelCentered("Confirm to delete your beliefs?")

	confirmButton := getWidgetCentered(widget.NewButtonWithIcon("Delete", theme.DeleteIcon(), func(){
			myLocalProfiles.DeleteProfileData("Mate", "Beliefs")
			nextPage()
		}))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, confirmButton)

	setPageContent(page, window)
}


func setBuildMateProfilePage_EditBeliefs(window fyne.Window, previousPage func(), nextPage func()){

	title := getPageTitleCentered("Edit Mate Beliefs")

	backButton := getBackButtonCentered(previousPage)

	beliefsEntry := widget.NewMultiLineEntry()
	beliefsEntry.Wrapping = 3

	//Outputs:
	//	-bool: Current beliefs exist
	//	-string: Current beliefs
	//	-error
	getCurrentBeliefs := func()(bool, string, error){	

		exists, currentBeliefs, err := myLocalProfiles.GetProfileData("Mate", "Beliefs")
		if (err != nil) { return false, "", err }
		if (exists == false){
			return false, "", nil
		}

		isAllowed := allowedText.VerifyStringIsAllowed(currentBeliefs)
		if (isAllowed == false){
			return false, "", errors.New("My current mate beliefs is not allowed: " + currentBeliefs)
		}

		if(len(currentBeliefs) > 1000){
			return false, "", errors.New("My current mate beliefs is too long: " + currentBeliefs)
		}

		return true, currentBeliefs, nil
	}

	currentBeliefsExist, currentBeliefs, err := getCurrentBeliefs()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	if (currentBeliefsExist == false){
		beliefsEntry.SetPlaceHolder("Enter your beliefs...")
	} else {
		beliefsEntry.SetText(currentBeliefs)
	}

	submitButton := getWidgetCentered(widget.NewButtonWithIcon(translate("Save"), theme.ConfirmIcon(), func(){

		newBeliefs := beliefsEntry.Text

		isAllowed := allowedText.VerifyStringIsAllowed(newBeliefs)
		if (isAllowed == false){
			title := translate("Invalid Beliefs")
			dialogMessageA := getLabelCentered(translate("Your beliefs contain an invalid character"))
			dialogMessageB := getLabelCentered(translate("It must be encoded in UTF-8."))
			dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
			dialog.ShowCustom(title, translate("Close"), dialogContent, window)
			return
		}

		currentBytesLength := len(newBeliefs)
		if (currentBytesLength > 1000){

			currentLengthString := helpers.ConvertIntToString(currentBytesLength)

			title := translate("Invalid Beliefs")

			dialogMessageA := getLabelCentered(translate("Your Beliefs are too long."))
			dialogMessageB := getLabelCentered(translate("Beliefs cannot be longer than 1000 bytes."))
			dialogMessageC := getLabelCentered(translate("Current Length: ")  + currentLengthString)
			dialogContent := container.NewVBox(dialogMessageA, dialogMessageB, dialogMessageC)
			dialog.ShowCustom(title, translate("Close"), dialogContent, window)
			return
		}

		if (newBeliefs == ""){
			myLocalProfiles.DeleteProfileData("Mate", "Beliefs")
		} else {
			myLocalProfiles.SetProfileData("Mate", "Beliefs", newBeliefs)
		}

		nextPage()
	}))

	emptyLabel := widget.NewLabel("")

	submitButtonWithSpacer := container.NewVBox(submitButton, emptyLabel)

	beliefsEntryBoxed := getWidgetBoxed(beliefsEntry)
	
	beliefsEntryWithSubmitButton := container.NewBorder(nil, submitButtonWithSpacer, nil, nil, beliefsEntryBoxed)

	header := container.NewVBox(title, backButton, widget.NewSeparator())

	page := container.NewBorder(header, nil, nil, nil, beliefsEntryWithSubmitButton)

	setPageContent(page, window)
}


func setBuildMateProfilePage_GenderIdentity(window fyne.Window, previousPage func()){
	
	currentPage := func(){setBuildMateProfilePage_GenderIdentity(window, previousPage)}

	title := getPageTitleCentered(translate("Build Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	pageSubtitle := getPageSubtitleCentered(translate("Gender Identity"))

	description1 := getLabelCentered("Enter the gender that you identify as.")
	description2 := getLabelCentered("Choose Man, Woman, or enter a custom value.")	

	standardGendersList := []string{translate("Man"), translate("Woman")}

	genderSelectEntry := widget.NewSelectEntry(standardGendersList)

	myGenderIdentityExists, myGenderIdentity, err := myLocalProfiles.GetProfileData("Mate", "GenderIdentity")
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}
	if (myGenderIdentityExists == true){

		if (len(myGenderIdentity) > 50){
			setErrorEncounteredPage(window, errors.New("MyLocalProfiles contains invalid GenderIdentity: " + myGenderIdentity), previousPage)
			return
		}

		genderSelectEntry.SetText(myGenderIdentity)
	} else {
		genderSelectEntry.SetPlaceHolder(translate("Select or enter gender..."))
	}
	
	getCurrentGenderIdentityLabel := func()fyne.Widget{

		if (myGenderIdentityExists == false){
			result := translate("No Response")

			noResponseLabel := getBoldItalicLabel(result)
			return noResponseLabel
		}

		if (myGenderIdentity == "Man"){
			genderIdentityLabel := getBoldLabel(translate("Man"))
			return genderIdentityLabel
		}
		if (myGenderIdentity == "Woman"){
			genderIdentityLabel := getBoldLabel(translate("Woman"))
			return genderIdentityLabel
		}

		genderIdentityLabel := getBoldLabel(myGenderIdentity)
		return genderIdentityLabel
	}

	currentGenderIdentityLabel := getCurrentGenderIdentityLabel()

	myGenderIdentityLabel := widget.NewLabel("My Gender Identity:")

	currentGenderIdentityRow := container.NewHBox(layout.NewSpacer(), myGenderIdentityLabel, currentGenderIdentityLabel, layout.NewSpacer())

	submitChangesButton := widget.NewButtonWithIcon("Submit", theme.ConfirmIcon(), func(){

		getNewGenderIdentity := func()string{

			newGenderIdentity := genderSelectEntry.Text

			if (newGenderIdentity == translate("Man")){
				return "Man"	
			}
			if (newGenderIdentity == translate("Woman")){
				return "Woman"
			}

			return newGenderIdentity
		}

		newGenderIdentity := getNewGenderIdentity()

		if (newGenderIdentity == ""){
			title := translate("Invalid Gender")
			dialogMessageA := getLabelCentered(translate("Invalid gender entered."))
			dialogMessageB := getLabelCentered(translate("Your gender cannot be empty."))
			dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
			dialog.ShowCustom(title, translate("Close"), dialogContent, window)
			return
		}

		if (len(newGenderIdentity) > 50){

			genderSelectEntry.SetText("")
			genderSelectEntry.SetPlaceHolder(translate("Select or enter gender..."))

			title := translate("Invalid Gender")
			dialogMessageA := getLabelCentered(translate("Invalid gender entered."))
			dialogMessageB := getLabelCentered(translate("It cannot be longer than 50 bytes."))
			dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
			dialog.ShowCustom(title, translate("Close"), dialogContent, window)
			return
		}

		isAllowed := allowedText.VerifyStringIsAllowed(newGenderIdentity)
		if (isAllowed == false){
			title := translate("Invalid Gender")
			dialogMessageA := getLabelCentered(translate("Your gender contains an invalid character."))
			dialogMessageB := getLabelCentered(translate("It must be encoded in UTF-8."))
			dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
			dialog.ShowCustom(title, translate("Close"), dialogContent, window)
			return
		}

		containsTabsOrNewlines := helpers.CheckIfStringContainsTabsOrNewlines(newGenderIdentity)
		if (containsTabsOrNewlines == true){
			dialogTitle := translate("Invalid Gender")
			dialogMessageA := getLabelCentered(translate("Your gender contains a tab or a newline character."))
			dialogMessageB := getLabelCentered(translate("Remove the character and resubmit."))
			dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
			dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
			return
		}

		myLocalProfiles.SetProfileData("Mate", "GenderIdentity", newGenderIdentity)
		currentPage()
	})
	
	genderSelectEntryWithSubmitButton := getContainerCentered(container.NewGridWithRows(1, genderSelectEntry, submitChangesButton))
	
	noResponseButton := getWidgetCentered(widget.NewButtonWithIcon(translate("No Response"), theme.CancelIcon(), func(){ 
			myLocalProfiles.DeleteProfileData("Mate", "GenderIdentity")
			currentPage()
		}))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), pageSubtitle, widget.NewSeparator(), description1, description2, widget.NewSeparator(), currentGenderIdentityRow, widget.NewSeparator(), genderSelectEntryWithSubmitButton, noResponseButton)

	setPageContent(page, window)
}


func setBuildMateProfilePage_Pets(window fyne.Window, previousPage func()){

	currentPage := func(){setBuildMateProfilePage_Pets(window, previousPage)}

	pageTitle := getPageTitleCentered(translate("Build Mate Profile - Mental"))

	backButton := getBackButtonCentered(previousPage)

	pageSubtitle := getPageSubtitleCentered(translate("Pets"))

	description1 := getLabelCentered(translate("Describe how much you enjoy owning pets."))
	description2 := getLabelCentered(translate("1 = Strongly Against, 10 = Strongly Support"))

	optionsList := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}

	handleSelectionFunction := func(response string){
			myLocalProfiles.SetProfileData("Mate", "PetsRating", response)
		}

	petsRatingSelector := widget.NewSelect(optionsList, handleSelectionFunction)

	currentPetsRatingExists, currentPetsRating, err := myLocalProfiles.GetProfileData("Mate", "PetsRating")
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	if (currentPetsRatingExists == true){
		petsRatingSelector.Selected = currentPetsRating
	} else {
		petsRatingSelector.PlaceHolder = translate("Choose rating...")
	}

	petsRatingSelectorCentered := getWidgetCentered(petsRatingSelector)

	petsNoResponseButton := getWidgetCentered(widget.NewButtonWithIcon(translate("No Response"), theme.CancelIcon(), func(){ 
			err := myLocalProfiles.DeleteProfileData("Mate", "PetsRating")
			if (err != nil){
				setErrorEncounteredPage(window, err, currentPage)
				return
			}
			currentPage()
		}))

	description3 := getLabelCentered(translate("Describe how much you enjoy each animal as a pet."))
	description4 := getLabelCentered(translate("1 = Strongly Against, 10 = Strongly Support"))

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

		petsGrid := container.NewGridWithColumns(3)

		petsList := []string{"Dogs", "Cats"}

		for _, petName := range petsList{

			petAttributeName := petName + "Rating"

			petNameLabel := getBoldLabelCentered(translate(petName))
			
			optionsList := []string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}

			handleSelectionFunction := func(response string){
					err := myLocalProfiles.SetProfileData("Mate", petAttributeName, response)
					if (err != nil){
						setErrorEncounteredPage(window, err, currentPage)
						return	
					}
				}

			petRatingSelector := widget.NewSelect(optionsList, handleSelectionFunction)

			currentRatingExists, currentPetRating, err := myLocalProfiles.GetProfileData("Mate", petAttributeName)
			if (err != nil){ return nil, err }

			if (currentRatingExists == true){
				petRatingSelector.Selected = currentPetRating
			} else {
				petRatingSelector.PlaceHolder = translate("Choose rating...")
			}

			noResponseButton := getWidgetCentered(widget.NewButtonWithIcon(translate("No Response"), theme.CancelIcon(), func(){ 
					err := myLocalProfiles.DeleteProfileData("Mate", petAttributeName)
					if (err != nil){
						setErrorEncounteredPage(window, err, currentPage)
						return
					}
					currentPage()
				}))

			petsGrid.Add(petNameLabel)
			petsGrid.Add(petRatingSelector)
			petsGrid.Add(noResponseButton)
		}

		petsGridCentered := getContainerCentered(petsGrid)

		return petsGridCentered, nil
	}
	
	petsGrid, err := getPetsGrid()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	page := container.NewVBox(pageTitle, backButton, widget.NewSeparator(), pageSubtitle, widget.NewSeparator(), description1, description2, petsRatingSelectorCentered, petsNoResponseButton, widget.NewSeparator(), description3, description4, widget.NewSeparator(), petsGrid)
	
	setPageContent(page, window)
}


