#include <fmt/core.h>
#include <iostream>

enum {
  PLAIN=0,
  TITLE=1,
  ENUM=2
};

%%{
  machine Parser;
  alphtype char;

  action mark { start = fpc; }
  action title { last = TITLE; }

  action enum { last = ENUM; }

  action content {
    if(last == TITLE) {
      title = input.substr(start - begin, fpc - start);
    } else if(last == ENUM) {
      content += "* " + input.substr(start - begin, fpc - start);
      content += "\n";
    } else {
      content += input.substr(start - begin, fpc - start);
      content += "\n";
    }

    last = PLAIN;
  }
  action meta {
    tk = input.substr(start - begin, fpc - start);
    deck->config = json::parse(tk);
    std::cout << "META:" << deck->config << '\n';
  }

  action start { fmt::println("----- START"); }

  action start_slide {
    title.clear();
    content.clear();
  }

  action end_slide {
    deck->slides.emplace_back(title, content, config);
  }

  eol = '\n';
  start = '===' %start;
  end = '---' %end_slide;
  pound = '#' %title;
  asterisk = '*' %enum;
  dash = '-' %enum;

  meta = ('{' ( any+) :>> '}') >mark %meta;
  content = (any+ -- (eol|end)) >mark %content;
  title = pound space+ content eol;
  enum = (asterisk | dash) space+ content eol;
  line = content :>> eol;
  blank = space* eol;

  slide = (title | enum | line | blank)+ >start_slide end eol;

  main := meta eol start eol (slide)+;
}%%

%% write data;


bool Parser::parse(const std::string& input) {
  int cs = 0;
  const char *start = nullptr;
  const char *begin = input.data();
  const char *p = input.data();
  const char *pe = p + input.size();
  const char *eof = p + input.size(); (void)eof;
  std::string tk;

  %% write init;
  %% write exec;

  bool good = pe - p == 0;

  if(good) {
    finalize();
  } else {
    error = true;
    std::cout << "!!!!!!!!!!!!!!!!!!!!!! error at:";
    std::cout << p;
  }
  return good;
}
