/*
*	Init-HandleGL.cpp
*	----------------------------------------
*	A part of "Intelligent AI"
*	© 2001 SCC Team 064
*	----------------------------------------
*
*	This file:
*		€ Initilizes and destroyes the OpenGL structure on the Draw Sprocket window,  
*		and handles other actions assosiated with the API.
*/


#include "MacInput.h"


// globals (internal/private) -----------------------------------------------
const RGBColor	rgbBlack	= { 0x0000, 0x0000, 0x0000 };
const short kWindowType = kWindowDocumentProc;



//-----------------------------------------------------------------------------------------------
GLuint 	BuildFontGL (AGLContext ctx, GLint fontID, Style face, GLint size)
{
	GLuint listBase = glGenLists (256);
	if (aglUseFont (ctx, fontID , face, size, 0, 256, (long) listBase))
	{
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
		return listBase;
	}
	else
	{
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
		glDeleteLists (listBase, 256);
		return 0;
	}
}


#pragma mark -
// --------------------------------------------------------------------------
// BuildDrawable
// Builds window to be used as drawable
static OSStatus BuildDrawable (AGLDrawable* paglDraw, GDHandle hGD, pstructGLInfo pcontextInfo)
{
	OSStatus err = noErr;
	Rect rectWin;
	RGBColor rgbSave;
	GrafPtr pGrafSave;

	*paglDraw = (AGLDrawable) NewCWindow (NULL, &rectWin, "\p", 0, kWindowType, 
		(WindowPtr)-1, 0, 0);

	ShowWindow ((GrafPtr)*paglDraw);
	GetPort (&pGrafSave);
	SetPort ((GrafPtr)*paglDraw);
	GetForeColor (&rgbSave);
	RGBForeColor (&rgbBlack);
	PaintRect (&(*paglDraw)->portRect);
	RGBForeColor (&rgbSave); // Ensure color is reset for proper blitting
	SetPort (pGrafSave);

	return err;
}


//--------------------------------------------------------------------------------------------
// BuildGLonDrawable
// Takes a drawable and tries to build on it
static OSStatus 	BuildGLonDrawable (AGLDrawable aglDraw, AGLContext* paglContext, 
	pstructGLWindowInfo pcontextInfo)
{
	GDHandle hGD = NULL;
	short numDevices;
	GLint depthSizeSupport;
	OSStatus err = noErr;
	
	if (!pcontextInfo->fDraggable && (numDevices == 1))  // Not draggable on a single device
		// Get an appropriate pixel format
		pcontextInfo->fmt = aglChoosePixelFormat (&hGD, 1, pcontextInfo->aglAttributes);
	else
		 // Get an appropriate pixel format
		 pcontextInfo->fmt = aglChoosePixelFormat (NULL, 0, pcontextInfo->aglAttributes);


	*paglContext = aglCreateContext (pcontextInfo->fmt, NULL); // Create an AGL context
	
	if (!aglSetDrawable (*paglContext, aglDraw)) // Attach the CGrafPtr to the context
		return err;

	return err;
}


#pragma mark -
//---------------------------------------------------------------------------------------------
// PreflightGL
// Checks for presense of OpenGL and DSp (if required)
Boolean		PreflightGL (Boolean checkFullscreen)
{
	// check for existance of OpenGL
	if ((Ptr) kUnresolvedCFragSymbolAddress == (Ptr) aglChoosePixelFormat) 
		return false;
	return true;
}


//---------------------------------------------------------------------------------------------
// BuildGLFromWindow
// Takes window in the form of an AGLDrawable and geometry request and tries to build best context
OSStatus 	BuildGLFromWindow (AGLDrawable aglDraw, AGLContext* paglContext, 
	pstructGLWindowInfo pcontextInfo)
{
	if (!aglDraw)
		return paramErr;
	return BuildGLonDrawable (aglDraw, paglContext, pcontextInfo);
}


//---------------------------------------------------------------------------------------------
// DestroyGLFromWindow
// Destroys context that waas allocated with BuildGLFromWindow
OSStatus 	DestroyGLFromWindow (AGLContext* paglContext, pstructGLWindowInfo pcontextInfo)
{
	OSStatus err;

	if ((!paglContext) || (!*paglContext))
		return paramErr; // not a valid context
	glFinish ();
	aglSetCurrentContext (NULL);
	aglSetDrawable (*paglContext, NULL);
	aglDestroyContext (*paglContext);
	*paglContext = NULL;
	
	if (pcontextInfo->fmt)
	{
		aglDestroyPixelFormat (pcontextInfo->fmt); // Pixel format is no longer valid
	}
	pcontextInfo->fmt = 0;
	
	return err;
}


//---------------------------------------------------------------------------------------------
// PauseGL
// Pauses GL to allow toolbox drawing
OSStatus 	PauseGL (AGLContext aglContext)
{
	if (aglContext)
	{
		glFinish (); // Must do this to ensure the queue is complete
		aglSetCurrentContext (NULL);
	}
	return noErr;
}


//---------------------------------------------------------------------------------------------
// ResumeGL
// Resumes GL to allow gl drawing
OSStatus 	ResumeGL (AGLDrawable aglDraw, AGLContext aglContext)
{
	#pragma unused (aglDraw)
	if (aglContext)
	{
		aglSetCurrentContext (aglContext);
	}
	return noErr;
}
