/*
 * mtsedit/main.h
 *
 * Copyright (C) 2019 bzt (bztsrc@gitlab)
 *
 * 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.
 *
 * @brief Main header
 *
 */

#ifndef _MSC_VER
#define _inline __inline__
#define _pack __attribute__((packed))
#define _unused __attribute__((unused))
#else
#define _inline
#define _pack
#define _unused
#endif
#ifndef  __cplusplus
#define _register register
#else
#define _register
#endif

#define THEME_INPUT     0
#define THEME_TABA      1
#define THEME_FG        2
#define THEME_TABU      3
#define THEME_INACT     4
#define THEME_BGLOGO    5
#define THEME_BG        6
#define THEME_INPBG     7
#define THEME_TABBG     8
#define THEME_SAVEACT   9
#define THEME_SAVEINACT 10
#define THEME_BP_FG     11
#define THEME_BP_BG     12

#define HIST_EMPTY       0
#define HIST_NODE        1
#define HIST_BRUSH       2
#define HIST_ADDY        3
#define HIST_DELY        4
#define HIST_ADDZ        5
#define HIST_DELZ        6
#define HIST_ADDX        7
#define HIST_DELX        8
#define HIST_ROTCW       9
#define HIST_ROTCCW     10
#define HIST_FLIP       11

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <limits.h>
#include <SDL.h>
#include "stb_image.h"
#include "lang.h"
/* must be 768 at least */
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif

#ifdef __WIN32__
#include <windows.h>
#define DIRSEP '\\'
#else
#define DIRSEP '/'
extern char *home;
#endif

typedef struct {
    char *name;
    char **blocknames;
    int numref;
    char numpar2;
    char rotate;
    char dobiome;
    uint32_t color;
    unsigned short blockids[4];
    unsigned char *img;
    unsigned char *dr;
    unsigned char *tr;
} mtsblock_t;

extern int numpalettes, lenpalettes, palette[16], strmaxw, strsepar, savelen, savepos, savepal, savemapgen, savebiome;
extern int numresults, *results;
extern int currlayer, gndlayer, mts_x, mts_y, mts_z, mix, miy, miz, max, may, maz, bound_valid, dx, dz, cx, cz, ox, oy, up, zoom;
/* that stupid MacOSX math.h defines y0, y1 and it is INCLUDED even if you don't #include math.h and don't link with -lm... */
extern int zx, zz, zs, shift, ctrl, activetool, activeblock, quitting, verbose, x0, x1, _y0, _y1, y3, brush_type, brush_hollow;
extern char **palettes, layerprob[256], *remapfile, noblocknametranslate;
extern int numblocks;
extern mtsblock_t *blocks;

typedef struct {
    unsigned short param0;
    unsigned char param1;
    unsigned char param2;
} node_t;
extern node_t nodes[256][256][256];

typedef struct {
    unsigned short oldparam0;
    unsigned char oldparam2;
    unsigned short newparam0;
    unsigned char newparam2;
    unsigned char x;
    unsigned char y;
    unsigned char z;
} hist_t;

typedef struct {
    unsigned char type;
    unsigned char x;
    unsigned char y;
    unsigned char z;
    union {
        struct multiple_s {
            int numentry;
            hist_t *entry;
        } multiple;
        struct bulk_s {
            unsigned short numentry;
            unsigned char pitch;
            node_t *entry;
        } bulk;
        struct node_s {
            unsigned short oldparam0;
            unsigned char oldparam2;
            unsigned short newparam0;
            unsigned char newparam2;
        } node;
    } data;
} histlist_t;
extern histlist_t histcurr;

typedef struct {
    char text;
    char *key;
} help_t;

/* PC Screen Font as used by Linux Console */
typedef struct {
    unsigned int magic;
    unsigned int version;
    unsigned int headersize;
    unsigned int flags;
    unsigned int numglyph;
    unsigned int bytesperglyph;
    unsigned int height;
    unsigned int width;
    unsigned char glyphs;
} _pack psf_t;

extern psf_t *font;
extern uint32_t theme[];
extern char *path, *fn, mtsfile[MAXPATHLEN], *status, **lang;
extern unsigned char *tmpblk;
extern SDL_Window *window;
extern SDL_Surface *screen, *icons, *blk, *fg, *cl, *bg;

/* util.c */
unsigned char *readfile(char *file, unsigned int *size);
void readschem();
void error(char *msg);
void errorcsv(int line);
int mbstrlen(char *s);
int isdir(char *path);
int listdir(char *path, char ***files, int type);
void freedir(int n, char ***files);
void detcube(int w, int h, unsigned char *block);
int instmod(unsigned char *data, int size);
int stairgen();
int blockgen(char *blockid);
int is_color_unique(uint32_t color);
int color2blockid(uint32_t color);
void gimppal();
void mapperpal();
void tileremap();

/* blocks.c */
void blocks_getdir(char **argv, char **envp);
void blocks_parse();
void blocks_free();

/* schemimp.c */
void schem_load(unsigned char *data, unsigned int size);
void bprint_load(unsigned char *data, unsigned int size);
void m3d_load(unsigned char *data, unsigned int size);
void tmx_load(unsigned char *data, unsigned int size);
void gox_load(unsigned char *data, unsigned int size);
void vox_load(unsigned char *data, unsigned int size);
int vox_save();
void qb_load(unsigned char *data, unsigned int size);
void we_load(unsigned char *data, unsigned int size);

/* mts.c */
void mts_load(unsigned char *data, unsigned int size);
int mts_save();
int mts_view(int type);
int mts_blueprint(int type);
int mts_dump();
int mts_getbounds(int sanitize, unsigned short *tr, unsigned short *tr2);
void mts_layerprob(int diff);
void mts_rotate(int ccw);
void mts_flip();
void mts_addy(int y, int copy);
void mts_dely(int y);
void mts_addz(int z, int copy);
void mts_delz(int z);
void mts_addx(int x, int copy);
void mts_delx(int x);

/* sdl.c */
void sdlprint(int x, int y, int fg, int bg, char *s);
void sdlredraw();
void sdldo(int opt);
int sdlmain(int opt);

/* edit.c */
void edit_placenode(int y, int z, int x, int i);
void edit_pipette(int y, int z, int x);
int edit_zoomin();
int edit_zoomout();
void edit_redraw(int full);
int edit_scroll(SDL_Event *event);
void edit_mouseover(SDL_Event *event);
void edit_mousedown(_unused SDL_Event *event);
void edit_key(SDL_Event *event);
void edit_rotate(int y, int z, int x, int ccw);

/* hist.c */
void hist_prepare(int type, int volume);
void hist_commit();
void hist_add(int y, int z, int x, unsigned short op0, unsigned char op2, unsigned short np0, unsigned char np2);
int hist_undo();
int hist_redo();
void hist_free(int s, int e);

/* load.c */
void load_redraw();
void load_scroll(SDL_Event *event);
void load_mousedown(SDL_Event *event);
void load_key(SDL_Event *event);

/* save.c */
void save_redraw();
void save_scroll(SDL_Event *event);
void save_mousedown(SDL_Event *event);
void save_key(SDL_Event *event);

/* search.c */
void search_redraw();
void search_scroll(SDL_Event *event);
void search_mousedown(SDL_Event *event);
void search_mouseover(SDL_Event *event);
void search_key(SDL_Event *event);

/* brush.c */
void brush_setmask(int needmax);
int brush_selected(int x, int z);
void brush_place(int blk);
void brush_floodfill(int blk);
int brush_height();
void brush_redraw();
int brush_mousedown(_unused SDL_Event *event);
void brush_key(SDL_Event *event);
