class app.views.EntryPage extends app.View
  @className: '_page'
  @errorClass: '_page-error'

  @events:
    click: 'onClick'

  @shortcuts:
    altC: 'onAltC'
    altO: 'onAltO'

  @routes:
    before: 'beforeRoute'

  init: ->
    @cacheMap = {}
    @cacheStack = []
    return

  deactivate: ->
    if super
      @empty()
      @entry = null
    return

  loading: ->
    @empty()
    @trigger 'loading'
    return

  render: (content = '', fromCache = false) ->
    return unless @activated
    @empty()
    @subview = new (@subViewClass()) @el, @entry

    $.batchUpdate @el, =>
      @subview.render(content, fromCache)
      @addCopyButtons() unless fromCache
      return

    if app.disabledDocs.findBy 'slug', @entry.doc.slug
      @hiddenView = new app.views.HiddenPage @el, @entry

    setFaviconForDoc(@entry.doc)
    @delay @polyfillMathML
    @trigger 'loaded'
    return

  addCopyButtons: ->
    unless @copyButton
      @copyButton = document.createElement('button')
      @copyButton.innerHTML = '<svg><use xlink:href="#icon-copy"/></svg>'
      @copyButton.type = 'button'
      @copyButton.className = '_pre-clip'
      @copyButton.title = 'Copy to clipboard'
      @copyButton.setAttribute 'aria-label', 'Copy to clipboard'
    el.appendChild @copyButton.cloneNode(true) for el in @findAllByTag('pre')
    return

  polyfillMathML: ->
    return unless window.supportsMathML is false and !@polyfilledMathML and @findByTag('math')
    @polyfilledMathML = true
    $.append document.head, """<link rel="stylesheet" href="#{app.config.mathml_stylesheet}">"""
    return

  LINKS =
    home: 'Homepage'
    code: 'Source code'

  prepareContent: (content) ->
    return content unless @entry.isIndex() and @entry.doc.links

    links = for link, url of @entry.doc.links
      """<a href="#{url}" class="_links-link">#{LINKS[link]}</a>"""

    """<p class="_links">#{links.join('')}</p>#{content}"""

  empty: ->
    @subview?.deactivate()
    @subview = null

    @hiddenView?.deactivate()
    @hiddenView = null

    @resetClass()
    super
    return

  subViewClass: ->
    app.views["#{$.classify(@entry.doc.type)}Page"] or app.views.BasePage

  getTitle: ->
    @entry.doc.fullName + if @entry.isIndex() then ' documentation' else " / #{@entry.name}"

  beforeRoute: =>
    @cache()
    @abort()
    return

  onRoute: (context) ->
    isSameFile = context.entry.filePath() is @entry?.filePath()
    @entry = context.entry
    @restore() or @load() unless isSameFile
    return

  load: ->
    @loading()
    @xhr = @entry.loadFile @onSuccess, @onError
    return

  abort: ->
    if @xhr
      @xhr.abort()
      @xhr = @entry = null
    return

  onSuccess: (response) =>
    return unless @activated
    @xhr = null
    @render @prepareContent(response)
    return

  onError: =>
    @xhr = null
    @render @tmpl('pageLoadError')
    @resetClass()
    @addClass @constructor.errorClass
    app.serviceWorker?.update()
    return

  cache: ->
    return if @xhr or not @entry or @cacheMap[path = @entry.filePath()]

    @cacheMap[path] = @el.innerHTML
    @cacheStack.push(path)

    while @cacheStack.length > app.config.history_cache_size
      delete @cacheMap[@cacheStack.shift()]
    return

  restore: ->
    if @cacheMap[path = @entry.filePath()]
      @render @cacheMap[path], true
      true

  onClick: (event) =>
    target = $.eventTarget(event)
    if target.hasAttribute 'data-retry'
      $.stopEvent(event)
      @load()
    else if target.classList.contains '_pre-clip'
      $.stopEvent(event)
      target.classList.add if $.copyToClipboard(target.parentNode.textContent) then '_pre-clip-success' else '_pre-clip-error'
      setTimeout (-> target.className = '_pre-clip'), 2000
    return

  onAltC: =>
    return unless link = @find('._attribution:last-child ._attribution-link')
    console.log(link.href + location.hash)
    navigator.clipboard.writeText(link.href + location.hash)
    return

  onAltO: =>
    return unless link = @find('._attribution:last-child ._attribution-link')
    @delay -> $.popup(link.href + location.hash)
    return
