/*
 * @(#)CubesP.h
 *
 * Copyright 1994 - 2008  David A. Bagley, bagleyd@tux.org
 *
 * 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 Cubes */

#ifndef _CubesP_h
#define _CubesP_h

#include "xwin.h"
#include "timer.h"
#include "Cubes.h"

#ifdef WINVER

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

#else

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

typedef struct _CubesClassPart {
	int         ignore;
} CubesClassPart;

typedef struct _CubesClassRec {
	CoreClassPart coreClass;
	CubesClassPart cubesClass;
} CubesClassRec;

extern CubesClassRec cubesClassRec;
#endif

#ifndef BUMPSOUND
#define BUMPSOUND "bump"
#endif
#ifndef DRIPSOUND
#define DRIPSOUND "drip"
#endif

#define SYMBOL ':'

#define TOP 0
#define RIGHT 1
#define BOTTOM 2
#define LEFT 3
#define INWARDS 4
#define OUTWARDS 5
#define COORD 6
#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 _CubesStack {
        MoveStack *currMove, *lastMove, *firstMove;
        int count;
} CubesStack;

typedef struct _CubesPart {
	int        *blockOfPosition, spacePosition;
	int         currentPosition, currentRow[3];
	Boolean     started, cheat, sound;
	Boolean     vertical, mono, reverse, focus;
	Boolean     scoreOnly, versionOnly;
	int         delay, numSlices;
	int         base;
	int         sizeX, sizeY, sizeZ, sizeRect, sizeBlock;
	Point       offset;
	Point       blockSize, faceSize, puzzleSize;
	Point       delta, puzzleOffset, digitOffset;
	GC          frameGC, textGC;
	GC          blockGC[FG_SHADES];
	GC          inverseGC[BG_SHADES];
	Pixmap      bufferBlocks[2];
	TimeVal     oldTime;
#ifdef WINVER
	char        userName[81], scoreFile[81], bumpSound[81], dripSound[81];
	char        picture[81];
#else
	char       *userName, *scoreFile, *bumpSound, *dripSound;
	char       *picture, *font;
	int         menu, graphicsFormat, pixmapSize;
	Boolean     install;
	Colormap    colormap, oldColormap;
	XImage     *image;
	XFontStruct *fontInfo;
	Pixel       foreground, background;
	Pixel       frameColor, blockColor, textColor;
	XtCallbackList select;
#endif
} CubesPart;

typedef struct _CubesRec {
	CorePart    core;
	CubesPart   cubes;
} CubesRec;

extern int *startPosition;
extern void setPuzzle(CubesWidget w, int reason);
extern int movePuzzleDir(CubesWidget w, const int direction, const int fast);
extern void animateSlide(CubesWidget w, int numBlocks, int direction, int fast,
	Boolean logMoves);

extern void solveSomeBlocks(CubesWidget w);
extern void drawAllBlocks(const CubesWidget w);
extern Boolean checkSolved(const CubesWidget w);
extern void newMoves(CubesStack *s);
extern void deleteMoves(CubesStack *s);
extern void setMove(CubesStack *s, int direction);
extern void getMove(CubesStack *s, int *direction);
extern int madeMoves(CubesStack *s);
extern void flushMoves(CubesWidget w, CubesStack *s, Boolean undo);
extern int numMoves(CubesStack *s);
extern void scanMoves(FILE *fp, CubesWidget w, int moves);
extern void printMoves(FILE *fp, CubesStack *s);
extern void scanStartPosition(FILE *fp, CubesWidget w);
extern void printStartPosition(FILE *fp, CubesWidget w);
extern void setStartPosition(CubesWidget w);

#endif /* _CubesP_h */
