var assert = require('assert');

module.exports = function formatText(text, options) {
  assert(text.shift() == 'text');

  var result = [];
  text.forEach(function(block) {
    result.push(formatBlock(block));
  });

  var output = result.join('\n\n') + '\n';
  if (options.standalone)
    output = header + output + footer;
  return output;
};

function formatBlock(block) {
  var type = block.shift();
  var attr = block.shift();

  var spans = [];
  block.forEach(function(span) {
    spans.push(formatSpan(span));
  });
  var text = spans.join('');

  switch (type) {
    case 'heading': return '\\section{' + text + '}';
    default: return text;
  };
};

function formatSpan(span) {
  var type = span.shift();
  var text = span.shift();
  assert(span.length == 0);

  switch (type) {
    default: return escape(text);
  };
};

function escape(str) {
  return str.
    replace(/\\/g,'\\textbackslash').
    replace(/{/g,'\\{').
    replace(/}/g,'\\}').
    replace(/~/g,'\\~{}').
    replace(/\$/g,'\\$');
};

var header = 
  '\\documentclass[10pt]{article}\n' +
  '\n' +
  '\\begin{document}\n\n';

var footer =
  '\n\n\\end{document}\n';

var assert = require('assert');
var wrap = require('../wrap');

module.exports = function formatText(text, options) {
  assert(text.shift() == 'text');

  var result = [];
  text.forEach(function(block) {
    result.push(formatBlock(block));
  });

  var output = result.join('\n\n') + '\n';
  if (options.standalone)
    output = header + output + footer;
  return output;
};

function formatBlock(block) {
  var type = block.shift();
  var attr = block.shift();

  switch (type) {
    case 'divider': return '\\hrulefill';
    case 'image': return formatImage(block);
    case 'heading': return '\\' + repeat('sub', attr.level-1) + 'section{' + formatSpans(block) + '}';
    case 'bulleted': return wordWrap(formatSpans(block), '\\item ');
    case 'numbered': return wordWrap(formatSpans(block), '\\item ');
    case 'quote': return '\\begin{quotation}\n' + wordWrap(formatSpans(block)) + '\n\\end{quotation}';
    case 'link': return null;
    case 'note': return null;
    case 'verbatim': return '\\begin{verbatim}\n' + formatSpans(block) + '\n\\end{verbatim}';
    case 'formula': return  '\\begin{equation}\n' + formatSpans(block) + '\n\\end{equation}';
    default: return wordWrap(formatSpans(block));
  };
};

var formatImage = function(spans) {
  return formatSpans(spans);
};

function wordWrap(text, prefix, firstPrefix) {
  return wrap(text, prefix, firstPrefix, '\\\\');
};

function formatSpans(spans) {
  return spans.map(formatSpan).join('');
}

function formatSpan(span) {
  var type = span.shift();
  var text = span.shift();
  assert(span.length == 0);

  switch (type) {
    default: return escape(text);
  };
};

function escape(str) {
  return str.
    replace(/\\/g,'\\textbackslash').
    replace(/{/g,'\\{').
    replace(/}/g,'\\}').
    replace(/~/g,'\\~{}').
    replace(/\$/g,'\\$');
};

function repeat(str, times) {
  return new Array(times+1).join(str);
};

var header = 
  '\\documentclass[10pt]{article}\n' +
  '\n' +
  '\\begin{document}\n\n';

var footer =
  '\n\n\\end{document}\n';

Implement basic block formatting.