#include <iostream>
#include <stdlib.h>
#include "windows.h"
#include <GL/glut.h>
#include <assert.h>
#include <fstream>
#include <math.h>

using namespace std;

const float BOX_SIZE = 2.0f; //The length of each side of the cube
float angle = 0;            //The rotation of the box
//GLuint _textureId;         //The OpenGL id of the texture, single texture
GLuint texture[6];         //Store 6 images for cube

bool rotate = false;
float alpha = 0.0f;
float radius = 15.0f;

void draw_scene();

//Represents an image
class Image {
	public:
		Image(char* ps, int w, int h);
		~Image();

		/* An array of the form (R1, G1, B1, R2, G2, B2, ...) indicating the
		 * color of each pixel in image.  Color components range from 0 to 255.
		 * The array starts the bottom-left pixel, then moves right to the end
		 * of the row, then moves up to the next column, and so on.  This is the
		 * format in which OpenGL likes images.
		 */
		char* pixels;
		int width;
		int height;
};



Image::Image(char* ps, int w, int h) : pixels(ps), width(w), height(h) {

}

Image::~Image() {
	delete[] pixels;
}

namespace {
	//Converts a four-character array to an integer, using little-endian form
	int toInt(const char* bytes) {
		return (int)(((unsigned char)bytes[3] << 24) |
					 ((unsigned char)bytes[2] << 16) |
					 ((unsigned char)bytes[1] << 8) |
					 (unsigned char)bytes[0]);
	}

	//Converts a two-character array to a short, using little-endian form
	short toShort(const char* bytes) {
		return (short)(((unsigned char)bytes[1] << 8) |
					   (unsigned char)bytes[0]);
	}

	//Reads the next four bytes as an integer, using little-endian form
	int readInt(ifstream &input) {
		char buffer[4];
		input.read(buffer, 4);
		return toInt(buffer);
	}

	//Reads the next two bytes as a short, using little-endian form
	short readShort(ifstream &input) {
		char buffer[2];
		input.read(buffer, 2);
		return toShort(buffer);
	}

	//Just like auto_ptr, but for arrays
	template<class T>
	class auto_array {
		private:
			T* array;
			mutable bool isReleased;
		public:
			explicit auto_array(T* array_ = NULL) :
				array(array_), isReleased(false) {
			}

			auto_array(const auto_array<T> &aarray) {
				array = aarray.array;
				isReleased = aarray.isReleased;
				aarray.isReleased = true;
			}

			~auto_array() {
				if (!isReleased && array != NULL) {
					delete[] array;
				}
			}

			T* get() const {
				return array;
			}

			T &operator*() const {
				return *array;
			}

			void operator=(const auto_array<T> &aarray) {
				if (!isReleased && array != NULL) {
					delete[] array;
				}
				array = aarray.array;
				isReleased = aarray.isReleased;
				aarray.isReleased = true;
			}

			T* operator->() const {
				return array;
			}

			T* release() {
				isReleased = true;
				return array;
			}

			void reset(T* array_ = NULL) {
				if (!isReleased && array != NULL) {
					delete[] array;
				}
				array = array_;
			}

			T* operator+(int i) {
				return array + i;
			}

			T &operator[](int i) {
				return array[i];
			}
	};
}

Image* loadBMP(const char* filename) {
	ifstream input;
	input.open(filename, ifstream::binary);
	printf(filename);
	assert(!input.fail() || !"Could not find file");
	char buffer[2];
	input.read(buffer, 2);
	assert(buffer[0] == 'B' && buffer[1] == 'M' || !"Not a bitmap file");
	input.ignore(8);
	int dataOffset = readInt(input);

	//Read the header
	int headerSize = readInt(input);
	int width;
	int height;


	switch(headerSize) {
		case 40:
			//V3
			width = readInt(input);
			height = readInt(input);
			input.ignore(2);
			assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");
			assert(readShort(input) == 0 || !"Image is compressed");
			break;
		case 12:
			//OS/2 V1
			width = readShort(input);
			height = readShort(input);
			input.ignore(2);
			assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");
			break;
		case 64:
			//OS/2 V2
			assert(!"Can't load OS/2 V2 bitmaps");
			break;
		case 108:
			//Windows V4
			assert(!"Can't load Windows V4 bitmaps");
			break;
		case 124:
			//Windows V5
			assert(!"Can't load Windows V5 bitmaps");
			break;
		default:
			assert(!"Unknown bitmap format");
	}


	//width = readInt(input);
//height = readInt(input);

	//Read the data
	int bytesPerRow = ((width * 3 + 3) / 4) * 4 - (width * 3 % 4);
	int size = bytesPerRow * height;
	auto_array<char> pixels(new char[size]);
	input.seekg(dataOffset, ios_base::beg);
	input.read(pixels.get(), size);

	//Get the data into the right format
	auto_array<char> pixels2(new char[width * height * 3]);
	for(int y = 0; y < height; y++) {
		for(int x = 0; x < width; x++) {
			for(int c = 0; c < 3; c++) {
				pixels2[3 * (width * y + x) + c] =
					pixels[bytesPerRow * y + 3 * x + (2 - c)];
			}
		}
	}

	input.close();
	return new Image(pixels2.release(), width, height);
}


void handleKeypress(unsigned char key, int x, int y)
  {

    if(key == 27)  // ESC key
       {
		  exit(0);
	   }

	if(key == 's')
	  {
	      rotate = false;
          draw_scene();
	  }

	if(key == 'r')
	  {
          rotate = true;
          draw_scene();
      }

  }



//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image)
 {
	GLuint textureId;
	glGenTextures(1, &textureId);
	glBindTexture(GL_TEXTURE_2D, textureId);
	glTexImage2D(GL_TEXTURE_2D,
				 0,
				 GL_RGB,
				 image->width, image->height,
				 0,
				 GL_RGB,
				 GL_UNSIGNED_BYTE,
				 image->pixels);
	return textureId;
 }

void initRendering()
 {
	glEnable(GL_DEPTH_TEST);
//	glEnable(GL_LIGHTING);
//	glEnable(GL_LIGHT0);
	glEnable(GL_NORMALIZE);
	glEnable(GL_COLOR_MATERIAL);
	glEnable(GL_TEXTURE_2D);

	Image* image0 = loadBMP("blue.bmp");
	Image* image1 = loadBMP("yellow.bmp");
	Image* image2 = loadBMP("green.bmp");
	Image* image3 = loadBMP("orange.bmp");
	Image* image4 = loadBMP("white.bmp");
	Image* image5 = loadBMP("red.bmp");

	texture[0] = loadTexture(image0);
	texture[1] = loadTexture(image1);
	texture[2] = loadTexture(image2);
	texture[3] = loadTexture(image3);
	texture[4] = loadTexture(image4);
	texture[5] = loadTexture(image5);

	delete image0;
	delete image1;
	delete image2;
	delete image3;
	delete image4;
	delete image5;

 }

void handleResize(int w, int h)
 {
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);
 }

void draw_scene()
 {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

        alpha += 0.05;
        if(alpha > 360.0) alpha = 0.0;


    double x = 2.0 * cos(radius);
    double y = 2.0 * cos(radius);
    double deltaX = x * cos(alpha) - x * sin(alpha);
    double deltaY = y * cos(alpha) + y * sin(alpha);


	GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

	GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
	GLfloat lightPos[] = {-2 * BOX_SIZE, BOX_SIZE, 4 * BOX_SIZE, 1.0f};
	glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
	glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

	glTranslatef(deltaX, deltaY, -15.0f);

    if(rotate == false)
       {
	       glRotatef(30.0, 1.0, 0.0, 0.0);
	       glRotatef(60.0, 0.0, 1.0, 0.0);
       }

	if(rotate == true) glRotatef(-angle, 1.0f, 1.0f, 0.0f);


	//Top face  //white
	glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture[4]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, 1.0, -0.333);
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.333, 1.0, -0.333);  // right top
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.333, 1.0, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.00 , 1.0, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, 1.0, -0.3333);    // middle top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, 1.0, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, 1.0, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, 1.0, -0.3333);    // left top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, 1.0, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 1.0, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, 1.0, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, 1.0, 0.3333);    // left middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, 1.0, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 1.0, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, 1.0, -0.3333);    // middle center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, 1.0, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, 1.0, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, 1.0, 0.3333);    // right center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, 1.0, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 1.0, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, 1.0, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, 1.0, 1.0);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, 1.0, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 1.0, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, 1.0, 1.0);    // bottom center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, 1.0, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, 1.0, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, 1.0, 1.0);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, 1.0, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 1.0, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, 1.0, 0.3333);
    glEnd();

/////////////////////////////////////////////

	//Bottom face  //yellow
	glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture[1]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -1.0, 0.333);
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.333, -1.0, 0.333);  // right top
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.333, -1.0, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.00 , -1.0, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, 0.3333);    // middle top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, -1.0, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, -1.0, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, -1.0, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, -1.0, 0.3333);    // left top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -1.0, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, -1.0, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, -1.0, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -1.0, -0.3333);    // left middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, -1.0, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, -1.0, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, 0.3333);    // middle center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, -1.0, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, -1.0, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, -1.0, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, -1.0, -0.3333);    // right center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -1.0, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, -1.0, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, -1.0, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -1.0, -1.0);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, -1.0, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, -1.0, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, -1.0);    // bottom center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, -1.0, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, -1.0,-0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, -1.0, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, -1.0, -1.0);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -1.0, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, -1.0, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, -1.0, -0.3333);
    glEnd();

////////////////////////////////////////

	//Left face  //red
	glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture[5]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, 0.333, -1.0);
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, 0.333, -0.3333);  // right top
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 1.0, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.00 , 1.0, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, 0.3333, -0.3333);    // right middle top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, 0.3333, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 1.0, 0.333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 1.0, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, 0.3333, 0.3333);    // right top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, 0.3333, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 1.0, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 1.0, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, -1.0);    // left middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, -0.3333);    // right middle center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, 0.3333);    // right middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -1.0, -1.0);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -1.0, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -1.0, -0.3333);    // right bottom center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -1.0, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -1.0, 0.3333);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -1.0, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, 0.3333);
    glEnd();

////////////////////////////////////////

	//Right face  //orange
	glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture[3]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, 0.333, 1.0);
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, 0.333, 0.3333);  // right top
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 1.0, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.00 , 1.0, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, 0.3333, 0.3333);    // right middle top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, 0.3333, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 1.0, -0.333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, 1.0, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, 0.3333, -0.3333);    // right top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, 0.3333, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 1.0, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, 1.0, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -0.3333, 1.0);    // left middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -0.3333, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 0.3333, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, 0.3333, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -0.3333, 0.3333);    // right middle center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -0.3333, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 0.3333, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, 0.3333, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -0.3333, -0.3333);    // right middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -0.3333, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, 0.3333, -0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -1.0, 1.0);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -1.0, 0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, -0.3333, 0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, -0.3333, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -1.0, 0.3333);    // right bottom center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -1.0, -0.3333);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, -0.3333, -0.3333);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, -0.3333, 0.3333);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -1.0, -0.3333);    // right bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -1.0, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, -0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, -0.3333, -0.3333);
    glEnd();

//////////////////////////////

	//Front face  //blue
	glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture[0]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, 0.333, 1.0);
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.333, 0.333, 1.0);  // right front top
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.333, 1.0, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.00 , 1.0, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, 0.3333, 1.0);    // middle front top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, 0.3333, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, 1.0, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, 0.3333, 1.0);    // right front top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, 0.3333, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 1.0, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, 1.0, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, 1.0);    // left front middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, -0.3333, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, 0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, -0.3333, 1.0);    // left front middle center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, -0.3333, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, 0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, 0.3333, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, -0.3333, 1.0);    // right front center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -0.3333, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, 0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, 0.3333, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-1.0, -1.0, 1.0);    // right front bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, -0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, 1.0);    // right front bottom center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, -1.0, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, -0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, -0.3333, 1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, -1.0, 1.0);    // right front bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(1.0, -1.0, 1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(1.0, -0.3333, 1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, -0.3333, 1.0);
    glEnd();

///////////////////////////////////////////////

	//Back face  //green
	glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture[2]);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glColor3f(1.0f, 1.0f, 1.0f);
	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, 0.333, -1.0);
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.333, 0.333, -1.0);  // right back top
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.333, 1.0, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.00 , 1.0, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, 0.3333, -1.0);    // middle back top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, 0.3333, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, 1.0, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, 0.3333, -1.0);    // right back top
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, 0.3333, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 1.0, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, 1.0, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -0.3333, -1.0);    // left back middle
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, -0.3333, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, 0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, 0.3333, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, -0.3333, -1.0);    // left back middle center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, -0.3333, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, 0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, 0.3333, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, -0.3333, -1.0);    // right back center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -0.3333, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, 0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, 0.3333, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(1.0, -1.0, -1.0);    // right back bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(0.3333, -1.0, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(0.3333, -0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(1.0, -0.3333, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(0.3333, -1.0, -1.0);    // right back bottom center
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-0.3333, -0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(0.3333, -0.3333, -1.0);
    glEnd();

	glBegin(GL_QUADS);
	glNormal3f(0.0, 0.0f, 1.0f);
	glTexCoord2f(0.0f, 0.0f);
	glVertex3f(-0.3333, -1.0, -1.0);    // right back bottom
	glTexCoord2f(1.0f, 0.0f);
	glVertex3f(-1.0, -1.0, -1.0);
	glTexCoord2f(1.0f, 1.0f);
	glVertex3f(-1.0, -0.3333, -1.0);
	glTexCoord2f(0.0f, 1.0f);
	glVertex3f(-0.3333, -0.3333, -1.0);
    glEnd();

	glutSwapBuffers();
 }


//Called every 25 milliseconds
void update(int value)
  {
	angle += 1.0f;
	if (angle > 360)
      {
	     angle -= 360;
	  }
	glutPostRedisplay();
	glutTimerFunc(25, update, 0);
 }

int main(int argc, char** argv)
 {
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(1280, 800);

	glutCreateWindow("Rubik's Cube");
	initRendering();

	glutDisplayFunc(draw_scene);
	glutKeyboardFunc(handleKeypress);
	glutReshapeFunc(handleResize);
	glutTimerFunc(25, update, 0);

	glutMainLoop();
	return 0;
 }
