components_settings_settings.bs

import "pkg:/source/utils/config.bs"
import "pkg:/source/utils/misc.bs"
import "pkg:/source/roku_modules/log/LogMixin.brs"
' post device profile
import "pkg:/source/utils/deviceCapabilities.bs"

sub init()
    m.log = log.Logger("Settings")
    m.top.optionsAvailable = false

    m.userLocation = []

    m.settingsMenu = m.top.findNode("settingsMenu")
    m.settingDetail = m.top.findNode("settingDetail")
    m.settingDesc = m.top.findNode("settingDesc")
    m.path = m.top.findNode("path")

    m.boolSetting = m.top.findNode("boolSetting")
    m.integerSetting = m.top.findNode("integerSetting")
    m.radioSetting = m.top.findNode("radioSetting")

    m.integerSetting.observeField("submit", "onKeyGridSubmit")
    m.integerSetting.observeField("escape", "onKeyGridEscape")

    m.settingsMenu.setFocus(true)
    m.settingsMenu.observeField("itemFocused", "settingFocused")
    m.settingsMenu.observeField("itemSelected", "settingSelected")

    m.boolSetting.observeField("checkedItem", "boolSettingChanged")
    m.radioSetting.observeField("checkedItem", "radioSettingChanged")

    m.postTask = createObject("roSGNode", "PostTask")

    ' Load Configuration Tree
    m.configTree = GetConfigTree()
    LoadMenu({ children: m.configTree })
end sub

sub onKeyGridSubmit()
    selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]
    set_user_setting(selectedSetting.settingName, m.integerSetting.text)
    m.settingsMenu.setFocus(true)
end sub

sub onKeyGridEscape()
    if m.integerSetting.escape = "left" or m.integerSetting.escape = "back"
        m.settingsMenu.setFocus(true)
    end if
end sub

sub LoadMenu(configSection)
    if configSection.children = invalid
        ' Load parent menu
        m.userLocation.pop()
        configSection = m.userLocation.peek()
    else
        if m.userLocation.Count() > 0 then m.userLocation.peek().selectedIndex = m.settingsMenu.itemFocused
        m.userLocation.push(configSection)
    end if

    result = CreateObject("roSGNode", "ContentNode")

    for each item in configSection.children
        listItem = result.CreateChild("ContentNode")
        listItem.title = tr(item.title)
        listItem.Description = tr(item.description)
        listItem.id = item.id
    end for

    m.settingsMenu.content = result

    if configSection.selectedIndex <> invalid and configSection.selectedIndex > -1
        m.settingsMenu.jumpToItem = configSection.selectedIndex
    end if

    ' Set Path display
    m.path.text = tr("Settings")
    for each level in m.userLocation
        if level.title <> invalid then m.path.text += " / " + tr(level.title)
    end for
end sub

sub settingFocused()

    selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]
    m.settingDesc.text = tr(selectedSetting.Description)
    m.top.overhangTitle = tr(selectedSetting.Title)

    ' Hide Settings
    m.boolSetting.visible = false
    m.integerSetting.visible = false
    m.radioSetting.visible = false

    userSettings = m.global.session.user.settings

    if selectedSetting.type = invalid
        return
    else if selectedSetting.type = "bool"

        m.boolSetting.visible = true

        if userSettings[selectedSetting.settingName] = true
            m.boolSetting.checkedItem = 1
        else
            m.boolSetting.checkedItem = 0
        end if
    else if selectedSetting.type = "integer"
        integerValue = userSettings[selectedSetting.settingName].ToStr()
        if isValid(integerValue)
            m.integerSetting.text = integerValue
        end if
        m.integerSetting.visible = true
    else if LCase(selectedSetting.type) = "radio"

        selectedValue = userSettings[selectedSetting.settingName]

        radioContent = CreateObject("roSGNode", "ContentNode")

        itemIndex = 0
        for each item in m.userLocation.peek().children[m.settingsMenu.itemFocused].options
            listItem = radioContent.CreateChild("ContentNode")
            listItem.title = tr(item.title)
            listItem.id = item.id
            if selectedValue = item.id
                m.radioSetting.checkedItem = itemIndex
            end if
            itemIndex++
        end for

        m.radioSetting.content = radioContent

        m.radioSetting.visible = true
    else
        m.log.warn("Unknown setting type", selectedSetting.type)
    end if

end sub


sub settingSelected()

    selectedItem = m.userLocation.peek().children[m.settingsMenu.itemFocused]

    if selectedItem.type <> invalid ' Show setting
        if selectedItem.type = "bool"
            m.boolSetting.setFocus(true)
        end if
        if selectedItem.type = "integer"
            m.integerSetting.setFocus(true)
        end if
        if (selectedItem.type) = "radio"
            m.radioSetting.setFocus(true)
        end if
    else if selectedItem.children <> invalid and selectedItem.children.Count() > 0 ' Show sub menu
        LoadMenu(selectedItem)
        m.settingsMenu.setFocus(true)
    else
        return
    end if

    m.settingDesc.text = m.settingsMenu.content.GetChild(m.settingsMenu.itemFocused).Description

end sub


sub boolSettingChanged()
    if m.boolSetting.focusedChild = invalid then return
    selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]

    if m.boolSetting.checkedItem
        session.user.settings.Save(selectedSetting.settingName, "true")
        if Left(selectedSetting.settingName, 7) = "global."
            ' global user setting
            ' save to main registry block
            set_setting(selectedSetting.settingName, "true")
            ' setting specific triggers
            if selectedSetting.settingName = "global.rememberme"
                set_setting("active_user", m.global.session.user.id)
            end if
        else
            ' regular user setting
            ' save to user specific registry block
            set_user_setting(selectedSetting.settingName, "true")
        end if
    else
        session.user.settings.Save(selectedSetting.settingName, "false")
        if Left(selectedSetting.settingName, 7) = "global."
            ' global user setting
            ' save to main registry block
            set_setting(selectedSetting.settingName, "false")
            ' setting specific triggers
            if selectedSetting.settingName = "global.rememberme"
                unset_setting("active_user")
            end if
        else
            ' regular user setting
            ' save to user specific registry block
            set_user_setting(selectedSetting.settingName, "false")
        end if
    end if
end sub

sub radioSettingChanged()
    if m.radioSetting.focusedChild = invalid then return
    selectedSetting = m.userLocation.peek().children[m.settingsMenu.itemFocused]
    set_user_setting(selectedSetting.settingName, m.radioSetting.content.getChild(m.radioSetting.checkedItem).id)
end sub

' JFScreen hook that gets ran as needed.
' Assumes settings were changed and they affect the device profile.
' Posts a new device profile to the server using the task thread
sub OnScreenHidden()
    m.postTask.arrayData = getDeviceCapabilities()
    m.postTask.apiUrl = "/Sessions/Capabilities/Full"
    m.postTask.control = "RUN"
    m.postTask.observeField("responseCode", "postFinished")
end sub

' Triggered by m.postTask after completing a post.
' Empty the task data when finished.
sub postFinished()
    m.postTask.unobserveField("responseCode")
    m.postTask.callFunc("empty")
end sub

' Returns true if any of the data entry forms are in focus
function isFormInFocus() as boolean
    if isValid(m.settingDetail.focusedChild) or m.radioSetting.hasFocus() or m.boolSetting.hasFocus() or m.integerSetting.hasFocus()
        return true
    end if
    return false
end function

function onKeyEvent(key as string, press as boolean) as boolean
    if not press then return false

    if (key = "back" or key = "left") and m.settingsMenu.focusedChild <> invalid and m.userLocation.Count() > 1
        LoadMenu({})
        return true
    else if (key = "back" or key = "left") and isFormInFocus()
        m.settingsMenu.setFocus(true)
        return true
    end if

    if key = "options"
        m.global.sceneManager.callFunc("popScene")
        return true
    end if

    if key = "right"
        settingSelected()
    end if

    if key = "up" and m.settingsMenu.focusedChild <> invalid and m.settingsMenu.itemFocused = 0
        m.settingsMenu.jumpToItem = m.settingsMenu.content.getChildCount() - 1

        return true
    end if

    if key = "down" and m.settingsMenu.focusedChild <> invalid
        if m.settingsMenu.itemFocused = m.settingsMenu.content.getChildCount() - 1
            m.settingsMenu.jumpToItem = 0

            return true
        end if
    end if

    return false
end function