// *************************************************************************************************
//
// Horde3D
//   Next-Generation Graphics Engine
//
// Sample Application
// ---------------------------------
// Copyright (C) 2006 Nicolas Schulz
//
//
// This sample source file is not covered by the LGPL as the rest of the SDK
// and may be used without any restrictions
//
// *************************************************************************************************

// This sample uses the SDL for cross-platform window setup and input handling

#include <iostream>
#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include "app.h"


// Configuration
const char *caption = "Knight - Horde3D Sample";
const int appWidth = 800;
const int appHeight = 600;
const bool fullScreen = false;


int main( int argc, char *argv[] )
{
	int mx, my, desktopWidth, desktopHeight;
	
	// Initialize SDL
	if( SDL_Init( SDL_INIT_VIDEO ) != 0 )
	{
		std::cout << "Unable to initialize SDL: " << SDL_GetError();
		SDL_Delay( 3000 );
		return -1;
	}

	desktopWidth = SDL_GetVideoInfo()->current_w;
	desktopHeight = SDL_GetVideoInfo()->current_h;

	SDL_WM_SetCaption( caption, 0x0 );

	SDL_GL_SetAttribute( SDL_GL_ACCELERATED_VISUAL, 1 );
	SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
	SDL_GL_SetAttribute( SDL_GL_BUFFER_SIZE, 32 );
	SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 24 );
	SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
	SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 );
	
	if ( !SDL_SetVideoMode( appWidth, appHeight, 32, SDL_OPENGL |
							(fullScreen ? SDL_FULLSCREEN : 0x00000000 ) ) )
	{
		std::cout << "Unable to set video mode: " << SDL_GetError();
		SDL_Delay( 3000 );
		SDL_Quit();
		return -1;
	}
	
	// Initalize engine and application
	Application *app = new Application();
	if( !app->init() )
	{
		// Fake message box
		SDL_SetVideoMode( 800, 16, 32, 0 );
		SDL_WM_SetCaption( "Unable to initalize engine - Make sure you have an OpenGL 2.0 compatible graphics card", 0x0 );
		
		std::cout << "Unable to initalize engine" << std::endl;
		std::cout << "Make sure you have an OpenGL 2.0 compatible graphics card";
		SDL_Delay( 4000 );
		SDL_Quit();
		return -1;
	}
	app->resize( appWidth, appHeight );

	SDL_ShowCursor( SDL_DISABLE );
	SDL_WarpMouse( 100, 100 );
	
	unsigned int numFrames = 0, startTick = SDL_GetTicks();
	float fps = 30.0f;
	bool running = true, active = true;
	
	// Game loop
	while( running )
	{
		// Handle events
		SDL_Event e;
		while( SDL_PollEvent( &e ) )
		{
			if( e.type == SDL_KEYDOWN )
			{
				if( e.key.keysym.sym == SDLK_ESCAPE )
				{
					running = false;
				}
				else if( e.key.keysym.sym == SDLK_F1 )
				{
					app->release();
					SDL_SetVideoMode( desktopWidth, desktopHeight, 32, SDL_OPENGL | SDL_FULLSCREEN );
					app->init();
					app->resize( desktopWidth, desktopHeight );
					SDL_WarpMouse( 100, 100 );
					startTick = SDL_GetTicks();
				}
				else
				{
					app->keyPressEvent( e.key.keysym.sym );
				}
			}
			else if( e.type == SDL_QUIT )
			{
				running = false;
			}
			else if( e.type == SDL_ACTIVEEVENT )
			{
				if( e.active.state & SDL_APPINPUTFOCUS || e.active.state & SDL_APPACTIVE )
				{
					if( e.active.gain == 0 )
					{	
						active = false;
					}
					else
					{	
						active = true;
						SDL_WarpMouse( 100, 100 );
						startTick = SDL_GetTicks();
					}
				}
			}
		}

		// Pause app if inactive
		if( !active ) continue;

		// Calc FPS
		++numFrames;
		if( numFrames >= 3 )
		{
			unsigned int tick = SDL_GetTicks();
			fps = numFrames / ((tick - startTick) / 1000.0f);
			numFrames = 0;
			startTick = tick;
		}

		// Handle mouse input
		SDL_GetMouseState( &mx, &my );
		SDL_WarpMouse( 100, 100 );
		app->mouseMoveEvent( mx - 100.0f, 100.0f - my );
		
		// Handle keyboard input
		Uint8 *keystate = SDL_GetKeyState( 0x0 );
		for( int i = 0; i < 255; ++i )
		{
			app->keyStateChange( i, keystate[i] != 0 );
		}

		// Render
		app->mainLoop( fps );
		SDL_GL_SwapBuffers();
	}

	// Quit
	app->release();
	delete app; app = 0x0;
	SDL_Quit();
	
	return 0;
}
