
# dependencies
_ = require 'underscore.string'
htmlEncode = require('js-htmlencode').htmlEncode

# regex
exps = [
  ['eol', /^$/, '']
  ['pre', /^```$/, '']
  ['html', /^(<.*)$/, '$1']
  ['embed', /<\[([^\]]*)\]>$/, '$1', 'full-width']
  ['embed', /^\[([^\]]*)\]$/, '$1']
  ['hr', /^\-\-(\-)+$/, '']
  ['ul', /^-\s+/, '', 'dash']
  ['ul', /^o\s+/, '', 'circle']
  ['ul', /^\[\s\]\s+/, '', 'checkbox']
  ['ul', /^\[x\]\s+/, '', 'checkbox checked']
  ['ol', /^[0-9]+\.\s*/, '', 'decimal']
  ['ol', /^[a-z]\.\s*/, '', 'lower-alpha']
  ['ol', /^[A-Z]\.\s*/, '', 'upper-alpha']
  ['blockquote', /^>\s*/, '']
  ['caption', /^\^\s*/, '']
  ['h6', /^######\s*/, '']
  ['h5', /^#####\s*/, '']
  ['h4', /^####\s*/, '']
  ['h3', /^###\s*/, '']
  ['h2', /^##\s*/, '']
  ['h1', /^#\s*/, '']
  ['table', /^\|/, '']
]

# get line type
parseLine = (lines, index) ->
  prev = _.trim lines[index - 1]
  line = _.trim lines[index]

  for [kind, re, repl, cls] in exps
    if re.test line
      return [kind, line.replace(re, repl), cls]

  return ['p', line] if prev is '' and line isnt ''
  return ['text', line]

# parse the content
parse = (content = '') ->
  lines = content.split '\n'

  output = '<div class="markdown">'
  state = {
    pre: false
    ol: false
    p: false
    table: false
    ul: false
  }

  index = 0
  while index < lines.length + 1
    [kind, line, cls] = parseLine lines, index

    kind = 'pre' if state.pre and kind in ['html', 'text']

    # start multi-line formatting
    if kind in ['pre', 'ol', 'ul', 'table'] and not state[kind]
      state[kind] = true
      output += "<#{kind}>"

    # end multi-line formatting
    for x in ['pre', 'ol', 'ul', 'table']
      if state[x] and kind isnt x
        state[x] = false
        output = output.trim() if x is 'pre'
        output += "</#{x}>"

    # paragraph start/end
    if kind is 'p' and not state.p
      state.p = true
      output += "<div class='paragraph'>"
    if kind is 'eol' and state.p
      state.p = false
      output += "</div>"

    # inline formatting
    line = line.replace /\(([^\)]*)\)->\[([^\]]*)\]/g, "<a href='$2'>$1</a>" # link with spaces
    line = line.replace /([^\s]*)->\[(.*)\]/g, "<a href='$2'>$1</a>" # link shortcut
    line = line.replace /\[(.*\.jpg)\]/, "<img src='$1' />"
    line = line.replace /\[(.*\.png)\]/, "<img src='$1' />"
    line = line.replace /\*\*([^\*]*)\*\*/g, "<span class='bold'>$1</span>"
    line = line.replace /\/\/([^\/]*)\/\//g, "<span class='italic'>$1</span>"
    line = line.replace /__([^\_]*)__/g, "<span class='underline'>$1</span>"
    line = line.replace /`([^\`]*)`/g, "<span class='inline-code'>$1</span>"

    switch kind
      when 'pre' then output += htmlEncode(line) + '\n'
      when 'p' then output += line
      when 'html' then output += line
      when 'text' then output += line
      when 'ul' then output += "<li class=\"#{cls}\">#{line}</li>"
      when 'ol' then output += "<li class=\"#{cls}\">#{line}</li>"
      when 'h1' then output += "<h1>#{line}</h1>"
      when 'h2' then output += "<h2>#{line}</h2>"
      when 'h3' then output += "<h3>#{line}</h3>"
      when 'h4' then output += "<h4>#{line}</h4>"
      when 'h5' then output += "<h5>#{line}</h5>"
      when 'h6' then output += "<h6>#{line}</h6>"
      when 'hr' then output += "<div class=\"hr\"></div>"
      when 'blockquote' then output += "<blockquote>#{line}</blockquote>"
      when 'caption' then output += "<div class=\"caption\">#{line}</div>"
      when 'table'
        cells = (cell.trim() for cell in _(line).trim('|').split('|'))
        output += "<tr>"
        output += "<td>#{cell}</td>" for cell in cells
        output += "</tr>"

    if kind is 'embed'
      output += "<div class=\"embed #{cls or ''}\">"
      if _(line.toLowerCase()).endsWith '.jpg'
        output += "<img src=\"#{line}\" />"
      else if _(line.toLowerCase()).endsWith '.png'
        output += "<img src=\"#{line}\" />"
      else if _(line.toLowerCase()).endsWith '.svg'
        output += "<img src=\"#{line}\" />"
      else if _(line.toLowerCase()).contains 'youtube.com'
        id = line.match(/youtube\.com\/watch\?v=([\-a-zA-Z0-9_]+)/)?[1]
        if id
          output += "<iframe src=\"https://www.youtube.com/embed/#{id}\" width=\"100%\"></iframe>"
      else
        output += "<iframe src=\"#{line}\" width=\"100%\"></iframe>"
      output += "</div>"

    # next
    index++

  output += "</div>"
  return output

# template
module.exports = (content) ->
  raw parse content
