/*
 * @(#)BarrelP.h
 *
 * Copyright 2003 - 2010  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 Barrel */

#ifndef _BarrelP_h
#define _BarrelP_h

#include "xwin.h"
#include "timer.h"
#include "Barrel.h"

#ifdef WINVER
extern void destroyPuzzle(BarrelWidget w, HBRUSH brush);
extern void resizePuzzle(BarrelWidget w);
extern void sizePuzzle(BarrelWidget w);
extern void initializePuzzle(BarrelWidget w, HBRUSH brush);
extern void exposePuzzle(BarrelWidget w);
extern void hidePuzzle(BarrelWidget w);
extern void selectPuzzle(BarrelWidget w,
	const int x, const int y, const int shift);
extern void motionPuzzle(BarrelWidget w,
	const int x, const int y, const int shift);
extern void releasePuzzle(BarrelWidget w,
	const int x, const int y, const int shift);
extern void practicePuzzle(BarrelWidget w);
extern void randomizePuzzle(BarrelWidget w);
extern void readPuzzle(BarrelWidget w);
extern void writePuzzle(BarrelWidget w);
extern void undoPuzzle(BarrelWidget w);
extern void redoPuzzle(BarrelWidget w);
extern void clearPuzzle(BarrelWidget w);
extern void solvePuzzle(BarrelWidget w);
extern void orientizePuzzle(BarrelWidget w);
extern void pairsPuzzle(BarrelWidget w);
extern void speedUpPuzzle(BarrelWidget w);
extern void slowDownPuzzle(BarrelWidget w);
extern void toggleSoundPuzzle(BarrelWidget w);
extern void enterPuzzle(BarrelWidget w);
extern void leavePuzzle(BarrelWidget w);
extern void movePuzzleInput(BarrelWidget w, int x, int direction, int shift);
extern int  movePuzzleDir(BarrelWidget w, const int direction);

#else

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

typedef struct _BarrelClassRec {
	CoreClassPart coreClass;
	BarrelClassPart barrelClass;
} BarrelClassRec;

extern BarrelClassRec barrelClassRec;
#endif

#ifndef BUMPSOUND
#define BUMPSOUND "bump"
#endif
#ifndef MOVESOUND
#define MOVESOUND "move"
#endif

#define SYMBOL ':'

#define TOP 0
#define RIGHT 1
#define BOTTOM 2
#define LEFT 3
#define COORD 4
#define MAX_COLORS (MAX_FACES+1)
#define PLUNGERS_NUMBER 3
#define FG_SHADES 3
#define MAX_SLICES 10

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

typedef struct _moveRecord {
#if 0
	int direction, control;
#endif
	unsigned char packed;	/* This makes assumptions on the data. */
	int tile;		/* Do not make assumptions on this one. */
} moveRecord;

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

typedef struct _BarrelStack {
	MoveStack *currMove, *lastMove, *firstMove;
	int count;
} BarrelStack;

typedef struct _BarrelPart {
	int        *tileOfPosition, spacePosition[PLUNGERS_NUMBER];
	int         currentTile, currentFace, currentRef;
	Boolean     started, cheat, sound, motion;
	Boolean     practice, orient, mono, reverse, pairs, focus;
	Boolean     scoreOnly, versionOnly;
	int         delay, numSlices, motionDiff, shiftDiff;
	int         base;
	int         tiles, faces, tileFaces;
	Point       offset, tileSize, faceSize, puzzleSize;
	Point       delta, puzzleOffset, digitOffset;
	GC          frameGC, borderGC, inverseGC;
	GC          tileGC[FG_SHADES];
	GC          faceGC[MAX_COLORS];
	Pixmap      bufferTiles[2];
	TimeVal     oldTime;
#ifdef WINVER
	char        userName[81], scoreFile[81], bumpSound[81], moveSound[81];
	char        picture[81];
	char        faceChar[MAX_COLORS];
#else
	int         menu, graphicsFormat, pixmapSize;
	char       *userName, *scoreFile, *bumpSound, *moveSound;
	char       *picture, *font;
	Boolean     install;
	Colormap    colormap, oldColormap;
	XImage     *image;
	XFontStruct *fontInfo;
	char       *faceName[MAX_COLORS];
	Pixel       foreground, background;
	Pixel       frameColor, tileColor, borderColor;
	Pixel       faceColor[MAX_COLORS];
	XtCallbackList select;
#endif
} BarrelPart;

typedef struct _BarrelRec {
	CorePart    core;
	BarrelPart   barrel;
} BarrelRec;

extern int *startPosition;
extern void setPuzzle(BarrelWidget w, int reason);
extern Boolean movePuzzle(BarrelWidget w,
	const int direction, const int tile, const int shift,
	const Boolean motion, const int speed);
extern void movePuzzleDelay(BarrelWidget w,
	const int direction, const int tile, const Boolean all);

extern void solveSomeTiles(BarrelWidget w);
extern void drawAllTiles(const BarrelWidget w);
extern Boolean checkSolved(const BarrelWidget w);
extern void newMoves(BarrelStack *s);
extern void deleteMoves(BarrelStack *s);
extern void setMove(BarrelStack *s, int direction, int tile, int control);
extern void getMove(BarrelStack *s, int *direction, int *tile, int *control);
extern int madeMoves(BarrelStack *s);
extern void flushMoves(BarrelWidget w, BarrelStack *s, Boolean undo);
extern int numMoves(BarrelStack *s);
extern void scanMoves(FILE *fp, BarrelWidget w, int moves);
extern void printMoves(FILE *fp, BarrelStack *s);
extern void scanStartPosition(FILE *fp, BarrelWidget w);
extern void printStartPosition(FILE *fp, BarrelWidget w);
extern void setStartPosition(BarrelWidget w);

#endif /* _BarrelP_h */
