define ['./states/index', './presenter'], (templates, presenter) ->
# If some extension provides you can use the type defined in there
# to extend your widget. Defaults to Base constructor.
#
# type: 'Base'
# TODO add support for authentication keys
# TODO get authentication keys from server side
# options:
# authentication_keys: ['email']
# Widget initialization method, will be called upon loading, options
# are already filled with defaults
initialize: (options) ->
sandbox = @sandbox
sandbox.logger.log "initialized!"
base =
status: 'idle'
classes: =>
"widget #{@state} #{base.status} authenticator"
toggle_state: (event) =>
@state = if @state == 'default' then 'passwords' else 'default'
false
# Forward the models to the presenter
authenticator =
message: null
email: null
password: null
button_label: 'Authenticate!'
# Authentication state
authenticate: (event) ->
base.status = "loading" # replace all status
sandbox.emit 'user.sign_in', authentication
# Listeners
authenticated: (session) ->
base.status = "success"
unauthorized: ->
authentication.message = "Ops... seu e-mail ou senha estão incorretos. Tente mais uma vez!
Esqueceu sua senha? Clique aqui."
base.status = "error"
recoverer =
email: null
message: null
button_label: 'Recuperar senha'
# Recovery state
recover: (event, models) ->
base.status = 'loading'
sandbox.emit 'user.recover_password', recovery
recovered: (password) ->
base.status = 'success'
# Bind and unbind events depending on state
sandbox.on 'user.signed_in' , authenticator.authenticated
sandbox.on 'session.creation_unauthorized' , authenticator.unauthorized
sandbox.on 'user.password_recovered' , recoverer.recovered
# Will also initialize sandbox!
@$el.attr 'data-class', 'base.classes < base.status'
@presentation = presenter authenticator, recoverer, base
authentication = @presentation.authenticator
recovery = @presentation.recoverer
# TODO Extract to stateable widget
# TODO use observable
@observed ||= {}
Object.defineProperty @, 'state',
get: => @observed.state
set: @transition
@state = 'default'
# TODO Extract to stateable widget
# TODO use observable
transition: (to) ->
@html templates[to]
@bind @presentation
@sandbox.emit 'authenticator.state_changed', target: @, to: to
@observed.state = to