#define PI    3.14159265358979
#define SQ2   1.4142135623731
#define SQ3   1.73205080756888
#define SQ2I  (SQ2 * 0.5)
#define SQ3I  (1 / SQ3)

#define CUBESIZE 3.0
#define CUBESIZE2 1.5
#define CUBLE 1.0
#define CUBLE2 0.5

#define CUBEMAX (CUBESIZE * SQ3)
#define CUBEMAX2 (CUBEMAX * 0.5)
#define CUBEWIN (CUBEMAX * 1.2)

#define TRUNCATE (0.08 * CUBLE)
#define STICKER (CUBLE - 2 * TRUNCATE)
#define STICKER2 (STICKER * 0.5)
#define BEVELW  (SQ2 * TRUNCATE)
#define BEVELW2 (BEVELW * 0.5)
#define BEVELZ  (SQ2 * CUBESIZE2 - BEVELW2)

#define CORNER1 (BEVELW2 * SQ3I)
#define CORNER2 (BEVELW * SQ3I)

#define BSHINE 10
#define SSHINE 100
#define SELSHINE 50

class Cube {
  public:
    Cube();

    void reset();
    void scramble();

    void twist(bool ccw, int face);
    int front_face();
    int front_face(int);

    void render();

    float twist_deg;
    int twistface;
  private:
    void get3adj(int, int, int*);
    void set3adj(int, int, int*);

    int face[6][3][3]; // each face has 9 stickers
    // each sticker belongs to a face, that is it can take a value
    // from 0 to 5, if for all i, j, k, face[i][j][k] == i then
    // the cube is solved!
    int twisted[6][3][3]; // how much rotated a sticker is

    int textures[6]; // one texture for each face

    static float sticker_spec[4];
    static float bevel_spec[4];
};

extern Cube cube;
