//screen.cpp
//initialize an OpenGL Context

#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
#include <OpenGL/glu.h>

#include <string.h>
#include "fileio.h"
#include "vectors.h"
#include "renderframe.h"
#include "gameframe.h"
#include "config.h"
#include "screen.h"
#include "gamemem.h"

float gFOVY,gFOVX; //field-of-view in the x and y directions

void InitGLContext();
void ReInitGLContext();
void ExitGLContext();
void ScreenGetModes();

tVideoMode gVideoModes[kMaxModes];
int gVideoNumModes=0;

tScreenTexture gScreenTextures[4];
int gScreenTexturesInited=false;
void SetupScreenTextures()
{
	for(int i=0;i<4;i++)
	{
		if(gScreenTexturesInited)
			if(gScreenTextures[i].xSize)
				glDeleteTextures(1,&gScreenTextures[i].texture);
		gScreenTextures[i].xSize=gScreenTextures[i].ySize=0;
		gScreenTextures[i].xOffset=gScreenTextures[i].yOffset=0;
		glGenTextures(1,&gScreenTextures[i].texture);
		glBindTexture(GL_TEXTURE_2D,gScreenTextures[i].texture);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	}	
	int screenTextureXSize=1;
	for(int i=0;i<16;i++)
		if(screenTextureXSize<gConfig->screenXSize)
			screenTextureXSize*=2;
	int screenTextureYSize=1;
	for(int i=0;i<16;i++)
		if(screenTextureYSize<gConfig->screenYSize)
			screenTextureYSize*=2;

	if(screenTextureXSize>1024)
		if(screenTextureYSize>1024)
		{
			gScreenTextures[0].xSize=1024;
			gScreenTextures[0].ySize=1024;		
			screenTextureXSize=1;
			for(int i=0;i<16;i++)
				if(screenTextureXSize<gConfig->screenXSize-1024)
					screenTextureXSize*=2;
			gScreenTextures[1].xSize=screenTextureXSize;
			gScreenTextures[1].ySize=1024;		
			gScreenTextures[1].xOffset=1024;		
			
			screenTextureYSize=1;
			for(int i=0;i<16;i++)
				if(screenTextureYSize<gConfig->screenYSize-1024)
					screenTextureYSize*=2;
			gScreenTextures[2].xSize=1024;
			gScreenTextures[2].ySize=screenTextureYSize;		
			gScreenTextures[2].yOffset=1024;		
			gScreenTextures[3].xSize=screenTextureXSize;
			gScreenTextures[3].ySize=screenTextureYSize;		
			gScreenTextures[3].xOffset=1024;		
			gScreenTextures[3].yOffset=1024;		
		}
		else
		{
			gScreenTextures[0].xSize=1024;
			gScreenTextures[0].ySize=screenTextureYSize;		

			screenTextureXSize=1;
			for(int i=0;i<16;i++)
				if(screenTextureXSize<gConfig->screenXSize-1024)
					screenTextureXSize*=2;
			gScreenTextures[1].xSize=screenTextureXSize;
			gScreenTextures[1].ySize=screenTextureYSize;		
			gScreenTextures[1].xOffset=1024;		
		}
	else
	{
		gScreenTextures[0].xSize=screenTextureXSize;
		gScreenTextures[0].ySize=screenTextureYSize;		
	}
	gScreenTexturesInited=true;
}

void SetupAspect(float fovy)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();							// Reset The Projection Matrix

	float aspect=(float)gConfig->screenXSize/(float)gConfig->screenYSize;
	gFOVY=fovy;
	gFOVX=aspect*gFOVY;
	gluPerspective(gFOVY*(360.0/(2*PI)),aspect,0.1f,ClipDistance());	// Calculate The Aspect Ratio Of The Window
	
	glMatrixMode(GL_MODELVIEW);
}

void InitGL()
{
 	glEnable(GL_DEPTH_TEST);					
	glEnable(GL_LIGHTING);						 
	glEnable(GL_CULL_FACE);						
	glEnable(GL_FOG);						
	glEnable(GL_TEXTURE_2D);
	
	float fogColor[4]={1,1,1,1};
	glFogi(GL_FOG_MODE,GL_LINEAR);
	glFogf(GL_FOG_START,600);
	glFogf(GL_FOG_END,800);
	glFogfv(GL_FOG_COLOR,fogColor);
	
	if(gConfig->fsaa)
		glEnable(GL_MULTISAMPLE_ARB);	

	if(!ScreenSupportsAnisotropicFiltering()&&gConfig->textureFilter==2)
		gConfig->textureFilter=1;

	SetupScreenTextures();
}

void ScreenInit()
{
	ScreenGetModes();
	InitGLContext();     
	InitGL();
	SetupAspect(kNormalFOVY);
}

void ScreenReInit()
{
	ScreenExit();
	ScreenInit();
}
