#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include "fmod.h"
	
FSOUND_SAMPLE *music = NULL;
const char mp3file[]="ice.mp3";
SDL_Surface *surface;
SDL_Event event;
GLuint texture[10];

int done = 0;
int volume = 255;
int i;
float trans = 2.5;
float 	lolsex = 0.0;
int lolsex2 = 0;
unsigned int tick;
unsigned int frames = 0;

int loadTexture(char *, int n);
int initSDL(void);
int initOGL(void);
int renderScene(void);
int resizeWindow(int height, int width);
void keypress(SDL_keysym *keysym);
void initSound();
void quit(int returnCode);

int main(int argc, char **argv)
{
	printf("Loading... (If you were watching this on a _really_ fast computer you wouldn't be able to read this...)\n");
	initSound();
	printf("Let's kick it!\n--------------\n");
	if (initSDL()) {
		printf("Error when initializing SDL\n");
		return 1;
	}

	if (initOGL()) {
		printf("Error when initialinzing OpenGL\n");
		return 1;
	}

	resizeWindow(640, 480);

	while(!done) {
		while(SDL_PollEvent(&event)) {
			switch(event.type) {
				case SDL_VIDEORESIZE:
					surface = SDL_SetVideoMode(event.resize.w, event.resize.h, 16, SDL_OPENGL);
					if (!surface) {
						printf("Couldn't get a surface after resize\n");
						quit(1);
					}
					resizeWindow(event.resize.w, event.resize.h);
					break;
				case SDL_KEYDOWN:
					keypress(&event.key.keysym);
					break;
				case SDL_QUIT:
					done = 1;
					break;
				default: break;
			}
		}

		renderScene();
	}

	return 0;
}

int loadTexture(char *filename, int n)
{
	SDL_Surface * image;
	if (!(image = IMG_Load(filename)))
	return 1;

	glGenTextures(1, &texture[n]);
	glBindTexture(GL_TEXTURE_2D, texture[n]);
	glTexImage2D(GL_TEXTURE_2D, 0, 3, image->w, image->h, 0, GL_BGR, GL_UNSIGNED_BYTE, image->pixels);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	SDL_FreeSurface(image);

	return 0;
}

int initSDL()
{
	if (SDL_Init(SDL_INIT_VIDEO) != 0) {
		printf("Unable to initialize SDL: %s\n", SDL_GetError());
		return 1;
	}

	surface = SDL_SetVideoMode(640, 480, 16, SDL_OPENGL | SDL_FULLSCREEN | SDL_HWSURFACE);
	if (!surface) {
		printf("Error %s\n", SDL_GetError());
		return 1;
	}

	SDL_WM_SetCaption("Ice Ice baby!", "OGL");

	SDL_ShowCursor(SDL_DISABLE);

	return 0;
}

int initOGL()
{
	/* load textures*/
	if (loadTexture("sorry.png", 8))
		return 1;/**/
	if (loadTexture("greets.png", 9))
		return 1;/**/
	if (loadTexture("music.png", 7))
		return 1;/**/
	if (loadTexture("gfx.png", 6))
		return 1;/**/
	if (loadTexture("code.png", 5))
		return 1;/**/
	if (loadTexture("dance.png", 4))
		return 1;/**/
	if (loadTexture("tagg.png", 2))
		return 1;/**/
	if (loadTexture("kikkit.png", 0))
		return 1;
	if (loadTexture("main_title.png", 1))
		return 1;/**/
	if (loadTexture("intro.png", 3))
		return 1;/**/

	/* enable opengl doublebuffering */
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	/* set color depth to 16 bit 565 */
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 6);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);

	glFogf(GL_FOG_START, 0.0);
	glFogf(GL_FOG_END , 1.0);
	glFogf(GL_FOG_DENSITY, 0.3);

	glEnable(GL_TEXTURE_2D);
	glEnable(GL_SMOOTH);
	glClearColor(0.0, 0.0, 0.0, 0.0);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
	
	return 0;
}

int renderScene()
{
	tick = SDL_GetTicks();
	glClear(GL_COLOR_BUFFER_BIT);
	glLoadIdentity();
	glTranslatef(0.0, 0.0,-2.5);

	glColor3ub(255, 255, 255);

	if (frames == 0)
		FSOUND_PlaySound(FSOUND_FREE, music);
	if (frames < 180) {
		glBindTexture(GL_TEXTURE_2D, texture[3]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 1.0);
			glVertex2f(-1.0,-1.0);
			glTexCoord2f(0.0, 0.0);
			glVertex2f(-1.0, 1.0);
			glTexCoord2f(1.0, 0.0);
			glVertex2f( 1.0, 1.0);
			glTexCoord2f(1.0, 1.0);
			glVertex2f( 1.0,-1.0);
		glEnd();
	}
	else if (frames < 358) {
		glBindTexture(GL_TEXTURE_2D, texture[1]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 1.0);
			glVertex2f(-1.0,-1.0);
			glTexCoord2f(0.0, 0.0);
			glVertex2f(-1.0, 1.0);
			glTexCoord2f(1.0, 0.0);
			glVertex2f( 1.0, 1.0);
			glTexCoord2f(1.0, 1.0);
			glVertex2f( 1.0,-1.0);
		glEnd();
	}
	else if (frames < 518) {
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, .25);
			glVertex2f(-1.0, 0.5);
			glTexCoord2f(0.0, 0.0);
			glVertex2f(-1.0, 1.0);
			glTexCoord2f(1.0, 0.0);
			glVertex2f( 1.0, 1.0);
			glTexCoord2f(1.0, .25);
			glVertex2f( 1.0, 0.5);

			if (frames > 437) {
				glTexCoord2f(0.0, 0.5);
				glVertex2f(-1.0, 0.0);
				glTexCoord2f(0.0, .25);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(1.0, .25);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(1.0, 0.5);
				glVertex2f( 1.0, 0.0);
			}
	
			if (frames > 440) {
				glTexCoord2f(0.0, .75);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.0, 0.5);
				glVertex2f(-1.0, 0.0);
				glTexCoord2f(1.0, 0.5);
				glVertex2f( 1.0, 0.0);
				glTexCoord2f(1.0, .75);
				glVertex2f( 1.0,-0.5);
			}
	
			if (frames > 443) {
				glTexCoord2f(0.0, 1.0);
				glVertex2f(-1.0,-1.0);
					glTexCoord2f(0.0, .75);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(1.0, .75);
				glVertex2f( 1.0,-0.5);
				glTexCoord2f(1.0, 1.0);
				glVertex2f( 1.0,-1.0);
			}
		glEnd();
	}
	else if (frames < 715) {
		glBindTexture(GL_TEXTURE_2D, texture[2]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 0.8);
			glVertex2f(-1.3,-0.7);
			glTexCoord2f(0.0, 0.0);
			glVertex2f(-1.3, 1.0);
			glTexCoord2f(1.0, 0.0);
			glVertex2f( 1.3, 1.0);
			glTexCoord2f(1.0, 0.8);
			glVertex2f( 1.3,-0.7);

			glTexCoord2f(0.0-lolsex, 1.0);
			glVertex2f(-1.3, -1.0);
			glTexCoord2f(0.0-lolsex, 0.8);
			glVertex2f(-1.3, -0.7);
			glTexCoord2f(1.0-lolsex, 0.8);
			glVertex2f( 1.3, -0.7);
			glTexCoord2f(1.0-lolsex, 1.0);
			glVertex2f( 1.3, -1.0);
		glEnd();
		lolsex += 0.03;
	}
	else if (frames < 815) {
		if (frames == 715) {
			trans = 2.5;
			glEnable(GL_FOG);
		}
		glLoadIdentity();
		glTranslatef(0.0, 0.0,-trans);
		glBindTexture(GL_TEXTURE_2D, texture[5]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 1.0);
			glVertex2f(-1.0,-1.0);
			glTexCoord2f(0.0, 0.0);
			glVertex2f(-1.0, 1.0);
			glTexCoord2f(1.0, 0.0);
			glVertex2f( 1.0, 1.0);
			glTexCoord2f(1.0, 1.0);
			glVertex2f( 1.0,-1.0);
		glEnd();
		if (frames > 760)
			trans += 0.3;
	}
	else if (frames < 915) {
		if (frames == 815) {
			trans = 2.5;
		}
		glLoadIdentity();
		glTranslatef(0.0, 0.0,-trans);
		glBindTexture(GL_TEXTURE_2D, texture[6]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 1.0);
			glVertex2f(-1.0,-1.0);
			glTexCoord2f(0.0, 0.0);
			glVertex2f(-1.0, 1.0);
			glTexCoord2f(1.0, 0.0);
			glVertex2f( 1.0, 1.0);
			glTexCoord2f(1.0, 1.0);
			glVertex2f( 1.0,-1.0);
		glEnd();
		if (frames > 860)
			trans += 0.3;
	}
	else if (frames < 1015) {
		if (frames == 915) {
			trans = 2.5;
		}
		glLoadIdentity();
		glTranslatef(0.0, 0.0,-trans);
		glBindTexture(GL_TEXTURE_2D, texture[7]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 1.0);
			glVertex3f(-1.0,-1.0, 0.0);
			glTexCoord2f(0.0, 0.0);
			glVertex3f(-1.0, 1.0, 0.0);
			glTexCoord2f(1.0, 0.0);
			glVertex3f( 1.0, 1.0, 0.0);
			glTexCoord2f(1.0, 1.0);
			glVertex3f( 1.0,-1.0, 0.0);
		glEnd();
		if (frames > 960)
			trans += 0.3;
	}
	else if (frames < 1200) {
		glBindTexture(GL_TEXTURE_2D, texture[4]);

		float fogcolor[] = {0.75, 0.43, 0.9, 0.0};
	
		glFogfv(GL_FOG_COLOR, fogcolor);
		glFogf(GL_FOG_DENSITY, 1.1);
		
		glBegin(GL_QUADS);
			if (lolsex2 < 6) { glTexCoord2f(0.0-lolsex, 0.5); }
			else if (lolsex2 < 12){glTexCoord2f(0.5-lolsex, 0.5);}
			else if (lolsex2 < 18){glTexCoord2f(0.0-lolsex, 1.0);}
			else if (lolsex2 < 24){glTexCoord2f(0.5-lolsex, 0.5);}
			glVertex3f(-1.6,-0.7,-0.3);

			if (lolsex2 < 6) { glTexCoord2f(0.0-lolsex,0.0); }
			else if (lolsex2 < 12){glTexCoord2f(0.5-lolsex,0.0); }
			else if (lolsex2 < 18){glTexCoord2f(0.0-lolsex,0.5); }
			else if (lolsex2 < 24){glTexCoord2f(0.5-lolsex, 0.0);}
			glVertex3f(-1.6, 0.7,-0.3);
	
			if (lolsex2 < 6) { glTexCoord2f(0.5-lolsex, 0.0); }
			else if (lolsex2 < 12){glTexCoord2f(1.0-lolsex, 0.0); }
			else if (lolsex2 < 18){glTexCoord2f(0.5-lolsex, 0.5); }
			else if (lolsex2 < 24){glTexCoord2f(1.0-lolsex, 0.0);}
			glVertex3f( 1.6, 0.7,-0.3);

			if (lolsex2 < 6) { glTexCoord2f(0.5-lolsex, 0.5); }
			else if (lolsex2 < 12){glTexCoord2f(1.0-lolsex, 0.5); }
			else if (lolsex2 < 18){glTexCoord2f(0.5-lolsex, 1.0); }
			else if (lolsex2 < 24){glTexCoord2f(1.0-lolsex, 0.5);}
			glVertex3f( 1.6,-0.7,-0.3);
		glEnd();
		lolsex2++;
		lolsex -= 0.02;
		if (lolsex2 >= 24)
			lolsex2 = 0;
	}
	else if (frames < 1600) {
		float fogcolor[] = {0.0, 0.0, 0.0, 0.0};
		glFogfv(GL_FOG_COLOR, fogcolor);
		glFogf(GL_FOG_DENSITY, 0.3);
		
		glBindTexture(GL_TEXTURE_2D, texture[9]);

		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 0.2);
			glVertex3f(-1.0, 0.6, 0.0);
			glTexCoord2f(0.0, 0.0);
			glVertex3f(-1.0, 1.0, 0.0);
			glTexCoord2f(1.0, 0.0);
			glVertex3f( 1.0, 1.0, 0.0);
			glTexCoord2f(1.0, 0.2);
			glVertex3f( 1.0, 0.6, 0.0);
		glEnd();

		if (frames < 1250) {
			if (frames == 1200) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.0, 0.375);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.0, 0.25);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(0.25, 0.25);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(0.25, 0.375);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1225)
				trans -= 0.6;
			else
				trans += 0.6;
		}
		else if (frames < 1300) {
			if (frames == 1250) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.25, 0.4);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.25, 0.2);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(0.5, 0.2);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(0.5, 0.4);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1275)
				trans -= 0.6;
			else
				trans += 0.6;
		}
		else if (frames < 1350) {
			if (frames == 1300) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.5, 0.4);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.5, 0.2);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(1.0, 0.2);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(1.0, 0.4);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1325)
				trans -= 0.6;
			else
				trans += 0.6;
		}
		else if (frames < 1400) {
			if (frames == 1350) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.0, 0.5);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.0, 0.375);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(0.625, 0.375);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(0.625, 0.5);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1375)
				trans -= 0.6;
			else
				trans += 0.6;
		}
		else if (frames < 1450) {
			if (frames == 1400) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.625, 0.5);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.625, 0.375);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(0.875, 0.375);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(0.875, 0.5);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1425)
				trans -= 0.6;
			else
				trans += 0.6;
		}
		else if (frames < 1500) {
			if (frames == 1450) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.0, 0.625);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.0, 0.5);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(0.625, 0.5);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(0.625, 0.625);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1475)
				trans -= 0.6;
			else
				trans += 0.6;
		}
		else if (frames < 1550) {
			if (frames == 1500) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.0, 0.75);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.0, 0.625);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(0.5, 0.625);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(0.5, 0.75);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1525)
				trans -= 0.6;
			else
				trans += 0.6;
		}
		else {
			if (frames == 1550) {
				trans = 17.5;
			}
			glLoadIdentity();
			glTranslatef(0.0, 0.0,-trans);
			glBegin(GL_QUADS);
				glTexCoord2f(0.5, 0.75);
				glVertex2f(-1.0,-0.5);
				glTexCoord2f(0.5, 0.625);
				glVertex2f(-1.0, 0.5);
				glTexCoord2f(1.0, 0.625);
				glVertex2f( 1.0, 0.5);
				glTexCoord2f(1.0, 0.75);
				glVertex2f( 1.0,-0.5);
			glEnd();
			if (frames < 1575)
				trans -= 0.6;
			else
				trans += 0.6;
		}
	}
	else if (frames < 1915) {
		glBindTexture(GL_TEXTURE_2D, texture[8]);
		glBegin(GL_QUADS);
			glTexCoord2f(0.0, 1.0);
			glVertex3f(-1.0,-1.0, 0.0);
			glTexCoord2f(0.0, 0.0);
			glVertex3f(-1.0, 1.0, 0.0);
			glTexCoord2f(1.0, 0.0);
			glVertex3f( 1.0, 1.0, 0.0);
			glTexCoord2f(1.0, 1.0);
			glVertex3f( 1.0,-1.0, 0.0);
		glEnd();
		if (frames > 1770) {
			trans += 0.3;
			FSOUND_SetVolume(FSOUND_ALL, volume-=2);
		}
	}
	else
		quit(0);

	SDL_GL_SwapBuffers();

	while(SDL_GetTicks() - tick < 33);

	frames++;
	if (frames%100 == 0)
		printf("Frame #%i, still going strong...\n", frames);

	return 0;
}


int resizeWindow(int width, int height)
{       
    GLfloat ratio;
	    
    if (height == 0)
    height = 1;

    ratio = (GLfloat)width / (GLfloat)height;

    glViewport(0, 0, (GLsizei)width, (GLsizei)height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
						    
    gluPerspective(45.0f, ratio, 0.1f, 100.0f);
								    
    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    return 1;
}

void keypress(SDL_keysym *keysym)
{
	switch(keysym->sym) {
	case SDLK_ESCAPE:
		printf("--------------\nMy god, ESC was pressed!!\n");
		quit(0);
		break;
	case SDLK_F1:
		SDL_WM_ToggleFullScreen(surface);
	default:
		break;
	}
}

void initSound()
{
	if (!FSOUND_Init(44100, 64, FSOUND_INIT_GLOBALFOCUS))
		quit(1);
	music = FSOUND_Sample_Load(FSOUND_FREE, mp3file, FSOUND_HW2D | FSOUND_ENABLEFX, 0);
	if (!music) {
		printf("Scaaaaaaaaaaaaat, 0 music :/\n");
		quit(1);
	}
}
void quit(int returnCode)
{
	printf("-------------------------\nCleaning up and quitting.\n");
	FSOUND_Sample_Free(music);
	FSOUND_Close();
	SDL_Quit();
	exit(returnCode);
}

