/*
 * @(#)RubikGLP.h
 *
 * Copyright 2003 - 2013  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 RubikGL */

#ifndef _RubikGLP_h
#define _RubikGLP_h

#include "RubikGL.h"
#include <GL/gl.h>
#include <GL/glu.h>
#ifndef WINVER
#include <GL/glx.h>

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

typedef struct _RubikGLClassRec {
	CoreClassPart coreClass;
	RubikClassPart rubikClass;
	RubikGLClassPart rubikGLClass;
} RubikGLClassRec;

extern RubikGLClassRec rubikGLClassRec;
#endif

#define TR 8
#define BR 9
#define BL 10
#define TL 11
#define SAME 0
#define OPPOSITE 1
#define DOWN 0
#define UP 1
#define COORD3D 12

#define AVSIZE ((w->rubik.sizeX+w->rubik.sizeY+w->rubik.sizeZ)/3.0)     /* Use of this should be minimized */
#define MAX_SIZEX w->rubik.sizeX
#define MAX_SIZEY w->rubik.sizeY
#define MAX_SIZEZ w->rubik.sizeZ
#define MAX_SIZEXY (w->rubik.sizeX*w->rubik.sizeY)
#define MAX_SIZEYZ (w->rubik.sizeY*w->rubik.sizeZ)
#define MAX_SIZEZX (w->rubik.sizeZ*w->rubik.sizeX)
#define LASTX (w->rubik.sizeX-1)
#define LASTY (w->rubik.sizeY-1)
#define LASTZ (w->rubik.sizeZ-1)
#define SCALE (float) (2.1/AVSIZE)
/* These are not likely to change but... */
#define FIRSTX 0
#define FIRSTY 0
#define FIRSTZ 0
#define TOP_FACE 0
#define LEFT_FACE 1
#define FRONT_FACE 2
#define RIGHT_FACE 3
#define BOTTOM_FACE 4
#define BACK_FACE 5
#define BORDER_FACE (MAX_FACES)
#define NO_FACE (MAX_FACES+1)
#define NO_POSITION (IGNORE_DIR)
#define NO_ROTATION (2*MAX_ORIENT)
#define NO_DEPTH (IGNORE_DIR)
#define REVX(a) (MAX_SIZEX-a-1)
#define REVY(a) (MAX_SIZEY-a-1)
#define REVZ(a) (MAX_SIZEZ-a-1)
#define MAX_TURN_INC 10

#define CUBE_LENGTH (float) 0.5
#define CUBE_ROUND (CUBE_LENGTH-(float) 0.05)
#define STICKER_LONG (CUBE_ROUND-(float) 0.05)
#define STICKER_SHORT (STICKER_LONG-(float) 0.05)
#define STICKER_DEPTH (CUBE_LENGTH+(float) 0.01)
#define SELECT_LONG (float) (4.0*CUBE_ROUND/5.0-0.05)
#define SELECT_SHORT (float) (4.0*STICKER_LONG/5.0-0.05)
#define CUT (float) 0.04
#define CUT_DEPTH (STICKER_DEPTH+(float) 0.001)
#define SELECT_DEPTH (STICKER_DEPTH+(float) 0.002)

typedef struct _RubikMove {
	int         face, direction;
	int         position;
} RubikMove;

typedef struct _RubikSlice {
	int         face, rotation;
	int         depth;
} RubikSlice;

typedef struct _RubikGLPart {
	double      angleStepX, angleStepY, angleStepZ, rotateStep;
	int         numTurnInc;
	/*Point       cubeSizeX, cubeSizeY, cubeSizeZ;*/
	RubikMove   movement;
	int         step;
} RubikGLPart;

typedef struct _RubikGLRec {
	CorePart    core;
	RubikPart   rubik;
	RubikGLPart rubikGL;
} RubikGLRec;

extern Boolean selectPiecesGL(RubikGLWidget w, int x, int y,
	int *face, int *position);
extern Boolean narrowSelectionGL(RubikGLWidget w,
	int *face, int *position, int *direction);
/*extern void drawFrameGL(RubikGLWidget w, Boolean focus);*/
extern void drawAllPiecesGL(RubikGLWidget w);
extern void movePiecesGL(RubikGLWidget w, int face, int position,
	int direction, Boolean control, int fast);
#ifdef WINVER
extern void resizePuzzleGL(RubikGLWidget w);
extern void exposePuzzleGL(RubikGLWidget w);
#endif

#endif /* _RubikGLP_h */
