#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>

#include <SDL.h>
#include <SDL/SDL_image.h>
#define NO_SDL_GLEXT
#include <SDL/SDL_opengl.h>

/* screen width, height, and bit depth */
#define SCREEN_WIDTH  512
#define SCREEN_HEIGHT 512
#define SCREEN_BPP     16

void mainLoop()
{
    int done = 0;
    SDL_Event event; /* used to collect events */

    /* wait for events */
    while ( !done )
    {
        /* handle the events in the queue */
        while ( SDL_PollEvent( &event ) )
        {
            switch( event.type )
            {
                case SDL_KEYDOWN:
                    done = 1;
                    break;

                case SDL_MOUSEBUTTONDOWN:
                    break;
                case SDL_MOUSEBUTTONUP:
                    break;
                case SDL_MOUSEMOTION:
                        //event.button.x
                        //event.button.y
                        //event.button.button
                    break;

                case SDL_QUIT:

                default:
                    break;
            }
        }
        drawGLScene( );
    }
}

/* general OpenGL initialization function */
int initGL( GLvoid )
{
    /* Enable Texture Mapping */
    glEnable( GL_TEXTURE_2D );

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    /* Enable smooth shading */
    glShadeModel( GL_SMOOTH );

    /* Set the background black */
    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );

    /* Depth buffer setup */
    glClearDepth( 1.0f );

    /* Enables Depth Testing */
    glEnable( GL_DEPTH_TEST );

    /* The Type Of Depth Test To Do */
    glDepthFunc( GL_LEQUAL );

    /* Really Nice Perspective Calculations */
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );

    glViewport( 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );
    gluPerspective( 45.0f, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 100.0f );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );

    return 1;
}

/* Here goes our drawing code */
int drawGLScene( GLvoid )
{
    static GLfloat yrot=0, xrot=0, z=-5;
    /* Clear The Screen And The Depth Buffer */
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glLoadIdentity( );

    /* Draw it to the screen */
    SDL_GL_SwapBuffers( );

    return 1;
}

int main( int argc, char **argv )
{
    SDL_Surface *surface; /* This is our SDL surface */
    int videoFlags; /* Flags to pass to SDL_SetVideoMode */
    const SDL_VideoInfo *videoInfo;/* this holds some info about our display */

    /* initialize SDL */
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        fprintf( stderr, "Video initialization failed: %s\n",SDL_GetError( ) );
        exit(1);
    }

    /* Fetch the video info */
    videoInfo = SDL_GetVideoInfo( );
    if ( !videoInfo )
    {
        fprintf( stderr, "Video query failed: %s\n",SDL_GetError( ) );
        exit(1);
    }

    /* the flags to pass to SDL_SetVideoMode */
    videoFlags  = SDL_OPENGL;          /* Enable OpenGL in SDL */
    videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
    videoFlags |= SDL_HWPALETTE;       /* Store the palette in hardware */
    if ( videoInfo->hw_available )
        videoFlags |= SDL_HWSURFACE;
    else
        videoFlags |= SDL_SWSURFACE;
    if ( videoInfo->blit_hw )
        videoFlags |= SDL_HWACCEL;

    /* Sets up OpenGL double buffering */
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

    /* get a SDL surface */
    surface = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
                                videoFlags );
    if ( !surface )
    {
        fprintf( stderr,  "Video mode set failed: %s\n", SDL_GetError( ) );
        exit(1);
    }

    /* initialize OpenGL */
    initGL( );

    mainLoop();

    /* clean up the window */
    SDL_Quit( );

    exit( EXIT_SUCCESS );
}
