function addPageNumbers() {
  let pages = document.getElementsByTagName('section')

  for (let i = 2; i <= pages.length; i++) {
    let div = document.createElement('div')
    div.classList.add('page-number')
    div.textContent = i
    pages[i - 1].id = 'page-' + i
    pages[i - 1].appendChild(div)
  }
}

function addTableOfContents() {
  let pages = document.getElementsByTagName('section')
  let hs = document.querySelectorAll('h1,h2,h3')
  let ol = document.createElement('ol')
  ol.classList.add('table-of-contents')

  let prefix_counter = [0, 0, 0]
  let page_counter = 2
  let page = document.querySelector('section')

  for (const h of hs) {
    let level = {
      'H1': 0,
      'H2': 1,
      'H3': 2,
    }[h.tagName]

    prefix_counter[level]++
    for (let i = level + 1; i < prefix_counter.length; i++)
      prefix_counter[i] = 0

    let prefix = ''
    for (let i = 0; i <= level; i++)
      prefix += prefix_counter[i] + '.'

    prefix = prefix.slice(0, prefix.length - 1)

    let li = document.createElement('li')
    let name = document.createElement('span')
    let page_number = document.createElement('a')

    name.innerHTML = prefix + ' - ' + h.innerHTML
    h.innerHTML = name.innerHTML

    let cur_page = h.closest('section')
    while (page && page != cur_page) {
      page = page.nextElementSibling
      if (page.tagName == 'SECTION') {
        page_counter++
      }
    }
    page_number.href = '#page-' + page_counter
    page_number.innerHTML = page_counter

    li.append(name, page_number)
    ol.appendChild(li)
  }

  let header = document.createElement('header')
  header.innerText = 'Содержание'
  let section = document.createElement('section')
  section.classList.add('col')
  pages[0].after(section)
  pages[1].appendChild(header)
  pages[1].appendChild(ol)
}

function addCaptions() {
  const objs = document.querySelectorAll('img, table')
  const obj_counter = {
    'IMG': 1,
    'TABLE': 1,
  }

  const counter_by_tag = {}

  for (const obj of objs) {
    const cap = document.createElement('caption')

    const prefix = {
      'IMG': 'Рисунок ',
      'TABLE': 'Таблица ',
    }[obj.tagName] + obj_counter[obj.tagName]

    cap.innerHTML = prefix + ' - ' + {
      'IMG': obj.alt,
      'TABLE': obj.dataset.alt,
    }[obj.tagName]

    let div = document.createElement('div')
    div.classList.add(...({
      'IMG': ['col', 'y-center'],
      'TABLE': ['colr', 'y-start'],
    })[obj.tagName])
    div.style.cssText = obj.style.cssText
    if (obj.dataset.style) {
      obj.style = obj.dataset.style
    } else {
      obj.style.cssText = 'width: 100%'
    }

    if (obj.dataset.tag) {
      counter_by_tag[obj.dataset.tag] = obj_counter[obj.tagName]
      div.id = 'tag-' + obj.dataset.tag
    }

    let prev = obj.previousSibling
    obj.remove()
    div.append(obj, cap)
    prev.after(div)
    obj_counter[obj.tagName]++
  }

  const refs = document.querySelectorAll('span[data-ref],a[data-ref]')

  for (const ref of refs) {
    switch (ref.tagName) {
      case 'A':
        ref.href = '#tag-' + ref.dataset.ref
      case 'SPAN':
        ref.innerHTML = counter_by_tag[ref.dataset.ref] ?? 'без номера'
        break
    }
  }
}

function genTables() {
  let tables = document.getElementsByTagName('table')

  for (const table of tables) {
    if (!table.dataset.gen)
      continue

    let row = document.createElement('tr')
    let dot = document.createElement('td')
    let value = ''

    const gen = table.dataset.gen
    for (let i = 0; i < gen.length;) {
      const char = gen[i]
      switch (char) {
        case ',':
          dot.innerHTML = value
          value = ''
          row.appendChild(dot)
          dot = document.createElement('td')
          i++
          break

        case ';':
          dot.innerHTML = value
          value = ''
          row.appendChild(dot)
          dot = document.createElement('td')
          table.appendChild(row)
          row = document.createElement('tr')
          i++
          break

        case '$':
          const args_end = gen.indexOf('$', i + 1)
          const args = gen.slice(i + 1, args_end).split(',')
          switch (args[0]) {
            case 'C':
              dot.colSpan = +args[1]
              break

            case 'R':
              dot.rowSpan = +args[1]
              break

            case 'c':
              dot.style.backgroundColor = {
                'r': 'lightcoral',
                'g': 'lightgreen',
                'b': 'lightblue',
              }[args[1]] ?? 'white'
              break
          }
          i = args_end + 1
          break

        default:
          value += char
          i++
          break
      }
    }
  }
}

function genMathML() {
  TeXZilla.setSafeMode(true)
  const maths = document.querySelectorAll('.tex')

  for (const math of maths)
    TeXZilla.filterElement(math)
}

function handleQueryParams() {
  const params = new URLSearchParams(location.search)
  if (params.has('printable')) {
    const pages = document.querySelectorAll('section.landscape')
    for (const page of pages) {
      page.style.transform = 'rotate(90deg)'
    }
  }
}

addTableOfContents()
addPageNumbers()
addCaptions()
genTables()
genMathML()
handleQueryParams()
