#include "guecs/lel.hpp"
#include <fmt/core.h>
#include <iostream>

namespace lel {

%%{
  machine Parser;
  alphtype char;

  action token {tk = input.substr(start - begin, fpc - start); }

  action col {}
  action ltab { grid.push_back(Row()); }
  action valign { cur.bottom = fc == '.'; }
  action id { id(input.substr(start - begin, fpc - start)); }
  action row { cur.col = 0; cur.row++; }
  action align { cur.right = fc == '>'; }
  action setwidth {cur.max_w = std::stoi(tk); }
  action setheight { cur.max_h = std::stoi(tk); }
  action expand { cur.expand = true; }
  action center { cur.center = true; }
  action percent { cur.percent = true; }

  col = "|" $col;
  ltab = "[" $ltab;
  rtab = "]" $row;
  valign = ("^" | ".") $valign;
  expand = "*" $expand;
  center = "=" $center;
  percent = "%" $percent;
  halign = ("<" | ">") $align;
  number =  digit+ >{ start = fpc; } %token;
  setw = ("(" number %setwidth ("," number %setheight)? ")") ;
  modifiers = (percent | center | expand | valign | halign | setw);
  id = ((alpha | '_')+ :>> (alnum | '_')*) >{start = fpc;} %id;
  cell = modifiers* id;
  row = space* ltab space* cell space* (col space* cell space*)* space* rtab space*;

  main := row+;
}%%

%% write data;

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

  %% write init;
  %% write exec;

  bool good = pe - p == 0;
  if(good) {
    finalize();
  } else {
    std::cout << "error at:";
    std::cout << p;
  }
  return good;
}

}
