/*
 * @(#)PyraminxGLP.h
 *
 * Copyright 2023 - 2024  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 PyraminxGL */

#ifndef _PyraminxGLP_h
#define _PyraminxGLP_h

#include "PyraminxGL.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 _PyraminxGLClassPart {
	int ignore;
} PyraminxGLClassPart;

typedef struct _PyraminxGLClassRec {
	CoreClassPart coreClass;
	PyraminxClassPart pyraminxClass;
	PyraminxGLClassPart pyraminxGLClass;
} PyraminxGLClassRec;

extern PyraminxGLClassRec pyraminxGLClassRec;
#endif

#define MAX_SIZE w->pyraminx.size
#define LAST (w->pyraminx.size-1)
#define FIRST 0
#define SCALE (float) (2.1/MAX_SIZE)

#define TOP_FACE 0
#define RIGHT_FACE 1
#define LEFT_FACE 2
#define BOTTOM_FACE 3

#define BORDER_FACE (MAX_FACES)
#define NO_FACE (MAX_FACES + 1)
#define NO_POSITION (IGNORE_DIR)
#define NO_ROTATION (2*MAX_ORIENT)
#define NO_FE (NO_ROTATION+1) /* 4 faces but 6 edges */
#define NO_DEPTH (IGNORE_DIR)
#define NO_STYLE (IGNORE_DIR)
#define REV(a) (MAX_SIZE-a-1)
#define MAX_TURN_INC 10

#define FACET_LENGTH (float) 0.5
#define SELECT_LENGTH2 (float) 0.5
#define STICKER_LENGTH2 (float) 0.485

#define FACET_TETRA (FACET_LENGTH-(float) 0.02)
#define STICKER_TETRA2 (FACET_TETRA-(float) 0.04)
#define STICKER_TETRA3 (STICKER_TETRA2-(float) 0.04)
#define SELECT_TETRA2 (STICKER_TETRA2-(float) 0.04)
#define SELECT_TETRA3 (STICKER_TETRA3-(float) 0.06)

#define BAR_WIDTH (FACET_LENGTH*(float) 0.05)
#define GAP_WIDTH (FACET_LENGTH*(float) 0.15)
#define GAP_WIDTH2 (FACET_LENGTH*(float) 0.2)

#define FACET_OCTA (FACET_LENGTH*(float) 1.90)
#define STICKER_OCTA2 (FACET_LENGTH*(float) 1.85)
#define SELECT_OCTA2 (FACET_LENGTH*(float) 1.81)

#define STICKER_LONG (FACET_TETRA-(float) 0.05)
#define STICKER_SHORT (STICKER_LONG-(float) 0.05)
#define STICKER_HALF ((STICKER_SHORT)*(float) 0.5)
#define STICKER_DEPTH (FACET_LENGTH+(float) 0.01)
#define SELECT_LONG (float) (4.5*FACET_TETRA/5.0-0.05)
#define SELECT_SHORT (float) (3.5*STICKER_LONG/5.0-0.05)
#define CUT (float) 0.04
#define CUT2 (float) 0.02
#define CUT_DEPTH (STICKER_DEPTH+(float) 0.001)
#define SELECT_DEPTH (STICKER_DEPTH+(float) 0.002)

typedef struct _PyraminxMove {
	int         face, direction;
	int         position;
	int         style;
	Boolean     control;
} PyraminxMove;

typedef struct _PyraminxSlice {
	int         fe, rotation; /* face or edge */
	int         depth;
} PyraminxSlice;

typedef struct _PyraminxGLPart {
	double      angleStep;
	double      rotateStep;
	int         numTurnInc;
	Position    faceDiagonal;
	Position    cubeDiagonalx, cubeDiagonaly, cubeDiagonalz;
	/*Point       cubeSizex, cubeSizey, cubeSizez;*/
	Point       faceSize, viewSize;
	Point       viewMiddle;
	PyraminxMove   movement;
	int         step;
} PyraminxGLPart;

typedef struct _PyraminxGLRec {
	CorePart    core;
	PyraminxPart   pyraminx;
	PyraminxGLPart pyraminxGL;
} PyraminxGLRec;

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

#endif /* _PyraminxGLP_h */
