/* cube.h
 *
 * Pieter Eendebak ( pte@ddsw.nl )
 *
 */

#ifndef CUBE_H
#define CUBE_H

#include <qpntarry.h>

#include "includes.h"
#include "vector.h"


#define BACKGROUND -1
#define EDGE -2
#define FOREGROUND -3

/**
 * This is the class Cube. It's a 3D model of the Rubik's Cube. It
 * allows twising and turning of the model and also provides functions
 * for saving and loading a cube, showing statistics, cleaning and srambling
 * the cube etc.
 *
 * @short 3D Model of the Rubik's Cube
 * @version 0.91
 * @author Pieter Eendebak <pte@ddsw.nl>
 */
class Cube : public QWidget
{
	Q_OBJECT

public:
	/**
	 * The constructor method for class Cube
	 *
	 * @see Cube
	 * @param parent Parent widget, used for QWidget
	 * @param name	Name for QWidget
	 *
	 */
	Cube ( QWidget *parent=0, const char *name=0 );
	
	/**
	 * The destrucor method for class KFortune
	 */
	~Cube();

	/**
	 * @return Returns the number of moves.
	 */
	int getMoves();

	/**
	 * @return Returns the time (in msecs) the cube has been played with
	 */
	int getTime();

	/**
	 * @return Returns the number of wrong pieces in the cube.
	 */
	int scattered();

	const int NO_SHADE = -1 ;

public slots:
	/**
	 * Starts with a new cube.
	 * This means resetting the viewpoint and then calling
	 * @ref #clean
	 *
	 */
	void newCube();

	/**
	 * Cleans the cube.
	 */
	void clean();
	/**
	 * Scrambles the cube.
	 */
	void scramble();

	/**
	 * Used for debugging
	 */
	void dumpData();

	/**
	 * Save the cube to a file
	 */
	void save();
	/**
	 * Load a cube from a file
	 */
	void load();

	/**
	 * Sets the colors from the cube.
	 *
	 * @param color	The color to be set
	 * @param slot The part of the cube of which the color must be set
	 * @param redraw repaints the cube if true
	 */
	void setColor ( QColor color, int slot, bool redraw=TRUE);

	/**
	 * Sets the shading level
	 * 
	 * @param level Use values between 0 and 10, -1 means no shading
	 */
	void setShading( int level );

	/**
	 * @return the current shading level
	 */
	int getShading();
	
	/**
	 * Restore the cube-colors to some default value 
	 *
	 * @param redraw repaints the cube if true
	 */
	void resetColors(bool redraw=TRUE);

	/**
	 * Get's a color item from the color-list.
	 */
	const QColor getColorList( int i );
	/**
	 * ...
	 */
	const QColor getColor( int i );

	/**
	 * @return the current backgroundcolor
	 */
	const QColor getBackgroundColor();

	/**
	 * @return color of the edges of the cube
	 */
	const QColor getEdgeColor();

	/**
 	 * @param n The number of moves to be set.
	 */
	void setMoves(int n);

signals:
	/**
	 * This signal is emitted whenever the state of the cube is changed.
	 * To be more specific :
	 *
	 * <pre>
	 * The singal is emitted when :
	 *
	 * - the number of moves is changed	
	 * - the cube is cleaned or a new cube is created
	 * - the cube is scrambled
	 *
	 * The signal is not emitted when :
	 *
	 * - the time has changed
	 * </pre>
	 */
	void stateChange();	
	
protected:
	/**
	 * Only calls the function resizeEvent()
	 *
	 * @see #resizeEvent
	 */
	void resizeEvent ( QResizeEvent * );
	/**
	 * Handels all the resizing of the main window of KRubik
	 */
	void resizeEvent ();

	/**
	 * Handles a mousePressEvent from the user.
	 */
	void mousePressEvent( QMouseEvent * );
	/**
	 * Handels mouseReleaseEvent.
	 */
	void mouseReleaseEvent( QMouseEvent * );
	/**
	 */
	void mouseMoveEvent( QMouseEvent * );

	/**
	 * Repaints the cube.
	 *
	 */
	void paintEvent ( QPaintEvent *);	

	/**
	 * Used internally to set up some data.
	 */
	void initData();

	/**
	 * Recreate the specified color. Used
	 * by @see #setShading and @see #setColor
	 */
	void createColor( int slot, int red, int green, int blue ) ;

	void redoColors();

	/**
	 * Turns one side of the cube
	 *
	 * @param sideNum Number of the side to turn
	 * @param quads Number of turns
	 * @param redraw repaints the cube if true
	 */
	void colorTwist(int sideNum, int quads, bool redraw=TRUE );

	/**
	 * Splits the cube into 2 parts for twising.
	 * The data for the two sub-cubes are stored in
	 * topBlocks/botBlocks and topCorners/botCorners
	 *
	 */

	void cutUpCube();
	/**
	 * Used by @ref #paintEvent to draw subcubes.
	 */
	void fixBlock(Vector beye, Vector beX, Vector beY,
			Vector **bcorners, const int *bblocks, const int mode);

	
	// The data needed to represent and paint the object :
	// these int't should be moved to appropriate subfunctions...
	int j,n,o,p,q;

	int lastX, lastY, dx, dy;
	// note resizing vor QPointArray is done automatic :-)
	QPointArray rect;
	
	int shading;
	QColor *bgcolor, *edge;
	QColor **colorList;		// colors used for shading
	Vector **sideVec;
	Vector **corners;		// vertex coordinates

	double *dragDir, *dragCorn;	

	// used for drawing/manipulating sub-cubes
	Vector **topCorners, **botCorners;
	
	// every side has 4 corners with a unique number
	int sides[24]={4,5,6,7,  3,2,1,0,  0,1,5,4,   1,2,6,5,
			2,3,7,6,  0,4,7,3 };
	// every side has 4 neighbour sides
	int nextSide[24]={2,3,4,5,  4,3,2,5,  1,3,0,5,  1,4,0,2,
				1,5,0,3,  2,0,4,1};
	// this is forbidden in ANSI C++
	// how to do it else??????
	int mainBlocks[24]={0,3,0,3,  0,3,0,3,  0,3,0,3,  0,3,0,3,
				 0,3,0,3,  0,3,0,3 };

	int twistDir[] = {-1,1,-1,1, -1,1,-1,1, 1,1,1,1, 1,-1,1,-1,
				1,1,1,1, -1,1,-1,1};
	int colDir[]={-1, -1, 1, -1, 1, -1};
	int circleOrder[]={0,1,2,5,8,7,6,3};

	int topBlocks[24], botBlocks[24];
	int *sideCols, sideW, sideH;
	// for the undo-option
	int *sideColsUndo;

	int dragReg, twistSide;
	int nearSide[24], buffer[12];

	// coordinates of viewpoint ( we're using 2 viewpoints
	// to make drawing of sub-cubes easier
	Vector eye, eX, eY;
	Vector Teye, TeX, TeY;

	Vector light, temp, temp2;
	double *newCoord;

	double phi,phibase,Cphi,Sphi;
	double currDragDir[2];

	// state of the cube
	bool naturalstate, twisting, OKtoDrag;


	// other data;
	int hoog, breed;
	int grootte;	// for resizing

	// cube statistics	
	int moves;
	QTime *time;
	bool timestarted;

 	QPixmap *map; 	// to provide buffer...
	QPainter *pt;
	QBrush *br;
	
public slots:

};

#endif

Documentation generated by root@localhost.localdomain on Sat Jun 27 15:21:54 MET DST 1998