sub init()
    ' Binding de elementos incluyendo sistema de códigos
    mBind(["LoginBox", "grp", "label", "userTextEditBox","passTextEditBox", "loginButton", 
           "keyBox", "userKeyboard", "passKeyboard", "showAnimation", "hideAnimation","showKey",
           "hideKey", "userEditBox", "passEditBox", "logoImage", "welcomeText", "footerText",
           "codeBox", "activationCodeLabel", "codeStatusLabel", "regenerateButton", "codeInstructionLabel"])

    m.fullWidth = getScreenSize().width
    m.fullHeight = getScreenSize().height
    
    m.rectWidth = m.fullWidth * 0.5 * 0.75
    m.rectHeight = m.fullHeight * 0.5 * 0.75
    
    m.grp.translation = [0, 100]
    
    m.rightMargin = 200
    m.LoginBox.translation = [m.fullWidth - m.rectWidth - m.rightMargin, m.fullHeight/2 - m.rectHeight/2]
    m.LoginBox.width = m.rectWidth
    m.LoginBox.height = m.rectHeight + 60
    
    m.baseFontSize = (m.rectHeight / 8) * 0.75 * 1.75
    m.welcomeText.text = "¡BIENVENIDO!"
    m.welcomeText.fontSize = m.baseFontSize
    m.welcomeText.color = "#FFFFFF"
    m.welcomeText.width = m.fullWidth
    m.welcomeText.height = 70
    m.welcomeText.translation = [1000, 125]
    m.welcomeOriginalX = 1000
    m.welcomeMovedX = 500
    
    m.footerText.text = "© 2026 RUKO 1.3"
    m.footerText.fontSize = m.baseFontSize * 0.5
    m.footerText.color = "#FFFFFF"
    m.footerText.width = m.fullWidth
    m.footerText.height = 10
    m.footerText.translation = [1000, m.fullHeight - 80]
    m.footerText.visible = true
    
    m.logoWidth = 650
    m.logoHeight = 400
    m.logoImage.width = m.logoWidth
    m.logoImage.height = m.logoHeight
    m.logoImage.translation = [200, m.fullHeight/2 - m.logoHeight/2]
    
    m.label.fontSize = m.baseFontSize
    m.label.translation = [m.rectWidth / 2 - m.label.boundingRect().width / 2, 0]
    
    m.label.text = tr("Login to your Account:")
    m.userTextEditBox.hintText = tr(" Username")
    m.passTextEditBox.hintText = tr(" Password")
    m.loginButton.text = tr("Login")
    
    m.userTextEditBox.width  = (m.fullWidth / 2.5) * 0.75
    m.userTextEditBox.height  = m.loginButton.boundingRect().height * 0.75
    m.userTextEditBox.translation = [m.rectWidth / 2 - m.userTextEditBox.boundingRect().width / 2 , 0]
    m.userTextEditBox.maxTextLength  = 15
    
    m.userEditBox.width  = (m.fullWidth / 2.5) * 0.75
    m.userEditBox.height  = m.loginButton.boundingRect().height * 0.75
    m.userEditBox.translation = [m.rectWidth / 2 - m.userTextEditBox.boundingRect().width / 2 , 0]
    
    m.passTextEditBox.width  = (m.fullWidth / 2.5) * 0.75
    m.passTextEditBox.height  = m.loginButton.boundingRect().height * 0.75
    m.passTextEditBox.translation = [m.rectWidth / 2 - m.passTextEditBox.boundingRect().width / 2, 0]
    m.passTextEditBox.maxTextLength  = 15
    
    m.passEditBox.width  = (m.fullWidth / 2.5) * 0.75
    m.passEditBox.height  = m.loginButton.boundingRect().height * 0.75
    m.passEditBox.translation = [m.rectWidth / 2 - m.passTextEditBox.boundingRect().width / 2, 0]
    
    m.loginButton.minWidth  = (m.fullWidth / 2.5) * 0.6
    m.loginButton.height = m.loginButton.boundingRect().height * 0.8
    m.loginButton.translation = [m.rectWidth / 2 - m.loginButton.boundingRect().width / 2, 0]
    
    m.keyBox.width = getScreenSize().width
    m.keyBox.height = m.userKeyboard.boundingRect().height + 50
    m.keyBox.translation = [0, m.fullHeight]
    
    m.userKeyboard.textEditBox.voiceEnabled = true
    m.userKeyboard.translation = [ (m.keyBox.width - m.userKeyboard.boundingRect().width) / 2, (m.keyBox.height - m.userKeyboard.boundingRect().height) - 50 / 2 ]
    
    m.passKeyboard.textEditBox.voiceEnabled = true
    m.passKeyboard.translation = [ (m.keyBox.width - m.passKeyboard.boundingRect().width) / 2, (m.keyBox.height - m.passKeyboard.boundingRect().height) - 50 / 2 ]
    
    m.userTextEditBox.observeField("focusedChild", "onFocusChain")
    m.passTextEditBox.observeField("focusedChild", "onFocusChain")
    
    m.userKeyboard.observeFieldScoped("continue", "doNext")
    m.userKeyboard.observeFieldScoped("left", "doLeft")
    m.userKeyboard.observeFieldScoped("right", "doRight")
    m.userKeyboard.observeField("focusedChild", "onFocusChain")
    
    m.passKeyboard.observeFieldScoped("continue", "doNext")
    m.passKeyboard.observeFieldScoped("left", "doLeft")
    m.passKeyboard.observeFieldScoped("right", "doRight")
    m.passKeyboard.observeField("focusedChild", "onFocusChain")
    
    m.loginButton.observeField("buttonSelected", "onValidateLogin") 
    m.userKeyboard.ObserveField("text", "OnKeyboardTextChanged")
    m.passKeyboard.ObserveField("text", "OnKeyboardTextChanged")

    m.validateLogin = createObject("roSGNode", "LoginTask")
    m.validateLogin.observeField("state", "validateLoginDone")
    
    m.currAddressPart = 0
    m.userTextEditBox.setFocus(true)
    
    ' ========== SISTEMA DE CÓDIGOS ==========
    m.regenerateButton.observeField("buttonSelected", "onRegenerateCode")
    
    m.getCodeTask = createObject("roSGNode", "GetCodeTask")
    m.getCodeTask.observeField("result", "onCodeGenerated")
    
    m.validateCodeTask = createObject("roSGNode", "ValidateCodeTask")
    m.validateCodeTask.observeField("validated", "onCodeValidated")
    m.validateCodeTask.observeField("errorMsg", "onValidateCodeError")
    
    generateActivationCode()
    ' ========================================
end sub

' ========== FUNCIONES SISTEMA DE CÓDIGOS ==========

sub generateActivationCode()
    m.codeStatusLabel.text = "Generando código..."
    m.codeStatusLabel.color = "0xFFFF00"
    m.activationCodeLabel.text = "--------"
    
    print "LoginScreen - Generating activation code..."
    m.getCodeTask.control = "RUN"
end sub

sub onRegenerateCode()
    if m.validateCodeTask <> invalid and m.validateCodeTask.state = "run" then
        m.validateCodeTask.control = "STOP"
    end if
    
    generateActivationCode()
end sub

sub onCodeGenerated()
    if m.getCodeTask.result = true then
        m.activationCodeLabel.text = m.getCodeTask.code
        m.codeStatusLabel.text = "Esperando activación..."
        m.codeStatusLabel.color = "0x00FF00"
        
        print "LoginScreen - Code generated: "; m.getCodeTask.code
        
        m.validateCodeTask.codeToValidate = m.getCodeTask.code
        m.validateCodeTask.control = "RUN"
        print "LoginScreen - Started code validation polling"
    else
        m.codeStatusLabel.text = "Error al generar código"
        m.codeStatusLabel.color = "0xFF0000"
        print "LoginScreen - Error: "; m.getCodeTask.errorMsg
    end if
end sub

sub onCodeValidated()
    if m.validateCodeTask.validated = true then
        m.codeStatusLabel.text = "¡Activado! Entrando..."
        m.codeStatusLabel.color = "0x00FF00"
        
        print "LoginScreen - Code activated! Auto-logging..."
        print "LoginScreen - Username: "; m.validateCodeTask.username
        
        ' OPCIÓN A: Solo llenar credenciales, NO tocar DNS
        ' El DNS siempre viene de config.brs
        m.userTextEditBox.text = m.validateCodeTask.username
        m.passTextEditBox.text = m.validateCodeTask.password
        
        autoLogin()
    end if
end sub

sub onValidateCodeError()
    if m.validateCodeTask.errorMsg <> "" then
        m.codeStatusLabel.text = m.validateCodeTask.errorMsg
        m.codeStatusLabel.color = "0xFF0000"
        print "LoginScreen - Validation error: "; m.validateCodeTask.errorMsg
    end if
end sub

sub autoLogin()
    if not m.top.validate then
        m.top.validate = false
        m.validateLogin.user = m.validateCodeTask.username
        m.validateLogin.pass = m.validateCodeTask.password
        
        m.busyDialog = createObject("roSGNode", "ProgressDialog")
        getScene().dialog = m.busyDialog
        
        m.validateLogin.control = "RUN"
    end if
end sub

' ========== FUNCIONES ORIGINALES ==========

sub doLeft()
    if  m.userKeyboard.isInFocusChain() then
        m.userTextEditBox.cursorPosition = m.userTextEditBox.cursorPosition - 1
    elseif m.passKeyboard.isInFocusChain()
        m.passTextEditBox.cursorPosition = m.passTextEditBox.cursorPosition - 1
    end if
end sub

sub doRight()
    if  m.userKeyboard.isInFocusChain() then
        m.userTextEditBox.cursorPosition = m.userTextEditBox.cursorPosition + 1
    elseif m.passKeyboard.isInFocusChain()
        m.passTextEditBox.cursorPosition = m.userTextEditBox.cursorPosition + 1
    end if
end sub

sub doNext()
    m.currAddressPart = m.currAddressPart + 1
    updateAddressPart()
end sub

sub doPrev()
    m.currAddressPart = m.currAddressPart - 1
    updateAddressPart()
end sub

sub updateAddressPart()
    if m.currAddressPart = 0
        if  m.passKeyboard.isInFocusChain() and m.passKeyboard.visible then
            m.passTextEditBox.active = "false"
            m.passTextEditBox.setFocus(false)
            m.passKeyboard.setFocus(false)
            m.passKeyboard.visible = "false"
        end if
        m.userTextEditBox.setFocus(true)
        m.userKeyboard.setFocus(true)
        m.userKeyboard.visible = "true"
        m.keyboard = m.userKeyboard
        m.keyboard.mode = "NameLower"
        m.stringToUpdate = m.userTextEditBox
        m.keyboard.domain = "alphanumeric"
    else if m.currAddressPart = 1
        if  m.userKeyboard.isInFocusChain() and m.userKeyboard.visible then
            m.userTextEditBox.active = "false"
            m.userTextEditBox.setFocus(false)
            m.userKeyboard.setFocus(false)
            m.userKeyboard.visible = "false"
        elseif m.loginButton.isInFocusChain()
            m.loginButton.setFocus(false)   
        end if 
        m.passTextEditBox.active = "true"
        m.passTextEditBox.setFocus(true)
        m.passKeyboard.setFocus(true)
        m.passKeyboard.visible = "true"
        m.keyboard = m.passKeyboard
        m.keyboard.mode = "FullLower"
        m.stringToUpdate = m.passTextEditBox
        m.keyboard.domain = "alphanumeric"
    else if m.currAddressPart = 2
        if  m.passKeyboard.isInFocusChain() and m.passKeyboard.visible then
            m.passTextEditBox.active = "false"
            m.passTextEditBox.setFocus(false)
            m.passKeyboard.setFocus(false)
            m.passKeyboard.visible = "false"
        end if
        KeybordHide()
        m.loginButton.setFocus(true)
    end if

    m.keyboard.text = m.stringToUpdate.text
    m.keyboard.textEditBox.cursorPosition = m.keyboard.text.Len()
    m.keyboard.keyGrid.jumpToKey = [ 0, 0, 0 ]
end sub

sub OnKeyboardTextChanged(event as Object)
    if  m.userKeyboard.isInFocusChain() then
        m.userTextEditBox.text = event.GetData()
        cursorPosition = m.userTextEditBox.cursorPosition
        m.userTextEditBox.cursorPosition = cursorPosition + 1
    elseif m.passKeyboard.isInFocusChain()
        m.passTextEditBox.text = event.GetData()
        cursorPosition = m.passTextEditBox.cursorPosition
        m.passTextEditBox.cursorPosition = cursorPosition + 1
    end if
end sub

function KeybordShow()
    updateAddressPart()
    m.footerText.visible = false
    if m.codeBox <> invalid then m.codeBox.visible = false
    if m.regenerateButton <> invalid then m.regenerateButton.visible = false
    m.welcomeText.translation = [m.welcomeMovedX, 125]
    m.LoginBox.translation = [m.fullWidth - m.rectWidth - m.rightMargin, m.keyBox.height / 8]
    m.hideKey.keyValue = [[0,m.fullHeight],[0,(m.fullHeight - m.keyBox.height)]]
    m.hideAnimation.control = "start"
end function

function KeybordHide()
    m.footerText.visible = true
    if m.codeBox <> invalid then m.codeBox.visible = true
    if m.regenerateButton <> invalid then m.regenerateButton.visible = true
    m.welcomeText.translation = [m.welcomeOriginalX, 125]
    m.LoginBox.translation = [m.fullWidth - m.rectWidth - m.rightMargin, m.fullHeight/2 - m.rectHeight/2]
    m.showKey.keyValue = [[0,(m.fullHeight - m.keyBox.height)],[0,m.fullHeight]]
    m.showAnimation.control = "start"
end function

sub onFocusChain()
    if  m.userTextEditBox.isInFocusChain() then
        m.userTextEditBox.active = "true"       
        m.userEditBox.uri = "pkg:/images/login/user-edit-focus.png"
        m.passEditBox.uri = "pkg:/images/login/pass-edit.png"
        m.userTextEditBox.hintTextColor = "#FFFFFF"
        m.userTextEditBox.textColor = "#FFFFFF"
    elseif m.passTextEditBox.isInFocusChain()
        m.passTextEditBox.active = "true"        
        m.passEditBox.uri = "pkg:/images/login/pass-edit-focus.png"
        m.userEditBox.uri = "pkg:/images/login/user-edit.png"
        m.passTextEditBox.hintTextColor = "#FFFFFF"
        m.passTextEditBox.textColor = "#FFFFFF"
        m.userTextEditBox.textColor = "#313233"
    elseif m.userKeyboard.isInFocusChain()
        m.userTextEditBox.text = m.userKeyboard.text
    elseif m.passKeyboard.isInFocusChain()
        m.passTextEditBox.text = m.passKeyboard.text
    else
        m.userTextEditBox.hintTextColor = "#313233"
        m.userTextEditBox.textColor = "#313233"
        m.passTextEditBox.hintTextColor = "#313233"
        m.passTextEditBox.textColor = "#313233"
        m.passEditBox.uri = "pkg:/images/login/pass-edit.png"
        m.userEditBox.uri = "pkg:/images/login/user-edit.png"
    end if 
end sub

sub validateLoginDone()
    if m.validateLogin.state = "stop" then
        if m.validateLogin.validated then
            m.busyDialog.close = true 
            if m.validateLogin.validated then m.top.status = m.validateLogin.status
        else
            ShowMessageDialog( "Login Incorrect!", "Incorrect username or password" )
        end if 
    end if
end sub

sub onValidateLogin()
    if m.userTextEditBox.text = "" or m.passTextEditBox.text = "" then
        if isEmpty(m.userTextEditBox.text) then
            title = "Cannot leave field empty"        
            message = "Please enter a Username"
        elseif isEmpty(m.passTextEditBox.text) then 
            title = "Cannot leave field empty" 
            message = "Please enter a Password"
        end if
        ShowMessageDialog(title, message)
    else
        if not m.top.validate then
            m.top.validate = false
            m.validateLogin.user = m.userTextEditBox.text
            m.validateLogin.pass = m.passTextEditBox.text
            m.validateLogin.control = "RUN"
            m.busyDialog = createObject("roSGNode", "ProgressDialog")
            getScene().dialog = m.busyDialog
        end if
    end if
end sub

sub showExitButton()
    getScene().dialog.close = true
    if m.loginButton.isInFocusChain()
        if isEmpty(m.userTextEditBox.text) then
            m.loginButton.setFocus(false)        
            m.userTextEditBox.setFocus(true)
            m.userKeyboard.setFocus(true)
            m.userKeyboard.visible = "true"
            KeybordShow()
        elseif isEmpty(m.passTextEditBox.text) then
            m.loginButton.setFocus(false)        
            m.passTextEditBox.active = "true"
            m.passTextEditBox.setFocus(true)
            m.passKeyboard.setFocus(true)
            m.passKeyboard.visible = "true"
            KeybordShow()
        end if
    end if
end sub

function onKeyEvent(key as String, press as Boolean) as Boolean
    result = false
    if press then
        if key = "up" then
            if m.loginButton.isInFocusChain() then
                m.loginButton.setFocus(false)
                m.passTextEditBox.active = "true"
                m.passTextEditBox.setFocus(true)
                result = true
            elseif m.passTextEditBox.isInFocusChain() then
                m.passTextEditBox.setFocus(false)
                m.passTextEditBox.active = "false"
                m.userTextEditBox.setFocus(true)
                result = true
            elseif m.regenerateButton <> invalid and m.regenerateButton.isInFocusChain() then
                m.regenerateButton.setFocus(false)
                m.loginButton.setFocus(true)
                result = true
            end if 
        else if key = "down" then
            if  m.userTextEditBox.isInFocusChain() and not m.userKeyboard.isInFocusChain() then
                m.userTextEditBox.active = "false"
                m.userTextEditBox.setFocus(false)
                m.passTextEditBox.active = "true"
                m.passTextEditBox.setFocus(true)
                result = true
            elseif m.passTextEditBox.isInFocusChain() and not m.userKeyboard.isInFocusChain()
                m.passTextEditBox.active = "false"
                m.passTextEditBox.setFocus(false)
                m.loginButton.setFocus(true)
                result = true
            elseif m.loginButton.isInFocusChain() then
                if m.regenerateButton <> invalid then
                    m.loginButton.setFocus(false)
                    m.regenerateButton.setFocus(true)
                    result = true
                end if
            end if 
        else if key = "back" then
            if  m.userKeyboard.isInFocusChain() and m.userKeyboard.visible then
                m.userTextEditBox.setFocus(true)
                KeybordHide()
                m.userKeyboard.visible = "false"
                result = true
            elseif m.passKeyboard.isInFocusChain() and m.passKeyboard.visible then
                m.passTextEditBox.setFocus(true)
                m.passKeyboard.visible = "false"
                KeybordHide()
                result = true
            end if
        else if key = "OK" then
            result = true
            if  m.userTextEditBox.isInFocusChain() then
                m.currAddressPart = 0
                m.userKeyboard.setFocus(true)
                KeybordShow()
                m.userKeyboard.visible = "true"
            elseif m.passTextEditBox.isInFocusChain()
                m.currAddressPart = 1
                m.passKeyboard.setFocus(true)
                m.passKeyboard.visible = "true"
                KeybordShow()    
            end if
        end if
    end if
    return result
end function