/*
 * @(#)TrianglesP.h
 *
 * Copyright 1994 - 2022  David A. Bagley, bagleyd AT verizon.net
 *
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear in
 * supporting documentation, and that the name of the author not be
 * used in advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 *
 * This program is distributed in the hope that it will be "useful",
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

/* Private header file for Triangles */

#ifndef _TrianglesP_h
#define _TrianglesP_h

#include "xwin.h"
#include "timer.h"
#include "Triangles.h"

#ifdef WINVER
extern void destroyPuzzle(TrianglesWidget w, HBRUSH brush);
extern void resizePuzzle(TrianglesWidget w);
extern void sizePuzzle(TrianglesWidget w);
extern void initializePuzzle(TrianglesWidget w, HBRUSH brush);
extern void exposePuzzle(TrianglesWidget w);
extern void hidePuzzle(TrianglesWidget w);
extern void selectPuzzle(TrianglesWidget w, const int x, const int y);
extern void releasePuzzle(TrianglesWidget w);
extern void getPuzzle(TrianglesWidget w);
extern void writePuzzle(TrianglesWidget w);
extern void undoPuzzle(TrianglesWidget w);
extern void redoPuzzle(TrianglesWidget w);
extern void clearPuzzle(TrianglesWidget w);
extern void randomizePuzzle(TrianglesWidget w);
extern void solvePuzzle(TrianglesWidget w);
extern void cornersPuzzle(TrianglesWidget w);
extern void incrementPuzzle(TrianglesWidget w);
extern void decrementPuzzle(TrianglesWidget w);
extern void speedUpPuzzle(TrianglesWidget w);
extern void slowDownPuzzle(TrianglesWidget w);
extern void toggleSoundPuzzle(TrianglesWidget w);
extern void enterPuzzle(TrianglesWidget w);
extern void leavePuzzle(TrianglesWidget w);
extern int movePuzzle(TrianglesWidget w, const int direction,
	const int control);

#else

/* This gets around C's inability to do inheritance */
typedef struct _TrianglesClassPart {
	int ignore;
} TrianglesClassPart;

typedef struct _TrianglesClassRec {
	CoreClassPart coreClass;
	TrianglesClassPart trianglesClass;
} TrianglesClassRec;

extern TrianglesClassRec trianglesClassRec;
#endif

#ifndef BUMPSOUND
#define BUMPSOUND "bump"
#endif

#define SYMBOL ':'

#define TR 0
#define RIGHT 1
#define BR 2
#define BL 3
#define LEFT 4
#define TL 5
#define TOP 6
#define BOTTOM 7
#define COORD 6
#define TRBL 0
#define TLBR 1
#define ROW 2
#define ROW_TYPES 3
#define DOWN 0
#define UP 1
#define MAX_ORIENT 2
#define BLOCKED (-3)
#define SPACE (-2)
#define FG_SHADES 3
#define BG_SHADES 5
#define MAX_SLICES 10

#define NORMAL 1
#define DOUBLE 2
#define INSTANT 3

typedef struct _MoveRecord {
#if 0
	int direction;
#endif
	unsigned char packed;	/* This makes assumptions on the data. */
} MoveRecord;

typedef struct _MoveStack {
	MoveRecord move;
	struct _MoveStack *previous, *next;
} MoveStack;

typedef struct _TrianglesStack {
	MoveStack *currMove, *lastMove, *firstMove;
	int count;
} TrianglesStack;

typedef struct _TrianglesPart {
	int        *tileOfPosition, spacePosition[MAX_ORIENT];
	int         spaceRow[MAX_ORIENT][ROW_TYPES];
	int         currentPosition, currentRow[ROW_TYPES];
	int         spaceOrient, currentPositionOrient;
	Boolean     started, cheat, sound;
	Boolean     corners, mono, reverse, focus;
	Boolean     scoreOnly, versionOnly;
	int         delay, numSlices;
	int         base;
	int         sizeX, sizeY, sizeSize, prevSizeSize;
	Point       offset, tileSize, puzzleSize;
	Point       delta, puzzleOffset, digitOffset;
	GC          textGC;
	GC          tileGC[FG_SHADES];
	GC          inverseGC[BG_SHADES];
	Pixmap      bufferTiles[2];
	TimeVal     oldTime;
#ifdef WINVER
	char        userName[81], scoreFile[81], bumpSound[81];
	char	    picture[81];
#else
	int         menu, graphicsFormat, pixmapSize;
	char       *userName, *scoreFile, *bumpSound;
	char       *picture, *font;
	Boolean     install;
	Colormap    colormap, oldColormap;
	XImage     *image;
	XFontStruct *fontInfo;
	Pixel       foreground, background;
	Pixel       tileColor, textColor;
	XtCallbackList select;
#endif
} TrianglesPart;

typedef struct _TrianglesRec {
	CorePart core;
	TrianglesPart triangles;
} TrianglesRec;

extern int *startPosition;
extern void setPuzzle(TrianglesWidget w, int reason);
extern int movePuzzleDir(TrianglesWidget w, const int direction,
	const int fast);

#ifdef TRY
/* For future auto-solver */
extern void solveSomeTiles(TrianglesWidget w);
#endif
extern void drawAllTiles(const TrianglesWidget w);
extern Boolean checkSolved(const TrianglesWidget w);
extern void newMoves(TrianglesStack *s);
extern void deleteMoves(TrianglesStack *s);
extern void setMove(TrianglesStack *s, int direction);
extern void getMove(TrianglesStack *s, int *direction);
extern int madeMoves(TrianglesStack *s);
extern void flushMoves(TrianglesWidget w, TrianglesStack *s, Boolean undo);
extern int numMoves(TrianglesStack *s);
extern Boolean scanMoves(FILE *fp, TrianglesWidget w, int moves);
extern void printMoves(FILE *fp, TrianglesStack *s);
extern Boolean scanStartPosition(FILE *fp, TrianglesWidget w);
extern void printStartPosition(FILE *fp, TrianglesWidget w);
extern void setStartPosition(TrianglesWidget w);
extern int toRow(TrianglesWidget w, const int pos);
extern int toTrBl(TrianglesWidget w, const int pos, const int posRow);
extern int toTlBr(TrianglesWidget w, const int pos, const int posRow);

#endif /* _TrianglesP_h */
