/*
 * liveGL - Live Broadcast Video Interface
 * Copyright (C) 2006 - Benjamin GIGON <benjamin#gigon.org>
 * 
 * First implementation for live broadcast video
 *   - Only MPEG reader  :-\
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <SDL.h>
#include <smpeg/smpeg.h>

#include <stdio.h>
#include <stdlib.h>


#define SCREEN_X 800
#define SCREEN_Y 600

int camera_rotation_x = 0;


int main(int argc, char *argv[])
{
	// Only for glut*
	glutInit(&argc, argv);
	
	// Init SDL
    SDL_Init(SDL_INIT_VIDEO);
	SDL_SetVideoMode( SCREEN_X, SCREEN_Y, 0, SDL_OPENGL|SDL_RESIZABLE);
	SDL_WM_SetCaption("LiveGL", NULL);
	
	// Init GL
	glEnable( GL_TEXTURE_2D );
	glEnable(GL_DEPTH_TEST);

	/* Perspective */
    glViewport( 0, 0, SCREEN_X, SCREEN_Y );
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
	gluPerspective(45, SCREEN_X/SCREEN_Y, 1, 1000);

    
	// Load Textures/MPEG
    GLuint texture; 
	SMPEG *mpeg;
	SMPEG_Info mpeg_info;
   	mpeg = SMPEG_new("video.mpeg", &mpeg_info, false);
	if(!mpeg) printf("Unable to read video.mpeg");
	
    SDL_Surface *surface = SDL_CreateRGBSurface( SDL_SWSURFACE,
                mpeg_info.width,
                mpeg_info.height,
                32,
                0x000000FF,
                0x0000FF00,
                0x00FF0000,
                0xFF000000 );
	
	if(!surface) printf("Surface not set\n");
	else		 printf("Video[%dx%d,%.2f] Surface:[%dx%d,%d]\n", 
							mpeg_info.width, mpeg_info.height, mpeg_info.total_time,
							surface->w, surface->h, surface->format->BytesPerPixel);
	
	
	SMPEG_setdisplay(mpeg, surface, NULL, NULL);
	SMPEG_enablevideo(mpeg, 1);
	SMPEG_enableaudio(mpeg, 0);
	glGenTextures( 1, &texture );
	glBindTexture( GL_TEXTURE_2D, texture );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, surface->w, surface->h, 0, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels );


	// Keyboard/Mouse/..  Events
	SDL_Event event;
	

	bool playing = true;
	while(playing == true) {
		glMatrixMode( GL_MODELVIEW );
		glLoadIdentity();
		glTranslatef(-100, 0, -800);
		glRotated (0, 1, 0, 0);
		glRotated (camera_rotation_x, 0, 1, 0);
		glRotated (0, 0, 0, 1);

		
		glClearColor( 0.0, 0.0, 0.0, 0.0 );
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );


		SMPEG_loop(mpeg, 1);
		SMPEG_play(mpeg);

		switch(SMPEG_status( mpeg )) {
			case SMPEG_STOPPED:
				//playing = false;
				break;
			case SMPEG_PLAYING:
				break;
			case SMPEG_ERROR:
				break;
		}

		
		// display cube
		glPushMatrix();
			glTranslatef(-10, 0, -100);
			glutSolidCube(100);	
		glPopMatrix();


		
		// display video
		glPushMatrix();
			glTranslatef(0, 0, 0);
			glColor4f(1, 1, 1, 0);
			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);
   			glBindTexture( GL_TEXTURE_2D, texture );
	    	glBegin( GL_QUADS );
				glTexCoord2f( 0, 1 );
   	     		glVertex3f( 0, 0, 0 );
				glTexCoord2f( 1, 1 );
   	     		glVertex3f( surface->w, 0, 0 );
				glTexCoord2f( 1, 0 );
   	     		glVertex3f( surface->w, surface->h, 0 );
				glTexCoord2f( 0, 0 );
   	     		glVertex3f( 0, surface->h, 0 );
    		glEnd();
		glPopMatrix();


		// display repere
		glPushMatrix();
			glTranslatef(0, 0, 0);
			// rouge +x
			glColor3f(1, 0, 0);
			glBegin(GL_POLYGON);
				glVertex3f( 0, 0, 0);
				glVertex3f( 5, 0, 0);
				glVertex3f( 5, 5, 0);
				glVertex3f( 0, 5, 0);
			glEnd();
			// vert -x
			glColor3f(0, 1, 0);
			glBegin(GL_POLYGON);
				glVertex3f( 0, 0, 0);
				glVertex3f( -5, 0, 0);
				glVertex3f( -5, 5, 0);
				glVertex3f( 0, 5, 0);
			glEnd();
		glPopMatrix();
		

    	SDL_GL_SwapBuffers();


		// Keyboard
		while ( SDL_PollEvent( &event ) == 1 )
		{
			if( event.type == SDL_KEYDOWN )
			{
				if(event.key.keysym.sym == SDLK_ESCAPE) {
					printf("Cleanup...\n");
					SMPEG_delete(mpeg);
    				glDeleteTextures( 1, &texture );
					SDL_FreeSurface(surface);
    				SDL_Quit();
					exit(0);
				}
				if(event.key.keysym.sym == SDLK_LEFT)
					camera_rotation_x+=10;
				if(event.key.keysym.sym == SDLK_RIGHT)
					camera_rotation_x-=10;
				if(event.key.keysym.sym == SDLK_a)
					SMPEG_rewind( mpeg );
			}
		}


	}
    
	return 0;
}
