#ifndef PUZZLE_H
#define PUZZLE_H
#include "line.h"
#include "tile.h"
#include "phisics.h"
#define PF_RENDERED (1 << 0)
#define PF_BORDER_L (1 << 1)
#define PF_BORDER_R (1 << 2)
#define PF_BORDER_T (1 << 3)
#define PF_BORDER_B (1 << 4)
#define PF_HANDLE_L (1 << 5)
#define PF_HANDLE_R (1 << 6)
#define PF_HANDLE_T (1 << 7)
#define PF_HANDLE_B (1 << 8)
#define PF_BORDERS (PF_BORDER_L|PF_BORDER_R|PF_BORDER_T|PF_BORDER_B)
#define PF_RENDERING (PF_BORDERS|PF_RENDERED)
#define PF_HANDLES (PF_HANDLE_L|PF_HANDLE_R|PF_HANDLE_T|PF_HANDLE_B)
#define PCP_BODY 1
#define PCP_EDGE 2
typedef struct Puzzle Puzzle;
typedef struct {
Puzzle *pz;
int r, c;
Tile t;
PhGroup *parent;
PhGroup group;
PhNode nodes[5];
Flags flags;
} Chunk;
struct Puzzle {
int rows, cols, turn;
Vertex **hlines;
Vertex **vlines;
Physics ph;
Chunk **chunks;
int groups;
Animation image;
TileMap tm;
Vec cs;
Chunk **chunksOrder;
int activeChunks;
Vec gmouse;
int mousefix;
int longframe;
};
static inline Vec chunkGroupPos(Chunk *c)
{ return vmulv( vadd(vec(c->c, c->r), vecxy(0.5)), c->pz->cs ); }
static inline Vec chunkWorldPos(Chunk *c)
{ return phGroupTrans(c->parent, chunkGroupPos(c)); }
static inline int chunkId(Chunk *c)
{ return c - c->pz->chunks[0]; }
static inline int chunkGid(Chunk *c)
{ return chunkId( (Chunk*)((char*)c->parent - offsetof(Chunk, group)) ); }
unsigned int chunkCalcEdges(Chunk *c);
void chunkDrawBase(Chunk *c, unsigned int edges);
void chunkDraw(Chunk *c);
void chunkDrawDebug(Chunk *c);
void chunkRender(Chunk *c);
void chunkMerge(Chunk *a, Chunk *b);
void chunkTryMerge(Chunk *a, int dr, int dc);
Flags chunkCheckPoint(Chunk *c, Vec p);
int chunkCheckEdge(Chunk *c, Vec p);
void puzzleAlloc(Puzzle *pz, int rows, int cols);
void puzzleFree(Puzzle *pz);
void puzzleClearImages(Puzzle *pz);
void puzzleGenLines(Puzzle *pz, double cellw, double cellh, double jitter, double depth);
void puzzleRecalcGroups(Puzzle *pz);
void puzzleGenChunks(Puzzle *pz);
void puzzleRenderChunks(Puzzle *pz, int size, double m);
int puzzlePopupGroup(Puzzle *pz, PhGroup *g);
int puzzleChooseChunks(Puzzle *pz, Vec mouse);
void puzzleReleaseChunks(Puzzle *pz);
void puzzleUpdate(Puzzle *pz, Vec hs, Vec mouse);
#endif