/*
 * OKP parsing library
 *
 * Copyright (C) 2020 Mateusz Viste
 *
 * MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

#ifndef okp_parse_h

#define OKPID(a,b) ((a << 8) | b)

enum okp_chunktype {
  OKP_FS = OKPID('f','s'),
  OKP_FC = OKPID('f','c'),
  OKP_LM = OKPID('l','m'),
  OKP_ME = OKPID('m','e'),
  OKP_WL = OKPID('w','l'),
  OKP_HE = OKPID('h','e'),
  OKP_MV = OKPID('m','v'),
  OKP_ER = 1
};

struct okp_chunklist {
  struct okp_chunklist *next;
  enum okp_chunktype id;
  union {
    struct {
      unsigned int w;
      unsigned int h;
    } fs;
    struct {
      unsigned int slen;
      char playfield[1];
    } fc;
    struct {
      unsigned int x;
      unsigned int y;
    } lm;
    struct {
      char ab;
    } me;
    struct {
      unsigned int x1;
      unsigned int y1;
      unsigned int x2;
      unsigned int y2;
    } wl;
    struct {
      unsigned int x;
      unsigned int y;
    } mv;
  } data;
};

/* parse an OKP string and explodes it into chunks.
 * returns a pointer to a chunklist on success, NULL on error.
 * the resulting list must be freed through okp_freelist() */
struct okp_chunklist *okp_parse(const char *okps);

/* free a chunklist returned by okp_parse() */
void okp_freelist(struct okp_chunklist *c);

#endif
