package gui

// proofFundsGui.go implements pages to view and increase a user's payment proof provider account funds,
//		and to spend funds to increase their identity balance

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

import "seekia/internal/appMemory"
import "seekia/internal/convertCurrencies"
import "seekia/internal/currencies"
import "seekia/internal/globalSettings"
import "seekia/internal/helpers"
import "seekia/internal/network/appNetworkType/getAppNetworkType"
import "seekia/internal/network/myProofFunds"
import "seekia/internal/parameters/getParameters"

import "errors"
import "time"

func setViewMyProofFundsPage(window fyne.Window, myIdentityType string, previousPage func()){

	currentPage := func(){setViewMyProofFundsPage(window, myIdentityType, previousPage)}

	appMemory.SetMemoryEntry("CurrentViewedPage", "AccountFunds")

	title := getPageTitleCentered("My " + myIdentityType + " Account Funds")

	backButton := getBackButtonCentered(previousPage)

	description1 := getLabelCentered("Broadcasting to the Seekia network requires funds.")
	description2 := getLabelCentered("You must spend Ethereum to add to your account funds.")

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

		//TODO: Also show balance in cryptocurrency units

		appNetworkType, err := getAppNetworkType.GetAppNetworkType()
		if (err != nil) { return nil, err }

		myFundsBalanceLabel := getItalicLabelCentered("My Funds Balance:")

		getCurrentAppCurrency := func()(string, error){
			exists, currentAppCurrency, err := globalSettings.GetSetting("Currency")
			if (err != nil) { return "", err }
			if (exists == false){
				return "USD", nil
			}
			return currentAppCurrency, nil
		}
		
		currentAppCurrencyCode, err := getCurrentAppCurrency()
		if (err != nil){ return nil, err }

		_, appCurrencySymbol, err := currencies.GetCurrencyInfoFromCurrencyCode(currentAppCurrencyCode)
		if (err != nil) { return nil, err }

		appCurrencySymbolButton := widget.NewButton(appCurrencySymbol, func(){
				setChangeAppCurrencyPage(window, currentPage)
			})

		parametersExist, appCurrencyAccountFundsBalance, err := myProofFunds.GetMyProofFundsAccountBalanceInAnyCurrency(myIdentityType, appNetworkType, currentAppCurrencyCode)
		if (err != nil) { return nil, err }

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

			if (parametersExist == false){
				return "Unknown", nil
			}

			appCurrencyAccountFundsBalanceString := helpers.ConvertFloat64ToStringRounded(appCurrencyAccountFundsBalance, 3)

			return appCurrencyAccountFundsBalanceString, nil
		}
		
		accountBalanceText, err := getAccountBalanceText()
		if (err != nil) { return nil, err }

		appCurrencyAccountFundsBalanceLabel := getBoldLabel(accountBalanceText + " " + currentAppCurrencyCode)

		myFundsBalanceRow := container.NewHBox(layout.NewSpacer(), appCurrencySymbolButton, appCurrencyAccountFundsBalanceLabel, layout.NewSpacer())

		currentBalanceRefreshButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh", theme.ViewRefreshIcon(), func(){
	
				if (parametersExist == false){

					dialogTitle := translate("Parameters Missing.")
					dialogMessageA := getLabelCentered(translate("The network parameters are not downloaded."))
					dialogMessageB := getLabelCentered(translate("You must wait for them to download to view your balance."))

					//TODO: View progress button

					dialogContent := container.NewVBox(dialogMessageA, dialogMessageB)
					dialog.ShowCustom(dialogTitle, translate("Close"), dialogContent, window)
					return
				}

				//TODO

				showUnderConstructionDialog(window)
			}))

		myFundsBalanceSection := container.NewVBox(myFundsBalanceLabel, myFundsBalanceRow, currentBalanceRefreshButton)

		return myFundsBalanceSection, nil
	}

	myFundsBalanceSection, err := getMyFundsBalanceSection()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	ethereumIcon, err := getFyneImageIcon("Ethereum")
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}
	iconSize := getCustomFyneSize(0)
	ethereumIcon.SetMinSize(iconSize)

	addFundsButton_Ethereum := widget.NewButton("Send Ethereum", func(){
			showUnderConstructionDialog(window)
//			nextPage := func(){setAddAccountFundsWithCryptocurrencyPage(window, myIdentityType, "Ethereum", currentPage)}

//			setBuyAccountFundsCryptoPrivacyWarningPage(window, currentPage, nextPage)
		})

	addFundsButtonWithIcon_Ethereum := getContainerCentered(container.NewGridWithColumns(1, ethereumIcon, addFundsButton_Ethereum))

	viewPricingButton := getWidgetCentered(widget.NewButtonWithIcon("View Pricing", theme.VisibilityIcon(), func(){
			setViewSeekiaPricingPage(window, currentPage)
		}))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, widget.NewSeparator(), myFundsBalanceSection, widget.NewSeparator(), addFundsButtonWithIcon_Ethereum, widget.NewSeparator(), viewPricingButton)

	setPageContent(page, window)
}

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

	title := getPageTitleCentered("Privacy Warning")

	backButton := getBackButtonCentered(previousPage)

	description1 := getLabelCentered("Be aware that your privacy is at risk when using cryptocurrencies.")
	description2 := getLabelCentered("When you send money from your wallet, it is possible to guess that you are a user of Seekia.")
	description3 := getLabelCentered("There is also a risk of someone linking your wallet to your Seekia identity.")
	description4 := getBoldLabelCentered("To protect yourself, wait before funding your Seekia identity.")
	description5 := getLabelCentered("For example, after funding your account, wait a few hours before funding your identity.")
	description6 := getLabelCentered("This will break the link between your transaction and your Seekia profile/identity.")
	description7 := getLabelCentered("If you have a large amount of cryptocurrency, you should be wary of sending your funds from that wallet.")
	description8 := getLabelCentered("For privacy, you should send funds directly from an exchange.")
	description9 := getLabelCentered("You can also use a privacy tool such as a zero knowledge accumulator for stronger protection.")

	description10 := getBoldLabelCentered("Do you understand the privacy risks?")

	iUnderstandButton := getWidgetCentered(widget.NewButtonWithIcon("I Understand", theme.ConfirmIcon(), nextPage))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, description2, description3, widget.NewSeparator(), description4, description5, description6, widget.NewSeparator(), description7, description8, description9, widget.NewSeparator(), description10, iUnderstandButton)
	
	setPageContent(page, window)
}


// This page is used to show how much it costs to fund broadcasts on the Seekia network
func setViewSeekiaPricingPage(window fyne.Window, previousPage func()){

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

	title := getPageTitleCentered("Seekia Pricing (Under Construction)")

	backButton := getBackButtonCentered(previousPage)

	description := getLabelCentered("Below are the estimated prices to broadcast content on the Seekia network.")

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

		exists, appCurrencyCode, err := globalSettings.GetSetting("Currency")
		if (err != nil) { return "", err }
		if (exists == false){
			return "USD", nil
		}
		return appCurrencyCode, nil
	}
	appCurrencyCode, err := getAppCurrency()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	currentCurrencyLabel := getBoldLabelCentered("Current Currency:")
	
	_, appCurrencySymbol, err := currencies.GetCurrencyInfoFromCurrencyCode(appCurrencyCode)
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	chooseCurrencyButton := widget.NewButton(appCurrencySymbol + appCurrencyCode, func(){
			setChangeAppCurrencyPage(window, currentPage) 
		})

	currentCurrencyRow := container.NewHBox(layout.NewSpacer(), currentCurrencyLabel, chooseCurrencyButton, layout.NewSpacer())

	actionNameLabel := getItalicLabelCentered("Action Name")
	costLabel := getItalicLabelCentered("Cost")

	actionNameColumn := container.NewVBox(actionNameLabel, widget.NewSeparator())
	costColumn := container.NewVBox(costLabel, widget.NewSeparator())

	appNetworkType, err := getAppNetworkType.GetAppNetworkType()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	//Outputs:
	//	-bool: Parameters exist
	//	-error
	addActionRows := func()(bool, error){

		exchangeRatesAreDownloaded, err := convertCurrencies.CheckIfExchangeRatesAreDownloaded(appNetworkType)
		if (err != nil){ return false, err }
		if (exchangeRatesAreDownloaded == false){
			return false, nil
		}

		//Outputs:
		//	-bool: Exchange rates exist
		//	-error
		addActionRow := func(actionName string, costInGramsOfGold float64)(bool, error){

			costInKilogramsOfGold := costInGramsOfGold/1000

			exchangeRateExists, appCurrencyCostFloat64, err := convertCurrencies.ConvertKilogramsOfGoldToAnyCurrency(appNetworkType, costInKilogramsOfGold, appCurrencyCode)
			if (err != nil) { return false, err }
			if (exchangeRateExists == false) {
				return false, nil
			}

			appCurrencyCostString := helpers.ConvertFloat64ToStringRounded(appCurrencyCostFloat64, 3)

			appCurrencyCostFormatted := appCurrencySymbol + " " + appCurrencyCostString + " " + appCurrencyCode

			actionNameText := getBoldLabelCentered(actionName)

			currencyCostLabel := getBoldLabelCentered(appCurrencyCostFormatted)

			actionNameColumn.Add(actionNameText)
			costColumn.Add(currencyCostLabel)

			actionNameColumn.Add(widget.NewSeparator())
			costColumn.Add(widget.NewSeparator())

			return true, nil
		}

		currentTime := time.Now().Unix()

		parametersExist, messageKilobyteGoldCostPerDay, err := getParameters.GetMessageKilobyteGoldCostPerDay(appNetworkType, currentTime)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		//TODO: Fix below numbers
		textMessageSizeKilobytes := float64(2)
		imageMessageSizeKilobytes := float64(22)

		textMessageGramsOfGoldCost := messageKilobyteGoldCostPerDay * textMessageSizeKilobytes * 14
		imageMessageGramsOfGoldCost := messageKilobyteGoldCostPerDay * imageMessageSizeKilobytes * 14

		parametersExist, err = addActionRow("Send 100 Text Messages", textMessageGramsOfGoldCost * 100)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		parametersExist, err = addActionRow("Send 100 Image Messages", imageMessageGramsOfGoldCost * 100)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		parametersExist, mateIdentityGoldCostPerDay, err := getParameters.GetIdentityBalanceGoldCostPerDay(appNetworkType, "Mate", currentTime)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}
		
		parametersExist, err = addActionRow("Fund Mate Identity for 3 Months", mateIdentityGoldCostPerDay * 90)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		parametersExist, hostIdentityGoldCostPerDay, err := getParameters.GetIdentityBalanceGoldCostPerDay(appNetworkType, "Host", currentTime)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		parametersExist, err = addActionRow("Fund Host Identity for 3 Months", hostIdentityGoldCostPerDay * 90)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		parametersExist, fundMateProfileCost, err := getParameters.GetFundMateProfileCostInGold(appNetworkType, currentTime)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}
		parametersExist, err = addActionRow("Broadcast Mate Profile 30 Times", fundMateProfileCost * 30)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		parametersExist, fundReportCost, err := getParameters.GetFundReportCostInGold(appNetworkType, currentTime)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		parametersExist, err = addActionRow("Make 10 Reports", fundReportCost * 10)
		if (err != nil) { return false, err }
		if (parametersExist == false){
			return false, nil
		}

		return true, nil
	}

	parametersExist, err := addActionRows()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}
	if (parametersExist == false){
		description1 := getBoldLabelCentered("Currency exchange rates are not downloaded.")
		descriptionB := getLabelCentered("Please wait for them to download to view pricing.")

		//TODO: Add monitor button
		refreshButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh", theme.ViewRefreshIcon(), currentPage))

		page := container.NewVBox(title, backButton, widget.NewSeparator(), description1, descriptionB, refreshButton)

		setPageContent(page, window)
		return
	}

	pricingGrid := container.NewHBox(layout.NewSpacer(), actionNameColumn, costColumn, layout.NewSpacer())

	calculateDescription := getLabelCentered("Use the pages below to calculate costs.")

	identityIcon, err := getFyneImageIcon("Profile")
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	chatIcon, err := getFyneImageIcon("Chat")
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	identityCostsButton := widget.NewButton("Identity Costs", func(){
			setViewIdentityBalancePriceCalculatorPage(window, "Mate", 30, currentPage)
		})

	chatCostsButton := widget.NewButton("Chat Costs", func(){
			setViewMessagePricingCalculatorPage(window, "Image", 14, 100, currentPage)
		})

	identityCostsButtonWithIcon := container.NewGridWithColumns(1, identityIcon, identityCostsButton)
	chatCostsButtonWithIcon := container.NewGridWithColumns(1, chatIcon, chatCostsButton)

	buttonsGrid := getContainerCentered(container.NewGridWithRows(1, identityCostsButtonWithIcon, chatCostsButtonWithIcon))

	page := container.NewVBox(title, backButton, widget.NewSeparator(), description, widget.NewSeparator(), currentCurrencyRow, widget.NewSeparator(), pricingGrid, widget.NewSeparator(), calculateDescription, buttonsGrid)

	setPageContent(page, window)
}

// This page is used to show how much it costs to fund a user on the Seekia network
// Users use this to determine how much money to send to their account
func setViewIdentityBalancePriceCalculatorPage(window fyne.Window, identityType string, daysToFund int, previousPage func()){

	currentPage := func(){setViewIdentityBalancePriceCalculatorPage(window, identityType, daysToFund, previousPage)}

	if (identityType != "Mate" && identityType != "Host"){
		setErrorEncounteredPage(window, errors.New("setViewIdentityBalancePriceCalculatorPage called with invalid identityType: " + identityType), previousPage)
		return
	}

	title := getPageTitleCentered("Identity Balance Pricing")

	backButton := getBackButtonCentered(previousPage)

	subtitle := getPageSubtitleCentered("Calculate Identity Balance Pricing")

	appNetworkType, err := getAppNetworkType.GetAppNetworkType()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	//Outputs:
	//	-bool: Parameters exist
	//	-*fyne.Container: Calculator section
	//	-error
	getCalculatorContainer := func()(bool, *fyne.Container, error){

		currentTime := time.Now().Unix()

		exchangeRatesAreDownloaded, err := convertCurrencies.CheckIfExchangeRatesAreDownloaded(appNetworkType)
		if (err != nil){ return false, nil, err }
		if (exchangeRatesAreDownloaded == false){
			return false, nil, nil
		}

		identityTypeLabel := getBoldLabelCentered("Identity Type:")

		identityTypesList := []string{"Mate", "Host"}

		identityTypeSelector := widget.NewSelect(identityTypesList, func(newIdentityType string){

				if (newIdentityType == identityType){
					return
				}

				setViewIdentityBalancePriceCalculatorPage(window, newIdentityType, daysToFund, previousPage)
			})
		identityTypeSelector.Selected = identityType

		identityTypeSelectorCentered := getWidgetCentered(identityTypeSelector)

		daysToFundSelectorFunction := func(entry string){
			if (entry == "1 month"){
				if (daysToFund == 30){
					return
				}
				setViewIdentityBalancePriceCalculatorPage(window, identityType, 30, previousPage)
			}
			if (entry == "3 months"){
				if (daysToFund == 90){
					return
				}
				setViewIdentityBalancePriceCalculatorPage(window, identityType, 90, previousPage)
			}
			if (entry == "6 months"){
				if (daysToFund == 180){
					return
				}
				setViewIdentityBalancePriceCalculatorPage(window, identityType, 180, previousPage)	
			}
		}

		desiredDurationLabel := getBoldLabelCentered("Desired Duration:")

		daysToFundSelectorOptions := []string{"1 month", "3 months", "6 months"}

		daysToFundSelector := widget.NewSelect(daysToFundSelectorOptions, daysToFundSelectorFunction)
		if (daysToFund == 30){
			daysToFundSelector.Selected = "1 month"
		} else if (daysToFund == 90){
			daysToFundSelector.Selected = "3 months"
		} else if (daysToFund == 180){
			daysToFundSelector.Selected = "6 months"
		}

		daysToFundSelectorCentered := getWidgetCentered(daysToFundSelector)

		costLabel := getBoldLabelCentered("Cost:")

		parametersExist, gramsOfGoldCostPerDay, err := getParameters.GetIdentityBalanceGoldCostPerDay(appNetworkType, identityType, currentTime)
		if (err != nil) { return false, nil, err }
		if (parametersExist == false){
			return false, nil, nil
		}

		gramsOfGoldCost := gramsOfGoldCostPerDay * float64(daysToFund)
		kilogramsOfGoldCost := gramsOfGoldCost/1000

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

			exists, appCurrencyCode, err := globalSettings.GetSetting("Currency")
			if (err != nil) { return "", err }
			if (exists == false){
				return "USD", nil
			}
			return appCurrencyCode, nil
		}
		appCurrencyCode, err := getAppCurrency()
		if (err != nil) { return false, nil, err }

		exchangeRateExists, appCurrencyCost, err := convertCurrencies.ConvertKilogramsOfGoldToAnyCurrency(appNetworkType, kilogramsOfGoldCost, appCurrencyCode)
		if (err != nil) { return false, nil, err }
		if (exchangeRateExists == false) {
			return false, nil, nil
		}

		appCurrencyCostString := helpers.ConvertFloat64ToStringRounded(appCurrencyCost, 2)

		_, appCurrencySymbol, err := currencies.GetCurrencyInfoFromCurrencyCode(appCurrencyCode)
		if (err != nil) { return false, nil, err }

		appCurrencyIconButton := widget.NewButton(appCurrencySymbol, func(){
				setChangeAppCurrencyPage(window, currentPage)
			})
		appCurrencyCostLabel := getBoldLabel(appCurrencyCostString + " " + appCurrencyCode)

		appCurrencyRow := container.NewHBox(layout.NewSpacer(), appCurrencyIconButton, appCurrencyCostLabel, layout.NewSpacer())

		calculatorContainer := container.NewVBox(identityTypeLabel, identityTypeSelectorCentered, widget.NewSeparator(), desiredDurationLabel, daysToFundSelectorCentered, widget.NewSeparator(), costLabel, appCurrencyRow)

		return true, calculatorContainer, nil
	}

	parametersExist, calculatorContainer, err := getCalculatorContainer()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}
	if (parametersExist == false){

		description1 := getBoldLabelCentered("Network parameters are not downloaded.")
		description2 := getLabelCentered("Please wait for them to download.")

		//TODO: Add page to monitor download progress.

		refreshButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh", theme.ViewRefreshIcon(), currentPage))

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

		setPageContent(page, window)
		return
	}

	description1 := getLabelCentered("Calculate identity balance pricing below.")
	description2 := getLabelCentered("All mate and host identities must be funded before broadcasting profiles.")
	description3 := getLabelCentered("You can always increase your identity balance later.")

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

	setPageContent(page, window)
}

// This page is used to show how much it costs to fund messages
// Users can use this to determine how much funds to send to their account
func setViewMessagePricingCalculatorPage(window fyne.Window, messageType string, messageDuration int64, numberOfMessages int, previousPage func()){

	if (messageType != "Image" && messageType != "Text"){
		setErrorEncounteredPage(window, errors.New("setViewMessagePricingCalculatorPage called with invalid messageType: " + messageType), previousPage)
		return
	}
	if (messageDuration != 2 && messageDuration != 14){
		setErrorEncounteredPage(window, errors.New("setViewMessagePricingCalculatorPage called with invalid messageDuration."), previousPage)
		return
	}
	if (numberOfMessages != 10 && numberOfMessages != 100 && numberOfMessages != 1000){
		setErrorEncounteredPage(window, errors.New("setViewMessagePricingCalculatorPage called with invalid numberOfMessages."), previousPage)
		return
	}

	currentPage := func(){setViewMessagePricingCalculatorPage(window, messageType, messageDuration, numberOfMessages, previousPage)}

	title := getPageTitleCentered("Message Pricing Calculator")

	backButton := getBackButtonCentered(previousPage)

	subtitle := getPageSubtitleCentered("Calculate Message Costs")

	appNetworkType, err := getAppNetworkType.GetAppNetworkType()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	//Outputs:
	//	-bool: Parameters exist
	//	-*fyne.Container: Calculator section
	//	-error
	getPricingCalculatorSection := func()(bool, *fyne.Container, error){

		messageTypeLabel := getBoldLabelCentered("Message Type:")

		messageTypesList := []string{"Image", "Text"}

		messageTypeSelector := widget.NewSelect(messageTypesList, func(newMessageType string){
				if (newMessageType == messageType){
					return
				}
				setViewMessagePricingCalculatorPage(window, newMessageType, messageDuration, numberOfMessages, previousPage)
			})

		messageTypeSelector.Selected = messageType

		messageTypeSelectorCentered := getWidgetCentered(messageTypeSelector)

		messageDurationLabel := getBoldLabelCentered("Message Duration:")

		durationOptionsList := []string{"2 days", "2 weeks"}

		durationSelectFunction := func(newDuration string){
			
			if (newDuration == "2 days"){
				if (messageDuration == 2){
					return			
				}
				setViewMessagePricingCalculatorPage(window, messageType, 2, numberOfMessages, previousPage)
				return
			}
			if (newDuration == "2 weeks"){
				if (messageDuration == 14){
					return
				}
				setViewMessagePricingCalculatorPage(window, messageType, 14, numberOfMessages, previousPage)
				return
			}
		}

		durationSelector := widget.NewSelect(durationOptionsList, durationSelectFunction)

		if (messageDuration == 2){
			durationSelector.Selected = "2 days"
		} else if (messageDuration == 14){
			durationSelector.Selected = "2 weeks"
		}

		durationSelectorCentered := getWidgetCentered(durationSelector)

		numberOfMessagesLabel := getBoldLabelCentered("Number Of Messages:")

		numberOfMessagesOptionsList := []string{"10 Messages", "100 Messages", "1000 Messages"}

		numberOfMessagesSelector := widget.NewSelect(numberOfMessagesOptionsList, func(newNumberOfMessages string){

				if (newNumberOfMessages == "10 Messages"){

					if (numberOfMessages == 10){
						return
					}

					setViewMessagePricingCalculatorPage(window, messageType, messageDuration, 10, previousPage)
					return
				}
				if (newNumberOfMessages == "100 Messages"){

					if (numberOfMessages == 100){
						return
					}
					setViewMessagePricingCalculatorPage(window, messageType, messageDuration, 100, previousPage)
					return
				}
				if (newNumberOfMessages == "1000 Messages"){
	
					if (numberOfMessages == 1000){
						return
					}
					setViewMessagePricingCalculatorPage(window, messageType, messageDuration, 1000, previousPage)
					return
				}
			})

		if (numberOfMessages == 10){
			numberOfMessagesSelector.Selected = "10 Messages"
		} else if (numberOfMessages == 100){
			numberOfMessagesSelector.Selected = "100 Messages"
		} else if (numberOfMessages == 1000){
			numberOfMessagesSelector.Selected = "1000 Messages"
		}

		numberOfMessagesSelectorCentered := getWidgetCentered(numberOfMessagesSelector)

		costLabel := getBoldLabelCentered("Cost:")

		currentTime := time.Now().Unix()

		parametersExist, messageKilobyteGoldCostPerDay, err := getParameters.GetMessageKilobyteGoldCostPerDay(appNetworkType, currentTime)
		if (err != nil) { return false, nil, err }
		if (parametersExist == false){
			return false, nil, nil 
		}

		getMessageSizeKilobytes := func()int{
			//TODO: Fix below numbers
			if (messageType == "Text"){
				return 2
			}
			// messageType == "Image"
			return 22
		}

		messageSizeKilobytes := getMessageSizeKilobytes()

		gramsOfGoldCost := messageKilobyteGoldCostPerDay * float64(messageSizeKilobytes) * float64(messageDuration) * float64(numberOfMessages)
		kilogramsOfGoldCost := gramsOfGoldCost/1000

		exchangeRatesExist, err := convertCurrencies.CheckIfExchangeRatesAreDownloaded(appNetworkType)
		if (err != nil) { return false, nil, err }
		if (exchangeRatesExist == false){
			return false, nil, nil
		}

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

			exists, appCurrencyCode, err := globalSettings.GetSetting("Currency")
			if (err != nil) { return "", err }
			if (exists == false){
				return "USD", nil
			}
			return appCurrencyCode, nil
		}

		appCurrencyCode, err := getAppCurrencyCode()
		if (err != nil) { return false, nil, err }

		parametersExist, appCurrencyCost, err := convertCurrencies.ConvertKilogramsOfGoldToAnyCurrency(appNetworkType, kilogramsOfGoldCost, appCurrencyCode)
		if (err != nil) { return false, nil, err }
		if (parametersExist == false){
			return false, nil, nil
		}

		_, appCurrencyUnitsSymbol, err := currencies.GetCurrencyInfoFromCurrencyCode(appCurrencyCode)
		if (err != nil) { return false, nil, err }

		appCurrencyCostString := helpers.ConvertFloat64ToStringRounded(appCurrencyCost, 2)

		appCurrencySymbolButton := widget.NewButton(appCurrencyUnitsSymbol, func(){
				setChangeAppCurrencyPage(window, currentPage)	
			})

		appCurrencyLabel := getBoldLabel(appCurrencyCostString + " " + appCurrencyCode)

		appCurrencyRow := container.NewHBox(layout.NewSpacer(), appCurrencySymbolButton, appCurrencyLabel, layout.NewSpacer())

		pricingCalculatorSection := container.NewVBox(messageTypeLabel, messageTypeSelectorCentered, widget.NewSeparator(), messageDurationLabel, durationSelectorCentered, widget.NewSeparator(), numberOfMessagesLabel, numberOfMessagesSelectorCentered, widget.NewSeparator(), costLabel, appCurrencyRow)

		return true, pricingCalculatorSection, nil
	}

	parametersExist, pricingCalculatorSection, err := getPricingCalculatorSection()
	if (err != nil) { 
		setErrorEncounteredPage(window, err, previousPage)
		return
	}
	if (parametersExist == false){

		description1 := getBoldLabelCentered("Network parameters are not downloaded.")
		description2 := getLabelCentered("Please wait for them to download.")

		//TODO: Add page to monitor download progress.

		refreshButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh", theme.ViewRefreshIcon(), currentPage))

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

		setPageContent(page, window)
		return
	}

	description := getLabelCentered("Use this calculator to estimate message costs.")

	page := container.NewVBox(title, backButton, widget.NewSeparator(), subtitle, widget.NewSeparator(), description, widget.NewSeparator(), pricingCalculatorSection)

	setPageContent(page, window)
}

func setIncreaseMyIdentityBalancePage(window fyne.Window, myIdentityType string, daysToFund int, previousPage func()){

	if (myIdentityType != "Mate" && myIdentityType != "Host"){
		setErrorEncounteredPage(window, errors.New("setIncreaseMyIdentityBalancePage called with invalid myIdentityType: " + myIdentityType), previousPage)
	}

	currentPage := func(){setIncreaseMyIdentityBalancePage(window, myIdentityType, daysToFund, previousPage)}

	title := getPageTitleCentered("Increase Identity Balance")

	backButton := getBackButtonCentered(previousPage)

	appNetworkType, err := getAppNetworkType.GetAppNetworkType()
	if (err != nil) {
		setErrorEncounteredPage(window, err, previousPage)
		return
	}

	//Outputs:
	//	-bool: Parameters exist
	//	-*fyne.Container
	//	-error
	getPageContent := func()(bool, *fyne.Container, error){

		description := getLabelCentered("Choose the amount of time to add to your identity balance.")

		myFundsBalanceLabel := getItalicLabelCentered("My Funds Balance:")

		getCurrentAppCurrency := func()(string, error){
			exists, currentAppCurrency, err := globalSettings.GetSetting("Currency")
			if (err != nil) { return "", err }
			if (exists == false){
				return "USD", nil
			}
			return currentAppCurrency, nil
		}

		currentAppCurrencyCode, err := getCurrentAppCurrency()
		if (err != nil){ return false, nil, err }

		_, appCurrencySymbol, err := currencies.GetCurrencyInfoFromCurrencyCode(currentAppCurrencyCode)
		if (err != nil){ return false, nil, err }

		appCurrencySymbolButton1 := widget.NewButton(appCurrencySymbol, func(){
				setChangeAppCurrencyPage(window, currentPage)
			})

		parametersExist, appCurrencyAccountFundsBalance, err := myProofFunds.GetMyProofFundsAccountBalanceInAnyCurrency(myIdentityType, appNetworkType, currentAppCurrencyCode)
		if (err != nil){ return false, nil, err }
		if (parametersExist == false){
			return false, nil, nil
		}

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

			if (parametersExist == false){
				return "Unknown", nil
			}

			appCurrencyAccountFundsBalanceString := helpers.ConvertFloat64ToStringRounded(appCurrencyAccountFundsBalance, 3)

			return appCurrencyAccountFundsBalanceString, nil
		}
		
		accountBalanceText, err := getAccountBalanceText()
		if (err != nil){ return false, nil, err }

		appCurrencyAccountFundsBalanceLabel := getBoldLabel(accountBalanceText + " " + currentAppCurrencyCode)

		myFundsBalanceRow := container.NewHBox(layout.NewSpacer(), appCurrencySymbolButton1, appCurrencyAccountFundsBalanceLabel, layout.NewSpacer())

		manageMyFundsBalanceButton := getWidgetCentered(widget.NewButtonWithIcon("Manage", theme.VisibilityIcon(), func(){
				setViewMyProofFundsPage(window, myIdentityType, currentPage)
			}))

		currentTime := time.Now().Unix()
		
		selectTimeDescription := getLabelCentered("Select the amount of time to fund.")

		//TODO: Make clear that there is a minimum amount that must be initially sent and show that value in the GUI

		timeOptionsList := []string{"1 Day", "1 Week", "1 Month", "3 Months", "6 Months"}

		timeToFundSelector := widget.NewSelect(timeOptionsList, func(response string){
				getNewDaysToFund := func()int{

					if (response == "1 Day"){
						return 1
					}
					if (response == "1 Week"){
						return 7	
					}
					if (response == "1 Month"){
						return 30
					}
					if (response == "3 Months"){
						return 90
					}
					// response == "6 Months"
					return 180
				}

				newDaysToFund := getNewDaysToFund()
				if (newDaysToFund == daysToFund){
					return
				}

				setIncreaseMyIdentityBalancePage(window, myIdentityType, newDaysToFund, previousPage)
			})

		if (daysToFund == 1){
			timeToFundSelector.Selected = "1 Day"
		} else if (daysToFund == 7){
			timeToFundSelector.Selected = "1 Week"
		} else if (daysToFund == 30){
			timeToFundSelector.Selected = "1 Month"
		} else if (daysToFund == 90){
			timeToFundSelector.Selected = "3 Months"
		} else if (daysToFund == 180){
			timeToFundSelector.Selected = "6 Months"
		}
		
		timeToFundSelectorCentered := getWidgetCentered(timeToFundSelector)

		costLabel := getLabelCentered("Cost:")

		parametersExist, gramsOfGoldCostPerDay, err := getParameters.GetIdentityBalanceGoldCostPerDay(appNetworkType, myIdentityType, currentTime)
		if (err != nil){ return false, nil, err }
		if (parametersExist == false){
			return false, nil, nil
		}

		appCurrencySymbolButton2 := widget.NewButton(appCurrencySymbol, func(){
				setChangeAppCurrencyPage(window, currentPage)	
			})

		costInKilogramsOfGold := (gramsOfGoldCostPerDay/1000) * float64(daysToFund)

		parametersExist, appCurrencyCost, err := convertCurrencies.ConvertKilogramsOfGoldToAnyCurrency(appNetworkType, costInKilogramsOfGold, currentAppCurrencyCode)
		if (err != nil){ return false, nil, err }

		appCurrencyCostString := helpers.ConvertFloat64ToStringRounded(appCurrencyCost, 3)

		appCurrencyLabel := getBoldLabel(appCurrencyCostString + " " + currentAppCurrencyCode)

		costRow := container.NewHBox(layout.NewSpacer(), appCurrencySymbolButton2, appCurrencyLabel, layout.NewSpacer())

		confirmButton := getWidgetCentered(widget.NewButtonWithIcon("Confirm Payment", theme.ConfirmIcon(), func(){
			//TODO
			showUnderConstructionDialog(window)
		}))

		pageContent := container.NewVBox(description, widget.NewSeparator(), myFundsBalanceLabel, myFundsBalanceRow, manageMyFundsBalanceButton, widget.NewSeparator(), selectTimeDescription, timeToFundSelectorCentered, widget.NewSeparator(), costLabel, costRow, widget.NewSeparator(), confirmButton)

		return true, pageContent, nil
	}

	parametersExist, pageContent, err := getPageContent()
	if (err != nil){
		setErrorEncounteredPage(window, err, previousPage)
		return
	}
	
	if (parametersExist == false){
		description1 := getBoldLabelCentered("Seekia is missing the network parameters.")
		description2 := getLabelCentered("You must wait for them to download.")

		//TODO: View progress page

		refreshButton := getWidgetCentered(widget.NewButtonWithIcon("Refresh", theme.ViewRefreshIcon(), currentPage))

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

		setPageContent(page, window)
		return
	}

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

	setPageContent(page, window)
}


