class Grant < Vue
  def initialize
    @filed = false
    @submitted = false
  end

  def render
    _h4 'Grant'

    _div.buttons do
      _button 'clear form', disabled: @filed, onClick: lambda {@name = @email = ''}
    end

    _form method: 'post', action: '../../tasklist/grant', target: 'content' do
      _input type: 'hidden', name: 'message'
      _input type: 'hidden', name: 'selected'
      _input type: 'hidden', name: 'signature', value: @@signature

      _table.form do
        _tr do
          _th 'From'
          _td do
            _input name: 'company', value: @company, required: true,
               disabled: @filed
          end
        end

        _tr do
          _th 'For'
          _td do
            _textarea name: 'description', value: @description, rows: 5,
              required: true, disabled: @filed
          end
        end

        _tr do
          _th 'Signed By'
          _td do
            _input name: 'name', value: @name, required: true, disabled: @filed
          end
        end

        _tr do
          _th 'E-mail'
          _td do
            _input name: 'email', value: @email, required: true, type: 'email',
              disabled: @filed
          end
        end

        _tr do
          _th 'File Name'
          _td do
            _input name: 'filename', value: @filename, required: true,
              pattern: '[a-zA-Z][\-\w]+(\.[a-z]+)?', disabled: @filed # bare '-' not allowed in v-mode character classes
          end
        end

        _tr do
          _th 'Project'
          _td do
            _select name: 'project', value: @project, disabled: @filed do
              _option ''
              @@projects.each do |project|
                _option project
              end
            end
          end
        end
      end

      _input.btn.btn_primary value: 'File', type: 'submit', ref: 'file'
    end
  end

  # on initial display, default various fields based on headers, and update
  # state
  def mounted()
    name = @@headers.name || ''

    # reorder name if there is a single comma present
    parts = name.split(',')
    if parts.length == 2 and parts[1] !~ /^\s*(jr|ph\.d)\.?$/i
      name = "#{parts[1].strip()} #{parts[0]}"
    end

    @name = name
    @email = @@headers.from

    # watch for status updates
    window.addEventListener 'message', self.status_update
  end

  def beforeDestroy()
    window.removeEventListener 'message', self.status_update
  end

  # as fields change, enable/disable the associated buttons and adjust
  # input requirements.
  def updated()
    # Grant file form
    valid = %w(company name email filename).all? do |name|
      document.querySelector("input[name=#{name}]").validity.valid
    end

    valid &= document.querySelector('textarea[name=description]').validity.valid

    $refs.file.disabled = !valid or @filed or @submitted

    # wire up form
    jQuery('form')[0].addEventListener('submit', self.file)
    jQuery('input[name=message]').val(window.parent.location.pathname)
    jQuery('input[name=selected]').val(decodeURIComponent(@@selected))

    # Safari autocomplete workaround: trigger change on leaving field
    # https://github.com/facebook/react/issues/2125
    if navigator.userAgent.include? 'Safari'
      Array(document.getElementsByTagName('input')).each do |input|
        input.addEventListener('blur', self.onblur)
      end
    end
  end

  # when leaving an input field, trigger change event (for Safari)
  def onblur(event)
    jQuery(event.target).trigger(:change)
  end

  # handle Grant form submission
  def file(event)
    setTimeout 0 do
      @submitted = true
      @filed = true
    end
  end

  # when tasks complete (or are aborted) reset form
  def status_update(event)
    @submitted = false
    @filed = false
  end
end
