/********************
*                   *
*   NeHeGL Header   *
*                   *
**********************************************************************************
*                                                                                *
*	You Need To Provide The Following Functions:                                 *
*                                                                                *
*	BOOL Initialize (GL_Window* window, Keys* keys);                             *
*		Performs All Your Initialization                                         *
*		Returns TRUE If Initialization Was Successful, FALSE If Not              *
*		'window' Is A Parameter Used In Calls To NeHeGL                          *
*		'keys' Is A Structure Containing The Up/Down Status Of keys              *
*                                                                                *
*	void Deinitialize (void);                                                    *
*		Performs All Your DeInitialization                                       *
*                                                                                *
*	void Update (DWORD milliseconds);                                            *
*		Perform Motion Updates                                                   *
*		'milliseconds' Is The Number Of Milliseconds Passed Since The Last Call  *
*		With Whatever Accuracy GetTickCount() Provides                           *
*                                                                                *
*	void Draw (void);                                                            *
*		Perform All Your Scene Drawing                                           *
*                                                                                *
*********************************************************************************/

#ifndef GL_FRAMEWORK__INCLUDED
#define GL_FRAMEWORK__INCLUDED

#include <windows.h>								// Header File For Windows

typedef struct {									// Structure For Keyboard Stuff
	BOOL keyDown [256];								// Holds TRUE / FALSE For Each Key
} Keys;												// Keys

typedef struct {									// Contains Information Vital To Applications
	HINSTANCE		hInstance;						// Application Instance
	const char*		className;						// Application ClassName
} Application;										// Application

typedef struct {									// Window Creation Info
	Application*		application;				// Application Structure
	char*				title;						// Window Title
	int					width;						// Width
	int					height;						// Height
	int					bitsPerPixel;				// Bits Per Pixel
	BOOL				isFullScreen;				// FullScreen?
} GL_WindowInit;									// GL_WindowInit

typedef struct {									// Contains Information Vital To A Window
	Keys*				keys;						// Key Structure
	HWND				hWnd;						// Window Handle
	HDC					hDC;						// Device Context
	HGLRC				hRC;						// Rendering Context
	GL_WindowInit		init;						// Window Init
	BOOL				isVisible;					// Window Visible?
	DWORD				lastTickCount;				// Tick Counter
} GL_Window;										// GL_Window

#define  M_PI  (3.14159265358979323846)
#define  M_2PI (6.28318530717958647692)
#define  M_PIH (1.57079632679489661923)
#define  M_3PIH (4.71238898038468985769)
#define  M_5PIH (7.85398163397448309615)
#define  M_7PIH (10.99557428756427633461)
#define  M_7PIV (5.497787143782138167305)
#define  M_5PIV (3.926990816987241548075)
#define  M_3PIV (2.356194490192344928845)
#define  M_PIV (0.785398163397448309625)
#define  M_SQRT2 (1.4142135623730950488016887242097)
#define  M_1SQRT2 (0.70710678118654752440084436210485)

#define chkfloat(p) { if ((p > -1e-10) && (p < 1e-10)) p = 0.0; else if ((p > 0.999999999) && (p < 1.000000001)) p = 1.0; else if ((p > -0.999999999) && (p < -1.000000001)) p = -1.0; else if ((p > 0.499999999) && (p < 0.500000001)) p = 0.5;else if ((p > -0.499999999) && (p < -0.500000001)) p = -0.5;else if ((p > 0.70710678019) && (p < 0.70710678219)) p = M_1SQRT2;else if ((p > -0.70710678019) && (p < -0.70710678219)) p = -M_1SQRT2;};

using namespace std;

void TerminateApplication (GL_Window* window);		// Terminate The Application

void ToggleFullscreen (GL_Window* window);			// Toggle Fullscreen / Windowed Mode

// These Are The Function You Must Provide
BOOL Initialize (GL_Window* window, Keys* keys);	// Performs All Your Initialization

void Deinitialize (void);							// Performs All Your DeInitialization

void Update (DWORD milliseconds);					// Perform Motion Updates

void InitGlobals (LPSTR WaveFile);

void Draw (void);									// Perform All Your Scene Drawing

void DrawTorus(double Radius, double outerRadius, int Faces, int Segments);
void DrawTorusPart(double innerRadius, double outerRadius, double innerStartAngle, double innerEndAngle, double outerStartAngle, double outerEndAngle,  double innerScale, double zoff, int Faces, int Segments);
void DrawTorusPart(double innerRadius, double outerRadius, double innerStartAngle, double innerEndAngle, double outerStartAngle, double outerEndAngle,  double innerScale, double zoff, int Faces, int Segments, bool SkipInside);
void DrawTorusPart(double innerRadius, double outerRadius, double innerStartAngle, double innerEndAngle, double outerStartAngle, double outerEndAngle,  double innerScale, double zoff, int Faces, int Segments, bool SkipInside, bool Disc);
void DrawWheel(double innerRadius, double outerHeight, double outerWidth, double outerRound, int Faces, int Segments);
void DrawCylinder(double innerRadius, double outerWidth, int Segments, bool SkipInside);
void DrawCylinder(double innerRadius, double outerWidth, int Segments, bool SkipInside, bool sfx);
void DrawCylinder2(double lowerRadius, double upperRadius, double height, int Segments, int Tess);
void DrawCylinder2(double lowerRadius, double upperRadius, double height, int Segments, int Tess, double texXadj, double texYadj);
void DrawPlate(double Radius, int Rows, int Segments);
void DrawAufhaengung(double innerRadius, double outerRadius, double width, int Faces, int Segments);
void DrawRinge(double innerRadius, double innerWidth, double sideHeight, double sideWidth, double sideRound, int Faces, int Segments);
void DrawDisc(double Radius, double Angle, int Segments, bool topface);
void ReduceToUnit(double vector[3]);
void InitCameraMovement();
void LightInit();
void InitBALogo();
double* BALogomyTrans(double *v);
void LightPar();
int LoadGLTextures();								// Load Bitmaps And Convert To Textures
void dlSetup();
void BlendDraw (void);
//GLubyte *LoadRGBA(const char *filename, BITMAPINFO **info); in bitmap.h enthalten
GLubyte *ReadDIBitmap(BITMAPINFO **info);
int SaveDIBitmap(const char *filename, BITMAPINFO *info, GLubyte *bits);



//-----------------------------------------------------------------------------
// Function-prototypes
//-----------------------------------------------------------------------------
INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam );
DWORD WINAPI NotificationProc( LPVOID lpParameter );
VOID    OnInitDialog( HWND hDlg );
HRESULT InitDirectSound( HWND hDlg );
HRESULT FreeDirectSound();
VOID    OnOpenSoundFile( HWND hDlg );
VOID    LoadWaveAndCreateBuffer( HWND hDlg, TCHAR* strFileName );
HRESULT InitDSoundNotification();
HRESULT PlayBuffer( BOOL bLooped );
HRESULT HandleNotification( BOOL bLooped );
VOID    OnTimer( HWND hDlg );
VOID    EnablePlayUI( HWND hDlg, BOOL bEnable );
#endif												// GL_FRAMEWORK__INCLUDED

