/*
 * @(#)PanexP.h
 *
 * Copyright 1996 - 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 Panex */

#ifndef _PanexP_h
#define _PanexP_h

#include "xwin.h"
#include "timer.h"
#include "Panex.h"

#ifdef WINVER
extern void destroyPuzzle(HBRUSH brush);
extern void resizePuzzle(PanexWidget w);
extern void sizePuzzle(PanexWidget w);
extern void initializePuzzle(PanexWidget w, HBRUSH brush);
extern void exposePuzzle(PanexWidget w);
extern void hidePuzzle(PanexWidget w);
extern void selectPuzzle(PanexWidget w, const int x);
extern void motionPuzzle(PanexWidget w, const int x);
extern void releasePuzzle(PanexWidget w, const int x);
extern void getPuzzle(PanexWidget w);
extern void writePuzzle(PanexWidget w);
extern void undoPuzzle(PanexWidget w);
extern void redoPuzzle(PanexWidget w);
extern void clearPuzzle(PanexWidget w);
extern void solvePuzzle(PanexWidget w);
extern void modePuzzle(PanexWidget w);
extern void decrementPuzzle(PanexWidget w);
extern void incrementPuzzle(PanexWidget w);
extern void speedUpPuzzle(PanexWidget w);
extern void slowDownPuzzle(PanexWidget w);
extern void toggleSoundPuzzle(PanexWidget w);
extern void enterPuzzle(PanexWidget w);
extern void leavePuzzle(PanexWidget w);

#else

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

typedef struct _PanexClassRec {
	CoreClassPart coreClass;
	PanexClassPart panexClass;
} PanexClassRec;

extern PanexClassRec panexClassRec;
#endif

#ifndef MOVESOUND
#define MOVESOUND "move"
#endif
#ifndef DRIPSOUND
#define DRIPSOUND "drip"
#endif

#define SYMBOL ':'

#define MAX_STACKS 3
#define UP 1
#define DOWN 0

#define TOP 0
#define RIGHT 1
#define BOTTOM 2
#define LEFT 3
#define COORD 4
#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 from, to;
#endif
	unsigned char packed;	/* This makes assumptions on the data. */
} MoveRecord;

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

typedef struct _PanexStack {
	MoveStack *currMove, *lastMove, *firstMove;
	int count;
} PanexStack;

typedef struct _PanexLoc {
	int stack, loc;
} PanexLoc;

typedef struct _PanexPart {
	PanexLoc   *tileOfPosition[MAX_STACKS];
	PanexLoc   *positionOfTile[MAX_STACKS];
	int         currentStack, currentPosition, previousStack;
	Boolean     started, cheat, sound;
	Boolean     mono, reverse, focus;
	Boolean     scoreOnly, versionOnly;
	int         mode, tiles, blanks, stacks;
	int         delay, numSlices;
	Position    width, height;
	Point       tileSize, pos;
	Point       delta, puzzleOffset, letterOffset;
	GC          pyramidGC[MAX_STACKS - 1];
	GC          stackGC, borderGC;
	GC          tileGC[FG_SHADES];
	GC          inverseGC[BG_SHADES];
	Pixmap      bufferTiles[2];
	TimeVal     oldTime;
#ifdef WINVER
	char        userName[81], scoreFile[81], moveSound[81], dripSound[81];
	char        pyramidChar[MAX_STACKS - 1];
#else
	int         menu, pixmapSize;
	char       *userName, *scoreFile, *moveSound, *dripSound, *font;
	Colormap    colormap;
	XFontStruct *fontInfo;
	Pixel       foreground, background;
	Pixel       tileColor, borderColor;
	Pixel       pyramidColor[MAX_STACKS - 1];
	String      pyramidName[MAX_STACKS - 1];
	XtCallbackList select;
#endif
} PanexPart;

typedef struct _PanexRec {
	CorePart    core;
	PanexPart   panex;
} PanexRec;

extern PanexLoc *startLoc[MAX_STACKS - 1];
extern void setPuzzle(PanexWidget w, int reason);
extern int movePuzzle(PanexWidget w, int fromStack, int fromPosition,
	int toStack, int fast);

extern void solveTilesFromStart(PanexWidget w);
extern void drawAllTiles(PanexWidget w);
extern int topOfStack(PanexWidget w, int stack, int start);
extern Boolean checkMiddle(PanexWidget w);
extern Boolean checkSolved(PanexWidget w);
extern void InitMoves(void);
extern void PutMove(int from, int to);
extern void GetMove(int *from, int *to);
extern void newMoves(PanexStack *s);
extern void deleteMoves(PanexStack *s);
extern void setMove(PanexStack *s, int from, int to);
extern void getMove(PanexStack *s, int *from, int *to);
extern int madeMoves(PanexStack *s);
extern void flushMoves(PanexWidget w, PanexStack *s, Boolean undo);
extern int numMoves(PanexStack *s);
extern void scanMoves(FILE *fp, PanexWidget w, int moves);
extern void printMoves(FILE *fp, PanexStack *s);
extern void scanStartPosition(FILE *fp, PanexWidget w);
extern void printStartPosition(FILE *fp, PanexWidget w);
extern void setStartPosition(PanexWidget w);

#endif /* _PanexP_h */
