#include <fmt/core.h>
#include <string_view>
#include <charconv>
#include "dbc.hpp"
#include <SFML/Graphics.hpp>

using namespace fmt;

%%{
  machine foo;

  action tstart {
    start = fpc;
  }

  action number {
    auto [ptr, ec] = std::from_chars(start, fpc, value);
    dbc::check(ec == std::errc(), "error in number parsing");
    println("NUM: {}", value);
  }

  action color24b {
    println("color24b");
  }

  action bg { fgcolor = false; }
  action fg { fgcolor = true; }

  action any {
    println("ANY: {}:{}", int(fc), fc);
  }

  action red { color.r = value; }
  action blue { color.g = value; }
  action green { color.b = value; }

  action start { value = 0; }

  action end {
    println("fg? {}, sf:Color: {},{},{},{}", fgcolor, color.r, color.g, color.b, color.a);
  }

  start = 0x1B "[";
  fg = "38;" %fg;
  bg = "48;" %bg;
  reset = ("39" | "49");
  num = digit+ >tstart %number;
  color256 = "5;";
  color24b = "2;";

  ansi = (
      start %start
      (
        reset |
        (fg|bg) color24b num %red ";" num %blue ";" num %green %color24b
      ) "m" %end
  );

  other = (any+ @any -- 0x1B)*;

  main := (other :> ansi)**;
}%%

%% write data;

bool parse_ansi(std::string_view codes) {
  const char *start = NULL;
  int cs = 0;
  uint8_t value = 0;
  const char *p = codes.data();
  const char *pe = p + codes.size();
  const char *eof = pe;
  bool fgcolor = false;
  sf::Color color;

  %% write init;
  %% write exec;

  print("PROCESSED {} CHARS of {}: {}", p - codes.data(), codes.size(), p);

  return true;
}
